已經看到如何使用Service來提供穩定IP,從而允許客戶端連接到服務後端的每個pod(或其他endpoint),打到Service的每個連線都會被轉發到隨機選擇的後端pod上。 但假如客戶端需要直接連接到所有的pod呢? 如果後端pod都需要連接到其它所有的後端pod呢? 透過Service連接顯然不是這樣做的。
要讓客戶端連接到所有pod,需要找出每個pod的IP。一種選擇是讓客戶端用k8s API獲取pod及其IP列表。但由於應該始終努力保持你的app跟k8s無關,因此使用k8s api並不理想。
k8s允許客戶端透過DNS查詢發現pod IP,通常,當執行服務的DNS查詢時,DNS server會返回單一IP(Service的clusterIP)。但是,如果告訴k8s不需要幫Service提供clusterIP (透過服務spec終將clusterIP設定為None來完成),則DNS將返回pod IP而不是單個服務IP。
DNS server不會返回單個DNS A record,而是會幫Service返回多個A record,每筆record指向Service後端的個別pod IP。因此客戶端可以做一個簡單的DNS A record查詢並獲得屬於該Service的一部分的所有pod IP。客戶端可以利用該資訊來連線到其中一個、多個或全部。
將Service spec中的clusterIP設定為None會使Service成為headless,因為k8s將不會幫Service配置clusterIP,客戶端無法透過該IP將連線到服務後端的pod。 建立 kubia-svc-headless.yaml,如下:
apiVersion: v1
kind: Service
metadata:
name: kubia-headless
spec:
clusterIP: None # 讓Service變成headless類型
ports:
- port: 80
targetPort: 8080
selector:
app: kubia
[root@cp200 ch5]# kubectl create -f kubia-svc-headless.yaml
service/kubia-headless created
建立headless服務後,可以利用 kubectl get
和 kubectl describe
查看服務,會發現沒有clusterIP,並且它的endpoint包含與pod選擇器匹配的(部分)pod。"部分"是因為pod包含就緒探針,所以只有準備就緒的pod會被列出來作為服務的endpoint。
目前3個pod中只有一個pod準備就緒,在利用以下指令,來確保有兩個pod準備就緒。
[root@cp200 ch5]# kubectl get po
NAME READY STATUS RESTARTS AGE
kubia-jtm2r 1/1 Running 0 12m
kubia-qlmwt 0/1 Running 0 12m
kubia-sk89x 0/1 Running 0 12m
[root@cp200 ch5]# kubectl exec kubia-qlmwt -- touch /var/ready
[root@cp200 ch5]# kubectl get po
NAME READY STATUS RESTARTS AGE
kubia-jtm2r 1/1 Running 0 13m
kubia-qlmwt 1/1 Running 0 13m
kubia-sk89x 0/1 Running 0 13m
現在需要建立一個可以執行dns查詢的pod(映像檔tutum/dnsutils有包含nslookup和dig工具),提供一個不透過YAML檔案來建立pod (這個pod裡面有包含可以使用nslookup的工具),使用以下指令單獨建立一個pod,如下:
[root@cp200 ch5]# kubectl run dnsutils --image=tutum/dnsutils --command -- sleep infinity
pod/dnsutils created
使用剛建立的pod執行DNS查詢
kubectl exec dnsutils -- nslookup kubia-headless
DNS為 kubia-headless.default.svc.cluster.local FQDN返回幾個不同的IP。這些都是”準備就緒”的pod IP。可以透過使用 kubectl get pods -o wide
列出pod來確認全部的pod IP清單。
這跟常規的服務(非headless服務)返回的DNS不同,比如:kubia服務返回的IP是服務的clusterIP
[root@cp200 ch5]# kubectl exec dnsutils -- nslookup kubia-headless
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: kubia-headless.default.svc.cluster.local
Address: 10.244.141.248
Name: kubia-headless.default.svc.cluster.local
Address: 10.244.172.249