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就绪探针插件