k8s的無頭服務(wù)

k8s的無頭服務(wù)

Headless Services是一種特殊的service,其spec:clusterIP表示為None,這樣在實(shí)際運(yùn)行時(shí)就不會(huì)被分配ClusterIP,也被稱為無頭服務(wù),通過DNS解析提供服務(wù)發(fā)現(xiàn)。與普通服務(wù)不同的是Headless Services不提供負(fù)載均衡功能,每個(gè)Pod都有唯一的DNS記錄,直接映射到其IP地址,適用于有狀態(tài)應(yīng)用的場(chǎng)景,如與StatefulSet一起部署數(shù)據(jù)庫。這種服務(wù)使得直接訪問單個(gè)Pod成為可能,而不經(jīng)過負(fù)載均衡器。

因?yàn)?Headless Service 屬于 Service ClusterIp 類型,所以在講解Headless Service前,先簡單說下 Service 和服務(wù)發(fā)現(xiàn)。

構(gòu)建鏡像

[root@chenby ~]# cat > Dockerfile <<EOF
FROM nginx
RUN echo '這是一個(gè)本地構(gòu)建的nginx鏡像,第一版' > /usr/share/nginx/html/index.html
EOF

docker build -t z.oiox.cn:18082/library/cby:v1 .

docker push z.oiox.cn:18082/library/cby:v1

編寫yaml文件

我這里只是創(chuàng)建了一個(gè)最簡單的容器,由StatefulSet控制器來管理,同時(shí)創(chuàng)建了無頭服務(wù)的svc

cat > cby.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None   #這使得服務(wù)成為無頭服務(wù)
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: z.oiox.cn:18082/library/cby:v1
        ports:
        - containerPort: 80
          name: web
EOF

查看已經(jīng)創(chuàng)建的資源

[root@k8s-master01 ~]# kubectl get statefulsets
NAME   READY   AGE
web    2/2     12m
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# kubectl get pod 
NAME                            READY   STATUS    RESTARTS      AGE
web-0                           1/1     Running   0             12m
web-1                           1/1     Running   0             12m
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
nginx          ClusterIP   None             <none>        80/TCP     12m
[root@k8s-master01 ~]# 

修改web-1的html內(nèi)容

statefulsets控制器是可以將存儲(chǔ)持久化的,我這里沒做存儲(chǔ)持久化,這里就進(jìn)入容器內(nèi)進(jìn)行修改頁面信息

kubectl exec web-1 -- sh -c 'echo 這是一個(gè)本地構(gòu)建的nginx鏡像,第二版 > /usr/share/nginx/html/index.html'

測(cè)試修改是否成功

[root@k8s-master01 ~]# kubectl get pod -o wide |grep web
web-0                           1/1     Running   0             40m   10.0.0.28    k8s-node02   <none>           <none>
web-1                           1/1     Running   0             40m   10.0.3.243   k8s-node01   <none>           <none>
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# curl 10.0.0.28
這是一個(gè)本地構(gòu)建的nginx鏡像,第一版
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# curl 10.0.3.243
這是一個(gè)本地構(gòu)建的nginx鏡像,第二版
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# 

查看svc的詳細(xì)

這里可以看到Endpoints已經(jīng)關(guān)聯(lián)到了后端的pod容器

[root@k8s-master01 ~]# kubectl describe svc nginx
Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       None
IPs:                      None
Port:                     web  80/TCP
TargetPort:               80/TCP
Endpoints:                10.0.0.28:80,10.0.3.243:80
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
[root@k8s-master01 ~]#

創(chuàng)建busybox測(cè)試容器

cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: docker-ce.chenby.cn/library/busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
EOF

進(jìn)入測(cè)試容器

