概述
DNS作為k8s的關鍵基礎服務,在配置不合理,集群規模較大時,DNS容易出現解析超時、解析失敗等現象。本文介紹Kubernetes集群中CoreDNS配置優化的最佳實踐,幫助您避免此類問題。
前提條件
- 創建一個云容器引擎集群,具體操作步驟請參見新建云容器引擎集群。
- 通過kubectl連接集群,詳情請參見通過kubectl連接集群。
- 安裝CoreDNS插件(推薦安裝CoreDNS最新版本),詳情請參見CoreDNS介紹。
實踐方案
CoreDNS配置優化方案包含客戶端和服務端的實踐。
- 在客戶端,您可以通過使用合適的容器鏡像,優化域名解析請求,增加節點DNS緩存等方式來降低解析時延和減少解析異常。
- 優化域名解析請求
- 選擇合適的容器鏡像
- 避免IPVS缺陷導致的DNS概率性解析超時
- 使用節點DNS緩存(NodeLocal DNSCache)
- 謹慎調整節點的DNS配置
- 在服務端,您可以合理的調整CoreDNS部署狀態或者調整CoreDNS配置來提升集群CoreDNS的可用性和吞吐量。
- 監控CoreDNS運行狀態
- 合理調整CoreDNS部署狀態
- 合理配置CoreDNS
優化域名解析請求
DNS域名解析請求作為Kubernetes最高頻的網絡行為之一,我們可以通過以下方式優化域名解析請求:
- 優化容器內resolv.conf文件:容器內配置域名的不同寫法決定了域名解析的效率,關于resolv.conf文件中ndots和search兩個參數的機制詳情,請參見:DNS策略。
- 優化域名配置:當容器內應用需要訪問某域名,建議該域名按以下原則配置,可以最大程度減少域名解析嘗試次數和耗時。
- 同命名空間下,Pod訪問Service,優先使用
訪問,其中service-name代指Service名稱。 - 不同命名空間下,Pod訪問另一個命名空間的Service,優先使用
. 訪問,其中namespace-name代指Service所處的命名空間。 - Pod訪問集群外部域名時,優先使用FQDN類型域名訪問,這類域名通過常見域名最后加半角句號(.)的方式來指定地址,可以避免search搜索域拼接帶來的多次無效搜索,例如需要訪問天翼云,則優先使用FQDN類型域名來訪問。
- 同命名空間下,Pod訪問Service,優先使用
- 使用連接池:當一個容器應用需要頻繁請求另一服務時,推薦使用連接池。連接池可以緩存上游服務的鏈接信息,避免每次訪問服務時域名解析和創建TCP連接的開銷。
- 使用本地DNS緩存:當集群規模增大,DNS解析請求量變多,可以考慮在節點緩存DNS(NodeLocal DNSCache)解析結果,具體操作,請參見:NodeLocal DNSCache加速。
選擇合適的容器鏡像
如果在云容器引擎集群中部署的應用容器使用了Alpine作為基礎鏡像,可能會因為下述musl libc特性導致無法正常解析域名,此時建議嘗試更換基礎鏡像,如Debian、CentOS等。Alpine容器鏡像內置的musl libc庫與標準的glibc存在以下差異:
- 3.3版本及更早版本的Alpine不支持search參數,不支持搜索域,無法完成服務發現。
- 并發請求
etc/resolve.conf中配置的多個DNS服務器,導致節點DNS緩存的優化失效。 - 并發使用同一Socket請求A和AAAA記錄,在舊版本內核上會觸發Conntrack源端口沖突導致丟包問題。
避免IPVS缺陷導致的DNS概率性解析超時問題
當集群的kube-proxy負載均衡模式為IPVS時,縮容或重啟CoreDNS可能會遇到DNS概率性解析超時的問題。該問題由社區Linux內核缺陷導致,具體信息請查看社區。
您可以通過使用節點DNS緩存(NodeLocal DNSCache),降低IPVS缺陷的影響,具體操作請參見:NodeLocal DNSCache加速。
使用節點DNS緩存(NodeLocal DNSCache)
節點DNS緩存(NodeLocal DNSCache)可以提升服務發現的穩定性和性能,詳情請參見:NodeLocal DNSCache加速。
謹慎調整節點的DNS配置
CoreDNS啟動時會默認獲取實例所在節點 /etc/resolve.conf中的DNS配置,而且在CoreDNS重啟之前不會再重新加載該節點上的resolve.conf配置。建議保持集群中各個節點的resolve.conf配置一致,并在修改CoreDNS實例所在節點resolve.conf文件后及時重啟CoreDNS。
監控CoreDNS狀態
云容器引擎監控組件默認配置了CoreDNS相關的指標監控和告警規則。具體安裝操作請參見集群監控。
合理調整集群CoreDNS部署狀態
CoreDNS應部署于您的Kubernetes集群中,默認情況下與您的業務容器運行在同樣的集群節點上,注意事項如下:
- 合理調整CoreDNS副本數
- 合理分配CoreDNS副本運行的位置
- 手動擴容副本數
- 基于CPU負載指標自動擴容副本數(HPA)
合理調整CoreDNS副本數
建議您在任何情況下設置CoreDNS副本數應至少為2,且副本數維持在一個合適的水位以承載整個集群的解析。
CoreDNS所能提供的域名解析QPS與CPU消耗成正相關,開啟緩存的情況下,單個CPU可以支撐10000+ QPS的域名解析請求。不同類型的業務對域名請求的QPS需求存在較大差異,您可以觀察每個CoreDNS副本的峰值CPU使用量,如果其在業務峰值期間占用CPU大于一核,建議您對CoreDNS進行副本擴容。無法確定峰值CPU使用量時,可以保守采用副本數和集群節點數1:8的比值來部署,即每擴容8個集群節點,增加一個CoreDNS副本,但副本數不應大于10。針對100節點以上的集群,推薦使用節點DNS緩存NodeLocal DNSCache。
- 當集群節點數目長時間較為固定時,可以手動擴容副本數。
- 如果集群節點數持續增長,可以設置自動擴容副本數。
合理分配CoreDNS副本運行的位置
建議您在部署CoreDNS副本時,應將CoreDNS副本打散在不同可用區、不同集群節點上,避免單節點、單可用區故障。CoreDNS默認配置了按節點的弱反親和性,可能會因為節點資源不足導致部分或全部副本部署在同一節點上,如果遇到這種情況,請刪除Pod重新觸發其調度來調整。
CoreDNS所運行的集群節點應避免CPU、內存用滿的情況,否則會影響域名解析的QPS和響應延遲。當集群節點條件允許時,可以考慮使用自定義參數將CoreDNS調度至獨立的集群節點上,以提供穩定的域名解析服務。關于CoreDNS調度至獨立的集群節點的方式,請參見使用自定義參數完成CoreDNS獨占部署。
手動擴容副本數
當集群節點數長時間較為固定時,您可以通過以下命令擴容CoreDNS副本數。
kubectl?scale?--replicas={target}?deployment/coredns?-n?kube-system
基于CPU負載指標自動擴容副本數(HPA)
由于HPA會頻繁觸發CoreDNS副本縮容,建議您不要使用容器水平擴縮容(HPA),如果您的場景下必須依賴于HPA,請參考以下基于CPU負載的策略配置:
apiVersion:?autoscaling/v2beta1
kind:?HorizontalPodAutoscaler
metadata:
??name:?coredns-hpa
??namespace:?kube-system
spec:
??scaleTargetRef:
????apiVersion:?apps/v1
????kind:?Deployment
????name:?coredns
??minReplicas:?2
??maxReplicas:?10
??metrics:
??-?type:?Resource
????resource:
??????name:?cpu
??????targetAverageUtilization:?50
合理配置CoreDNS
云容器引擎僅提供CoreDNS的默認配置,您應關注配置中的各個參數、優化其配置,以使CoreDNS可以為您的業務容器正常提供DNS服務。CoreDNS的配置非常靈活。
早期版本隨Kubernetes集群部署的CoreDNS默認配置可能存在一些風險,推薦您按以下方式檢查和優化:
- 合理調整CoreDNS的資源Request和Limit
- 關閉kube-dns服務的親和性配置
- 配置CoreDNS優雅退出
- 配置Ready就緒探針插件