Kubernetes之无头服务(headless)
己經看到如何使用服務來提供穩定的ip地址,從而允許客戶端連接到支持服務的每個pod (或其他端點)。到服務的每個連接都被轉發到一個隨機選擇的pod上。但是如果客戶端需要鏈接到所有的pod呢?如果后端的pod都需要連接到所有其他 pod呢?通過服務連接顯然不是這樣的,那是怎樣的呢?
要讓客戶端連接到所有pod,需要找出每個pod的IP。一種選擇是讓客戶端調用Kubernetes API服務器并通過API調用獲取pod及其IP地址列表,但由于應始終努力保持應用程序與Kubernetes無關,因此使用API服務器并不理想。
幸運的是,Kubernetes允許客戶通過DNS查找發現pod IP。通常,當執行服務的DNS查找時,DNS服務器會返回單個IP——服務的集群IP。但是,如果告訴 Kubernetes,不需要為服務提供集群IP (通過在服務spec中將clusterIP字段設置為None來完成此操作),則DNS服務器將返回podIP而不是單個服務IP。
DNS服務器不會返回單個DNS A記錄,而是會為該服務返回多個A記錄,每個記錄指向當時支持該服務的單個pod的IP。客戶端因此可以做一個簡單的DNS A 記錄查找并獲取屬于該服務一部分的所有pod的IP。客戶端可以使用該信息連接到其中的一個、多個或全部。
1.創建headless服務
將服務spec中的clusterIP字段設置為None會使服務成為headless服務,因為Kubernetes不會為其分配集群IP,客戶端可通過該IP將其連接到支持它的pod。
現在將創建一個名為kubia-headless的headless服務。以下代碼清單顯示了它的定義。
apiVersion: v1
kind: Service
metadata:
name: kubia-headless
spec:
clusterIP: None #這使得服務成為headless
ports:
- port: 80
targetPort: 8080
selector:
app: kubia
在使用kubectlcreate創建服務之后,可以通過kubectlget和kubectl describe來查看服務,你會發現它沒有集群IP,并且它的后端包含與pod選擇器匹配的(部分)pod。“部分”是因為pod包含就緒探針,所以只有準備就緒的pod會被列出作為服務的后端文件來確保至少有兩個pod報告己準備就緒。
2.通過DNS發現pod
準備好pod后,現在可以嘗試執行DNS查找以查看是否獲得了實際的podIP。需要從其中一個pod中執行查找。不幸的是,kubia容器鏡像不包含nslookup(或dig)二進制文件,因此無法使它執行DNS查找。
所要做的就是在集群中運行的一個pod中執行DNS查詢。為什么不尋找一個包含所需二進制文件的鏡像來運行新的容器?要執行與DNS相關的操作,可以使用DockerHub上提供的tutum/dnsutils容器鏡像,它包含nslookup和dig二進制文件。要運行pod,可以完成創建YAML清單并將其傳給kubectlcreate的整個過程。但是太煩瑣了,對嗎?幸運的是,有一個更快的方法。
不通過YAML文件運行pod
使用kubectlrun是這次只想創建一個pod,不需要創建一個ReplicationController來管理pod。可以這樣做:
$ kubectl run dnsutils --image=tutum/dnsutils --generator=run-pod/v1 --command -- sleep infinity pod "dnsutils" created
訣竅在--generator=run-pod/vl選項中,該選項讓kubectl直接創建pod,而不需要通過ReplicationController之類的資源來創建。
理解headless服務的DNSA記錄解析
使用新創建的pod執行DNS查找:
$ kubectl exec dnsutils nslookup kubia-headless Name: kubia-headless.default.svc.cluster.local Address: 10.108.1.4 Name: kubia-headless.default.svc.cluster.local Address: 10.108.2.5
DNS服務器為kubia-headless.default.svc.cluster.localFQDN返回兩個不同的IP。這些是報告準備就緒的兩個pod的IP。可以通過使用kubectlgetpods-owide列出pod來確認此問題,該清單顯示了pod的IP。
這與常規(非headless服務)服務返回的DNS不同,比如kubia服務,返回的IP是服務的集群IP。(這里就不做代碼演示了)
盡管headless服務看起來可能與常規服務不同,但在客戶的視角上它們并無不同。即使使用headless服務,客戶也可以通過連接到服務的DNS名稱來連接到pod上,就像使用常規服務一樣。但是對于headless服務,由于DNS返回了pod的IP,客戶端直接連接到該pod,而不是通過服務代理。
注意:headless服務仍然提供跨pod的負載平衡,但是通過DNS輪詢機制不是
3.發現所有的pod--包括未就緒的pod
只有準備就緒的pod能夠作為服務的后端。但有時希望即使pod沒有準備就緒,服務發現機制也能夠發現所有匹配服務標簽選擇器的pod。
幸運的是,不必通過查詢KubernetesAPI服務器,可以使用DNS查找機制來查找那些未準備好的pod。要告訴Kubernetes無論pod的準備狀態如何,希望將所有pod添加到服務中。必須將以下注解添加到服務中:
kind: Service
metadata:
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
警告: 就像說的那樣,注解名稱表明了這是一個alpha功能。KubernetesService API己經支持一個名為publishNotReadyAddresses的新服務規范字段,它將替換tolerate-unready-endpoints注解。在Kubernetes1.9.0版本中,這個字段還沒有實現(這個注解決定了未準備好的endpoints是否在DNS的記錄中)。檢查文檔以查看是否己更改。
作者:小家電維修
相見有時,后會無期。
總結
以上是生活随笔為你收集整理的Kubernetes之无头服务(headless)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 向量、矩阵的范数/模(norm)
- 下一篇: 电信网关怎样连接路由器如何连接网关上的路