service discory
kubernetes中查找服務主要有兩種方式:環境變量和DNS
- 環境變量
kubelet給每個pod中添加了每個service對應的一組環境變量,包括簡單變量{SVCNAME}_SERVICE_HOST和Docker-links變量{SVCNAME}_PORT,變量中的service_name全部大寫,中劃線轉為下劃線。
我的一個svc相關變量如下:
SVC_MALIBU_SERVICE_HOST=172.21.39.194
SVC_MALIBU_PORT_8080_TCP_ADDR=172.21.39.194
SVC_MALIBU_PORT_8080_TCP_PORT=8080
SVC_MALIBU_SERVICE_PORT=8080
SVC_MALIBU_PORT_8080_TCP=tcp://172.21.39.194:8080
SVC_MALIBU_PORT_8080_TCP_PROTO=tcp
SVC_MALIBU_PORT=tcp://172.21.39.194:8080
注:在pod中使用這些變量的時候,一定要在pod運作前先建立好svc,不然pod裡面讀不到的
- DNS
像coredns等叢集感覺的DNS server監視了kubernetes api,它會為新service建立一組dns記錄。
-
A記錄
除了Headless Service外的svc,會以 svc-name.svc-namespace.svc.cluster-domain.example 的形式添加一條A記錄。記錄值為svc的Cluster IP。
“Headless” Service也會以 svc-name.svc-namespace.svc.cluster-domain.example 這種名字的形式添加一條A記錄,它會解析成該 Service 選擇(selector)的一組Pod的IP。用戶端使用round-robin政策從這一組IP中進行選擇。
-
SRV記錄
命名端口會建立一條SRV記錄,格式 _port-name._port-protocol.svc-name.svc-namespace.svc.cluster-domain.example,普通的svc解析結果是端口号和CNAME(svc-name.svc-namespace.svc.cluster-domain.example)。headless類型的svc會解析出多個值,每個pod一個對應的port和CNAME(pod-name.svc-name.svc-namespace.svc.cluster-domain.example)
我們在應用配置檔案中,經常會看到寫多個位址,比如zookeeper位址配置為
zookeeper://10.0.1.11:2181?backup=10.0.1.12:2181
,在k8s中,建立headless類型的svc,會在kube-dns中為每個pod添加一條記錄
$(podname).$(headless-svc-name).namespace.svc.cluster.local
,值為pod的ip。這樣配合stateful-set類型的控制器,每個pod就會有固定的hostname和域名。
headless service
不需要負載均衡或者pod間通路的情況下可能會用到。它不會建立cluster ip和proxy規則。ExternalName接受IPv4位址字元串,但作為包含數字的DNS名稱,而不是IP位址。
無selector的service
可以自己手動建立endpoint,與service關聯
externalname service
PodSpec.dnsPolicy配置
-
: Pod從運作所在的節點繼承dns配置。Default
-
: 與配置的叢集域字尾不比對的任何DNS查詢(例如 “www.taobao.com”)都将轉發到從節點繼承的上遊dns伺服器。ClusterFirst
-
: 對于與hostNetwork一起運作的Pod,需要設定其DNS政策為”ClusterFirstWithHostNet“,pod裡面nameserver為叢集dns位址。ClusterFirstWithHostNet
-
: 它使Pod忽略Kubernetes環境中的DNS設定,使用Pod Spec中的 dnsConfig字段提供所有DNS設定。None