在集群中部署NodeLocal DNSCache可以提升服務發現的穩定性和性能,NodeLocal DNSCache通過在集群節點運行DNS緩存代理來提高集群DNS性能。
本文介紹如何安裝NodeLocal DNSCache,并在應用中使用NodeLocal DNSCache。
NodeLocal DNSCache簡介
云容器引擎NodeLocal DNSCache插件是基于社區開源項目NodeLocal DNSCache的一套DNS本地緩存解決方案,該方案主要由DNS本地緩存和DNSConfig動態注入控制器組成:
- DNSConfig動態注入控制器,基于Admission Webhook機制攔截Pod創建的請求,自動注入使用DNS緩存的Pod DNSConfig配置;
- DNS緩存代理,在每個集群節點上創建一個虛擬網絡接口(默認監聽IP 169.254.20.10),配合Pod的DNSConfig和節點上的網絡配置,Pod內產生的DNS請求會被該服務所代理。
工作原理圖如下圖所示:
說明1、已注入DNS本地緩存的Pod,默認會通過NodeLocal DNSCache的服務地址(169.254.20.10)解析域名;
2、NodeLocal DNSCache本地若無緩存應答解析請求,則將請求轉發到CoreDNS進行解析;
3、CoreDNS對于非集群內域名,會通過節點配置的DNS服務進行解析;
4、已注入DNS本地緩存的Pod,當無法連通NodeLocal DNSCache時,會繼續通過CoreDNS進行解析,此鏈路為備用鏈路;
5、未注入DNS本地緩存的Pod,會通過CoreDNS進行解析。
安裝NodeLocal DNSCache
可在云容器引擎控制臺安裝NodeLocal DNSCache插件,步驟請參考安裝插件。
Pod使用NodeLocal DNSCache
Pod需調整resolv.conf的nameservers配置,以將原本請求CoreDNS改為請求DNS緩存代理,有如下幾種方式可以配置:
- 借助DNSConfig動態注入控制器在Pod創建時配置DNSConfig自動注入,推薦使用此方式;
- 創建Pod時手動指定DNSConfig;
- 修改kubelet參數,并重啟節點kubelet。
注意第三種存在業務中斷風險,不推薦使用此方式。
配置DNSConfig自動注入
DNSConfig動態注入控制器可用于自動注入DNSConfig至新建的Pod中,無需手工配置Pod YAML進行注入。該控制器默認會監聽包含node-local-dns-injection=enabled標簽的命名空間中新建Pod的請求,可以通過以下命令給命名空間打上該標簽:
kubectl label namespace default node-local-dns-injection=enabled
開啟自動注入后,后續新創建的Pod會被增加以下字段,為了最大程度上保證業務DNS請求高可用,nameservers中會額外加入kube-dns的ClusterIP地址作為備份的DNS服務器:
dnsConfig:
nameservers:
- 169.254.20.10
- 172.21.0.10
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
dnsPolicy: None
Pod在同時滿足以下條件時,才會自動注入DNS緩存。如果Pod未注入DNS緩存服務地址,請檢查Pod是否滿足以下條件:
- 新建Pod不位于kube-system和kube-public命名空間;
- 新建Pod所在命名空間的Labels標簽包含node-local-dns-injection=enabled;
- 新建Pod所在命名空間的Labels不包含ECI Pod相關標簽,例如virtual-node-affinity-injection、eci等,或打上禁用DNS注入node-local-dns-injection=disabled標簽;
- 新建Pod的網絡為hostNetwork且DNSPolicy為ClusterFirstWithHostNet,或Pod為非hostNetwork且DNSPolicy為ClusterFirst。
手動指定DNSConfig
可以通過修改Pod進行手動指定DNSConfig,示例配置如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
namespace: default
spec:
containers:
- image: registry-vpc-gzsyj.crs.daliqc.cn:30015/library/nginx-photon:v1.8.6
name: demo
dnsPolicy: None
dnsConfig:
nameservers: ["169.254.20.10","172.21.0.10"]
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"
說明1、dnsPolicy:必須為None;
2、nameservers:配置成169.254.20.10和kube-dns的ClusterIP對應的IP地址;
3、searches:設置搜索域,保證集群內部域名能夠被正常解析;
4、ndots:默認為5,可以適當降低ndots以提升解析效率。更多信息,請參見resolv.conf。
配置kubelet啟動參數
kubelet通過–cluster-dns和–cluster-domain兩個參數來全局控制Pod DNSConfig。在 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 配置文件中需要增加一個–cluster-dns參數,設置值為鏈路本地地址169.254.20.10,染后執行sudo systemctl daemon-reload和sudo systemctl restart kubelet重啟kubelet。
--cluster-dns=169.254.20.10 --cluster-dns=<kube-dns ip> --cluster-domain=<search domain>
參數解釋如下:
- cluster-dns:部署Pod時,默認采用的DNS服務器地址,默認只引用了 kube-dns 的服務IP,需要增加一個對鏈路本地地址169.254.20.10的引用;
- cluster-domain:部署Pod時,默認采用的DNS搜索域,保持原有搜索域即可,一般為 cluster.local。
配置Pod使用NodeLocal DNSCache示例
通過在default命名空間下部署示例應用,演示如何配置應用使用NodeLocal DNSCache.執行以下命令,給接入NodeLocal DNSCache的應用所在的命名空間(default)設置標簽:
kubectl label namespace default node-local-dns-injection=enabled
在集群的default命名空間下部署示例應用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- image: registry-vpc-gzsyj.crs.daliqc.cn:30015/library/nginx-photon:v2.5.3
name: demo
查看創建的Pods:
# kubectl get po -l app=nginx-demo
NAME READY STATUS RESTARTS AGE
nginx-demo-748fb499d7-2xtd8 1/1 Running 0 4s
nginx-demo-748fb499d7-q84dc 1/1 Running 0 4s
執行以下命令,查看Pod的dnsConfig是否已經接入NodeLocal DNSCache:
kubectl get pod nginx-demo-748fb499d7-2xtd8 -o=jsonpath='{.spec.dnsConfig}'
預期輸出:
map[nameservers:[169.254.20.10 172.21.0.10] options:[map[name:ndots value:5]] searches:[default.svc.cluster.local svc.cluster.local cluster.local]]
當輸出以上內容時,說明成功為應用接入NodeLocal DNSCache。開啟自動注入后,新創建的Pod會被增加以下字段,為了最大程度上保證業務DNS請求高可用,nameservers中會額外加入kube-dns服務的ClusterIP地址(172.21.0.10)作為備份的DNS服務器:
dnsConfig:
nameservers:
- 169.254.20.10
- 172.21.0.10
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
dnsPolicy: None