DNS最佳實踐
DNS是Kubernetes集群中至關重要的基礎服務之一,在客戶端設置不合理、集群規模較大等情況下DNS容易出現解析超時、解析失敗等現象。本文介紹Kubernetes集群中DNS的最佳實踐,幫助您避免此類問題。
前提條件
- 創建Kubernetes集群
- 獲取集群KubeConfig并通過kubectl工具連接集群
優化域名解析請求
DNS域名解析請求是Kubernetes最高頻的網絡行為之一,其中很多請求是可以優化和避免的。您可以通過以下方式優化域名解析請求:
- (推薦)使用連接池:當一個容器應用需要頻繁請求另一服務時,推薦使用連接池。連接池可以將請求上游服務的鏈接緩存在內存中,避免每次訪問時域名解析和TCP建連的開銷。
- (推薦)使用DNS緩存:當您的應用無法改造成通過連接池連接另一服務時,可以考慮在應用側緩存DNS解析結果。
- 優化resolv.conf文件:由于resolv.conf文件中ndots和search兩個參數的機制作用,容器內配置域名的不同寫法決定了域名解析的效率。
- 優化域名配置:當容器內應用需要訪問某域名時,可以最大程度減少域名解析嘗試次數,繼而減少域名解析耗時。
使用合適的容器鏡像
Alpine容器鏡像內置的musl libc庫與標準glibc的實現存在以下差異:
- 3.3及更早版本Alpine不支持search參數,不支持搜索域,無法完成服務發現。
- 并發請求/etc/resolv.conf中配置的多個DNS服務器,導致NodeLocal DNSCache優化失效。
- 并發使用同一Socket請求A和AAAA記錄,在舊版本內核上觸發Conntrack源端口沖突導致丟包問題。
當Kubernetes集群中部署的容器采用了Alpine作為基礎鏡像時,可能會因為上述musl libc特性而無法正常解析域名,建議嘗試更換基礎鏡像,如Debian、CentOS等。
避免IPVS缺陷導致的DNS概率性解析超時問題
當集群使用IPVS作為kube-proxy負載均衡模式時,您可能會在CoreDNS縮容或重啟時遇到DNS概率性解析超時的問題。
您可以通過以下任意方式降低IPVS缺陷的影響:
- 使用節點DNS緩存NodeLocal DNSCache。
- 修改kube-proxy中IPVS UDP會話保持的超時時間。
使用節點DNS緩存NodeLocal DNSCache
在云容器引擎集群中部署NodeLocal DNSCache可以提升服務發現的穩定性和性能,NodeLocal DNSCache通過在集群節點上作為DaemonSet運行DNS緩存代理來提高集群DNS性能。
使用合適的CoreDNS版本
CoreDNS對Kubernetes版本實現了較好的向后兼容,建議您保持CoreDNS版本為較新的穩定版本。云容器引擎插件市場中提供了CoreDNS的安裝、升級、配置能力,您可以關注插件市場中插件狀態,若CoreDNS組件顯示可升級,請盡快選擇業務低峰期進行升級。
CoreDNS v1.7.0以下的版本存在風險隱患,包括且不僅限于以下:
- CoreDNS與APIServer連通性異常(例如APIServer重啟、APIServer遷移、網絡抖動)時,CoreDNS會因錯誤日志寫入失敗導致容器重啟。
- 啟動CoreDNS時會占用額外內存,默認采用的Memory Limit在較大規模集群下可能觸發OOM(OutOfMemory)問題,嚴重時可能導致CoreDNS Pod反復重啟無法自動恢復。
- CoreDNS存在若干可能影響Headless Service域名、集群外部域名解析的問題。
監控CoreDNS運行狀態
監控指標
CoreDNS通過標準的Promethues接口暴露出解析結果等健康指標,發現CoreDNS服務端甚至上游DNS服務器的異常。
運行日志
在DNS異常發生的情況下,CoreDNS日志有助于您快速診斷異常根因。建議您開啟CoreDNS域名解析日志和其SLS日志采集。
合理調整集群CoreDNS部署狀態
CoreDNS應部署于您的Kubernetes集群中,默認情況下與您的業務容器運行在同樣的集群節點上,注意事項如下:
- 合理調整CoreDNS副本數
- 合理分配CoreDNS副本運行的位置
- 手動擴容副本數
- 自動擴容副本數(cluster-autoscaler)
- 基于CPU負載指標自動擴容副本數(HPA)
- 使用自定義參數完成CoreDNS獨占節點部署
合理調整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就緒探針插件