[root@k8s-master01 ~]# kubectl exec -ti busybox -- sh
/ # 
/ # 
/ # ping nginx.default.svc.cluster.local 
PING nginx.default.svc.cluster.local (10.0.0.28): 56 data bytes
64 bytes from 10.0.0.28: seq=0 ttl=63 time=0.066 ms
64 bytes from 10.0.0.28: seq=1 ttl=63 time=0.077 ms
64 bytes from 10.0.0.28: seq=2 ttl=63 time=0.070 ms
^C
--- nginx.default.svc.cluster.local ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.066/0.071/0.077 ms
/ # 
/ # 
/ # 
/ # ping web-0.nginx.default.svc.cluster.local 
PING web-0.nginx.default.svc.cluster.local (10.0.0.28): 56 data bytes
64 bytes from 10.0.0.28: seq=0 ttl=63 time=0.046 ms
64 bytes from 10.0.0.28: seq=1 ttl=63 time=0.079 ms
64 bytes from 10.0.0.28: seq=2 ttl=63 time=0.064 ms
^C
--- web-0.nginx.default.svc.cluster.local ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.046/0.063/0.079 ms
/ # 
/ # 
/ # 
/ # ping web-1.nginx.default.svc.cluster.local 
PING web-1.nginx.default.svc.cluster.local (10.0.3.243): 56 data bytes
64 bytes from 10.0.3.243: seq=0 ttl=63 time=0.369 ms
64 bytes from 10.0.3.243: seq=1 ttl=63 time=0.373 ms
64 bytes from 10.0.3.243: seq=2 ttl=63 time=0.328 ms
^C
--- web-1.nginx.default.svc.cluster.local ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.328/0.356/0.373 ms
/ # 
/ # 
/ # 
/ # 
/ # cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.0.0.238  busybox
/ # 
/ # 
/ # 
/ # 

進(jìn)行訪問性測(cè)試

[root@k8s-master01 ~]# kubectl exec -ti nginx-demo-cccbdc67f-6nkgd -- sh
/ # 
/ # 
/ # curl nginx.default.svc.cluster.local
這是一個(gè)本地構(gòu)建的nginx鏡像,第二版
/ # curl nginx.default.svc.cluster.local
這是一個(gè)本地構(gòu)建的nginx鏡像,第一版
/ # 
/ # 
/ # 
/ # curl web-0.nginx.default.svc.cluster.local 
這是一個(gè)本地構(gòu)建的nginx鏡像,第一版
/ # curl web-0.nginx.default.svc.cluster.local
這是一個(gè)本地構(gòu)建的nginx鏡像,第一版
/ # curl web-0.nginx.default.svc.cluster.local
這是一個(gè)本地構(gòu)建的nginx鏡像,第一版
/ # 
/ # 
/ # 
/ # curl web-1.nginx.default.svc.cluster.local 
這是一個(gè)本地構(gòu)建的nginx鏡像,第二版
/ # curl web-1.nginx.default.svc.cluster.local
這是一個(gè)本地構(gòu)建的nginx鏡像,第二版
/ # curl web-1.nginx.default.svc.cluster.local
這是一個(gè)本地構(gòu)建的nginx鏡像,第二版

總結(jié)

在某些場(chǎng)景中,無需對(duì)外提供訪問能力,只需要在內(nèi)部找到自己想找到的Pod資源時(shí),可以通過Headless Service來實(shí)現(xiàn)。這種不具有ClusterIP的Service資源就是Headless Service,該 Service 的請(qǐng)求流量不需要 kube-proxy 處理,也不會(huì)有負(fù)載均衡和路由規(guī)則,而是由ClusterDNS的域名解析機(jī)制直接去訪問固定的Pod資源。

既然是Headless Service,那首先它是Service,一般的Service能被內(nèi)部和外部訪問。之所以叫Headless Service,是因?yàn)橹粚?duì)內(nèi)提供訪問,既然只對(duì)內(nèi)訪問,那肯定就需要提供穩(wěn)定的訪問能力了,否則就沒什么作用了。比如說擁有固定的Pod名稱和存儲(chǔ),所以一般會(huì)結(jié)合StatefulSet一起使用,用來部署有狀態(tài)的應(yīng)用。

如果想讓部署的有狀態(tài)應(yīng)用暴露給集群外部客戶端訪問的話,可以新建個(gè)普通(有ClusterIP)的服務(wù),通過標(biāo)簽選擇關(guān)聯(lián)有狀態(tài)服務(wù)實(shí)例。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容