Service工作模式:

工作模式:userspace,iptables ipvs

userspace:1.1-
iptables:1.10-
ipvs:1.11+

Service类型:

ExternalName,ClusterIP,NodePort和LoadBalancer
NodePort的工作逻辑;client->NodeIP.NodePort->ClusterIP.ServicePort->PodIP,containerPort
No ClusterIP;Headless Service

无头类型的工作逻辑ServiceName->PodIP,由上看出NodePort的工作逻辑是解析出ClusterIP,而无头类型是把ServiceName名称直接解析为后端PodIP

资源记录

SVC_NAME.NS_NAME.DOMAIN.LTD
svc.Cluster.local

举例:

redis.default.svc.Cluster.local

Service清单举例:

ClusterIP类型:

apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
spec:
  selector:
    app: redis
    role: logstor
   clusterIP: 10.1.97.97
   type: ClusterIP
   ports:
   - port: 6379
     targetPort: 6379

NodePort类型:

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  sessionAffinity: ClientIP
  clusterIP: 10.1.97.97
  selector:
    app: myapp
    release: canary
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080

注意:其中sessionAffinity可以会话保持,而spec中的ClusterIP和ports中的nodePort可以选择不定义,不定义的结果是Cluster IP和nodeProtIP系统自动分配一个对应的地址和端口。

无头类型:

apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: default
spec:
  sessionAffinity: ClientIP
  clusterIP: None
  selector:
    app: myapp
    release: canary
  ports:
  - port: 80
    targetPort: 80

Service无头类型和有头类型(ClusterIP和NodePort)比较:

在一个集群中有这个几个组件:pod-a,svc-b,pod-b1,pod-b2。当 pod-a 想访问 pod-b 中的应用程序时,先会把请求打到 svc-b,再由 svc-b 将请求随机转发到 pod-b1或 pod-b2。

如果有个需求:pod-a 需要同时连接到 pod-b1和 pod-b2 ,这时再采用 svc-b 转发显然已经不能满足需求了。那 pod-a 该如何获取到 pod-b1和 pod-b2 的 IP 地址呢?采用 handless service 就可以实现。
无头SVC解析到的主机名:

[root@master ~]# dig -t A myapp-headless.default.svc.Cluster.local @10.1.0.10
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> -t A myapp-headless.default.svc.Cluster.local @10.1.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36998
;; flags: qr aa rd; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myapp-headless.default.svc.Cluster.local. IN A

;; ANSWER SECTION:
myapp-headless.default.svc.Cluster.local. 30 IN    A 10.244.2.11
myapp-headless.default.svc.Cluster.local. 30 IN    A 10.244.1.10
myapp-headless.default.svc.Cluster.local. 30 IN    A 10.244.1.11
myapp-headless.default.svc.Cluster.local. 30 IN    A 10.244.2.10
myapp-headless.default.svc.Cluster.local. 30 IN    A 10.244.2.12

;; Query time: 55 msec
;; SERVER: 10.1.0.10#53(10.1.0.10)
;; WHEN: Fri Dec 24 22:57:31 CST 2021
;; MSG SIZE  rcvd: 349

此时可以看到解析到的主机名有五个,而有头的SVC却只能解析到一个。
有头的SVC解析到的主机名:

[root@master ~]# dig -t A myapp.default.svc.Cluster.local @10.1.0.10
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> -t A myapp.default.svc.Cluster.local @10.1.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14319
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myapp.default.svc.Cluster.local. IN    A

;; ANSWER SECTION:
myapp.default.svc.Cluster.local. 30 IN    A    10.1.155.68

;; Query time: 1 msec
;; SERVER: 10.1.0.10#53(10.1.0.10)
;; WHEN: Fri Dec 24 22:59:38 CST 2021
;; MSG SIZE  rcvd: 107

举例:

配置一个完整的Deployment:

#Service书写规范及注释
apiVersion: v1                #api-version版本,必填
kind: Service                 #对象选择,必填
metadata:                     #元数据,必填
  name: nginx-deploy-svc      #Service名称,必填
  labels:                     #自定义标签
    name: nginx-deploy-svc    #标签名称
spec:                         #Service详细定义
  type: NodePort              #node节点端口方式映射服务ip
  selector:                   #Pod标签选择
    app: nginx-deploy-pvc     #选择某app的名称的Pod,与下方deployment中的spec.selector.matchLabels的标签对应
  ports:                      #端口列表
  - port: 80                  #Service端口
    targetPort: 3000          #转发到后台Pod的端口
    nodePort: 32817           #映射到node上的端口
    protocol: TCP             #传输协议:TCP/UDP, 默认为TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-pvc
  name: nginx-deploy-pvc
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy-pvc
  template:
    metadata:
      labels:
        app: nginx-deploy-pvc
spec:
  containers:
  - image: ikubernetes/myapp:v1
    name: myapp
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      protocol: TCP
最后修改:2023 年 06 月 09 日
如果觉得我的文章对你有用,请随意赞赏