使用CoreDNS實現Kubernetes基於DNS的服務發現
1.Kubernetes基於DNS的服務發現
在Kubernetes叢集推薦使用Service Name作為服務的訪問地址,因此需要一個Kubernetes叢集範圍的DNS服務實現從Service Name到Cluster Ip的解析,這就是Kubernetes基於DNS的服務發現功能。
在從Kubernetes 1.10開始Dynamic Kubelet Configuration特性進入beta階段,kubelet的大多數命令列引數都改為推薦在 --config
指定位置的配置檔案中進行配置,包括 ---cluster-dns
和 --cluster-domain
兩個引數,在kubelet的配置檔案中配置如下:
apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration ...... clusterDNS: - 10.96.0.10 clusterDomain: cluster.local ......
其中clusterDNS指定了叢集中所有容器將使用的DNS Server,即kubelet會在每個Pod內部設定DNS服務的地址為clusterDNS配置的地址。前面的配置中設定了Kubernetes叢集訪問內DNS伺服器的地址是10.96.0.10,將由起完成Service Name到Cluster Ip的解析。有了這個配置,我們還需要在叢集內部署DNS服務,DNS服務一般都是作為addon元件部署在Kubernetes叢集內的。
2.Kubernetes DNS服務發展史
從Kubernetes 1.11開始,可使用CoreDNS作為Kubernetes的DNS外掛進入GA狀態,Kubernetes推薦使用CoreDNS作為叢集內的DNS服務。 我們先看一下Kubernetes DNS服務的發展歷程。
2.1 Kubernetes 1.3之前的版本 - skyDNS
Kubernetes 1.3之前的版本使用skyDNS作為DNS服務,這個有點久遠了。Kubernetes的DNS服務由kube2sky、skyDNS、etcd組成。 kube2sky通過kube-apiserver監聽叢集中Service的變化,將生成的DNS記錄資訊更新到etcd中,而skyDNS將從etcd中獲取資料對外提供DNS的查詢服務。
2.2 Kubernetes 1.3版本開始 - kubeDNS
Kubernetes 1.3開始使用kubeDNS和dnsmasq替換了原來的kube2sky和skyDNS,不再使用etcd,而是將DNS記錄直接存放在記憶體中,通過dnsmasq的快取功能提高DNS的查詢效率。下圖是描述了Kubernetes使用kubeDNS實現服務發現的整體架構:
2.3 Kubernetes 1.11版本開始 - CoreDNS進入GA
從Kubernetes 1.11開始,可使用CoreDNS作為Kubernetes的DNS外掛進入GA狀態,Kubernetes推薦使用CoreDNS作為叢集內的DNS服務。 CoreDNS從2017年初就成為了CNCF的的孵化專案,CoreDNS的特點就是十分靈活和可擴充套件的外掛機制,各種外掛實現不同的功能,如重定向、定製DNS記錄、記錄日誌等等。下圖描述了CoreDNS的整體架構:
3.Kubernetes配置使用CoreDNS
在Kubernetes中部署CoreDNS作為叢集內的DNS服務有很多種方式,例如可以使用官方Helm Chart庫中的helm chart部署,具體可檢視 ofollow,noindex" target="_blank">CoreDNS Helm Chart 。這裡繼承我們之前部署kubeDNS的傳統,使用Kubernetes中addon庫中的yaml檔案部署,地址在這裡 coredns addon 。
檢視transforms2sed.sed的內容:
s/__PILLAR__DNS__SERVER__/$DNS_SERVER_IP/g s/__PILLAR__DNS__DOMAIN__/$DNS_DOMAIN/g s/__PILLAR__CLUSTER_CIDR__/$SERVICE_CLUSTER_IP_RANGE/g s/__MACHINE_GENERATED_WARNING__/Warning: This is a file generated from the base underscore template file: __SOURCE_FILENAME__/g
將 $DNS_SERVER_IP
和 DNS_DOMAIN
替換成kubelet配置的內容。這裡將 $DNS_SERVER_IP
替換成 10.96.0.10
,將 DNS_DOMAIN
替換成 cluster.local
。
執行下面的命令,生成部署coreDNS所需的coredns.yaml檔案:
sed -f transforms2sed.sed coredns.yaml.base > coredns.yaml
對coredns.yaml做微調,如修改映象地址為私有映象倉庫,調整副本數量等等。
kubectl delete -f kube-dns.yaml #刪除原來的kubeDNS部署 kubectl apply -f coredns.yaml
檢視coredns的Pod,確認所有Pod都處於Running狀態:
kubectl get pods -n kube-system -l k8s-app=kube-dns NAMEREADYSTATUSRESTARTSAGE coredns-699477c54d-9fsl21/1Running05m coredns-699477c54d-d6tb21/1Running05m coredns-699477c54d-qh54v1/1Running05m coredns-699477c54d-vvqj91/1Running05m coredns-699477c54d-xcv8h1/1Running06m
測試一下DNS功能是否好用:
kubectl run curl --image=radial/busyboxplus:curl -i --tty nslookup kubernetes.default Server:10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name:kubernetes Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
DNS服務是Kubernetes賴以實現服務發現的核心元件之一,預設情況下只會建立一個DNS Pod,在生產環境中我們需要對coredns進行擴容。 有兩種方式:
- 手動擴容 kubectl –namespace=kube-system scale deployment coredns –replicas=
- 使用 DNS Horizontal Autoscaler