kubernetes-Service

1、前言

我们不应该期望Kubernetes Pod是健壮的,而是要假设Pod中的容器很可能因为各种原因发生故障而死掉。Deployment等Controller会通过动态创建和销毁Pod来保证应用整体的健壮性。换句话说,Pod是脆弱的,但应用是健壮的。每个Pod都有自己的IP地址。当Controller用新Pod替代发生故障的Pod时,新Pod会分配到新的IP地址。这样就产生了一个问题:如果一组Pod对外提供服务(比如HTTP),它们的IP很有可能发生变化,那么客户端如何找到并访问这个服务呢?Kubernetes给出的解决方案是Service。

2、基本语法

2.1 Service yaml

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: httpd-demo-1
  namespace: test
  labels:
    app: httpd-demo
spec:
  selector:
    app: httpd-demo
  ports:
  - port: 80
    protocol: TCP

2.2 关键字段

  • selector:选择器。selector是一个键值对,用于指定Service要代理的Pod的标签。Service会自动检测满足selector条件的Pod,并将流量转发给它们。
  • ports:用于定义Service所使用的端口。这个字段是一个对象,其中包含多个字段,最常用的两个字段是port和targetPort

2.3 port、nodePort、targetPort、containerPort字段说明

port是暴露在cluster ip上的端口,:port提供了集群内部客户端访问service的入口,即clusterIP:port。

nodePort提供了集群外部客户端访问service的一种方式,:nodePort提供了集群外部客户端访问service的端口,即nodeIP:nodePort提供了外部流量访问k8s集群中service的入口。

targetPort是pod上的端口,从port/nodePort上来的数据,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。

containerPort是在pod控制器中定义的、pod中的容器需要暴露的端口。

3、Service 类型

3.1 ClusterIP

Service通过Cluster内部的IP对外提供服务,只有Cluster内的节点和Pod可访问,这是默认的Service类型。

3.2 NodePort

将Service通过指定的Node上的端口暴露给外部,访问任意一个 NodeIP:nodePort都将路由到ClusterIP。

端口范围:30000-32767,可以不指定,k8s会生成一个nodePort

3.3 LoadBalancer

使用云平台的负载均衡器向外部公开 Service。Kubernetes 不直接提供负载均衡组件; 你必须提供一个,或者将你的 Kubernetes 集群与某个云平台集成。

3.4 ExternalName

将服务映射到 externalName 字段的内容(例如,映射到主机名 api.foo.bar.example)。 该映射将集群的 DNS 服务器配置为返回具有该外部主机名值的 CNAME 记录。 集群不会为之创建任何类型代理。

4、无头服务(Headless Services)

service 有一个特别的形态就是 Headless Service。service 创建的时候可以指定 clusterIP:None,告诉 K8s 说我不需要 clusterIP(就是刚才所说的集群里面的一个虚拟 IP),然后 K8s 就不会分配给这个 service 一个虚拟 IP 地址,它没有虚拟 IP 地址怎么做到负载均衡以及统一的访问入口呢?

它是这样来操作的:pod 可以直接通过 service_name 用 DNS 的方式解析到所有后端 pod 的 IP 地址,通过 DNS 的 A 记录的方式会解析到所有后端的 Pod 的地址,由客户端选择一个后端的 IP 地址,这个 A 记录会随着 pod 的生命周期变化,返回的 A 记录列表也发生变化,这样就要求客户端应用要从 A 记录把所有 DNS 返回到 A 记录的列表里面 IP 地址中,客户端自己去选择一个合适的地址去访问 pod。

无头 Service 不会获得集群 IP,kube-proxy 不会处理这类 Service, 而且平台也不会为它们提供负载均衡或路由支持。你可以使用无头 Service 与其他服务发现机制交互,而不必绑定到 Kubernetes 的实现。

5、访问service

启动demo

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: httpd-demo-1
  namespace: test
  labels:
    app: httpd-demo
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: httpd-demo

---

apiVersion: v1
kind: Service
metadata:
  name: httpd-demo-2
  namespace: test
  labels:
    app: httpd-demo
spec:
  type: NodePort
  ports:
  - nodePort: 32181
    port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: httpd-demo

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-demo
  namespace: test
  labels:
    app: httpd-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: httpd-demo
  template:
    metadata:
      labels:
        app: httpd-demo
    spec:
      containers:
      - name: httpd-demo
        image: httpd:latest
ini 复制代码
kubectl --kubeconfig=xxx apply -f service.yaml  

启动一个busybox镜像的pod,方便连接service进行测试

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox-test
  namespace: test
  labels:
    app: busybox
spec:
  containers:
  - name: busybox-test
    image: busybox:latest
    command: ["/bin/sh", "-c"]
    args:
    - |
      sleep 100000

查看当前service

scss 复制代码
kubectl --kubeconfig=xxx get svc -n test

NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
httpd-demo-1                  ClusterIP   10.30.99.106    <none>        80/TCP         1h
httpd-demo-2                  NodePort    10.30.167.74    <none>        80:32181/TCP   1h

通过nodeIp:nodePort访问 http://xx.xx.xx.xx:32181/

集群内访问 curl 10.30.99.106:80

其他pod访问

bash 复制代码
kubectl --kubeconfig=xxx exec -it -n test busybox-test sh

# 通过clusterIp访问service
wget -O- 10.30.99.106
# 通过环境变量访问service
wget -O- $HTTPD_DEMO_1_SERVICE_HOST
# 通过服务名访问service,如果是不同namespace,加上.namaspace
wget -O- httpd-demo-1
wget -O- httpd-demo-1.test

# 查看环境变量,可以看到写入了很多环境变量,如xxx_SERVICE_HOST xxx_PORT
env |grep HTTPD_DEMO

参考

相关推荐
木鱼时刻14 小时前
容器与 Kubernetes 基本概念与架构
容器·架构·kubernetes
chuanauc1 天前
Kubernets K8s 学习
java·学习·kubernetes
庸子2 天前
基于Jenkins和Kubernetes构建DevOps自动化运维管理平台
运维·kubernetes·jenkins
李白你好2 天前
高级运维!Kubernetes(K8S)常用命令的整理集合
运维·容器·kubernetes
Connie14512 天前
k8s多集群管理中的联邦和舰队如何理解?
云原生·容器·kubernetes
伤不起bb2 天前
Kubernetes 服务发布基础
云原生·容器·kubernetes
别骂我h2 天前
Kubernetes服务发布基础
云原生·容器·kubernetes
weixin_399380692 天前
k8s一键部署tongweb企业版7049m6(by why+lqw)
java·linux·运维·服务器·云原生·容器·kubernetes
斯普信专业组3 天前
K8s环境下基于Nginx WebDAV与TLS/SSL的文件上传下载部署指南
nginx·kubernetes·ssl
&如歌的行板&3 天前
如何在postman中动态请求k8s中的pod ip(基于nacos)
云原生·容器·kubernetes