总述
DNS 作为 Kubernetes 集群中服务访问的第一环节,其稳定性和性能至关重要,如何以更优的方式配置和使用 DNS,涉及到方方面面,本文档将总结这些最佳实践。
选择最佳 CoreDNS 版本
下表列出了随各个版本 TKE 集群默认部署的 CoreDNS 版本:
由于历史原因,可能会有 v1.18 及以上版本的集群仍然部署 v1.6.2 版本的 CoreDNS,如果当前 CoreDNS 版本不满足需求,可以按如下指引手动升级:
配置合适的 CoreDNS 副本数
1. TKE 默认设置 CoreDNS 副本数为2,且配置了 podAntiAffinity
使两副本部署在不同节点。
3. 一般根据集群内业务访问 DNS 的 QPS 来确定 CoreDNS 合理的副本数,也可以根据节点数以及总核数来确定,在安装 NodeLocal DNSCache 后,建议 CoreDNS 最大副本数为10,可以按照如下方式配置:
副本数 = min ( max ( ceil (QPS/10000), ceil (集群节点数/8) ), 10 )
示例:
集群节点数为 10,DNS 服务请求 QPS 为 22000,则副本数为 3。
集群节点数为 30,DNS 服务请求 QPS 为 15000,则副本数为 4。
集群节点数为 100,DNS 服务请求 QPS 为 50000,则副本数为 10(已部署 NodeLocal DNSCache)
data:
ladder: |-
{
"coresToReplicas":
[
[ 1, 1 ],
[ 128, 3 ],
[ 512,4 ],
],
"nodesToReplicas":
[
[ 1, 1 ],
[ 2, 2 ]
]
}
使用 NodeLocal DNSCache
在 TKE 集群中部署 NodeLocal DNSCache 可以提升服务发现的稳定性和性能,其通过在节点上作为 DaemonSet 运行 DNS 缓存代理来提高集群 DNS 性能。
关于更多 NodeLocal DNSCache 的介绍及如何在 TKE 集群中部署 NodeLocal DNSCache 的具体步骤,参见:在 TKE 集群中使用 NodeLocal DNS Cache。 配置 CoreDNS 平滑升级
当重启节点或者升级 CoreDNS 时,可能导致 CoreDNS 部分副本在一段时间不可用,可以通过以下配置,最大程度保证 DNS 服务的可用性,实现平滑升级。
kube-proxy 为 iptables 模式,无需配置
iptables模式下,kube-proxy会在同步iptables规则后及时清理遗留的conntrack表项,不存在会话保持问题,无需配置。
kube-proxy 为 IPVS 模式,配置 IPVS UDP 协议的会话保持超时时间
IPVS 模式下,如果业务自身没有 UDP 服务,可以通过降低 IPVS UDP 协议的会话保持超时时间来尽量减少服务不可用的时间。
1. 集群版本大于等于1.18,kube-proxy 提供参数--ipvs-udp-timeout
,默认为0s,也即使用系统默认值:300s,推荐配置为--ipvs-udp-timeout=10s
。按如下方式配置 kube-proxy DaemonSet:
spec:
containers:
- args:
- --kubeconfig=/var/lib/kube-proxy/config
- --hostname-override=$(NODE_NAME)
- --v=2
- --proxy-mode=ipvs
- --ipvs-scheduler=rr
- --nodeport-addresses=$(HOST_IP)/32
- --ipvs-udp-timeout=10s
command:
- kube-proxy
name: kube-proxy
2. 集群版本小于等于1.16,kube-proxy 不支持该参数,可以使用ipvsadm
工具批量在节点侧修改:
yum install -y ipvsadm
ipvsadm --set 900 120 10
3. 配置完成后,可以按如下方式验证:
ipvsadm -L --timeout
Timeout (tcp tcpfin udp): 900 120 10
注意:
在配置完成后,需要等待5min,再继续后面的步骤;如果业务有使用 UDP 服务,请 提交工单 来寻求帮助。 配置 CoreDNS 优雅退出
已经收到退出信号的副本,可以通过配置 lameduck 使其能在一段时间内继续提供服务,按如下方式配置 CoreDNS 的 configmap(仅展示 CoreDNS 1.6.2版本的部分配置,其它版本配置参见 手动升级 CoreDNS): .:53 {
health {
lameduck 30s
}
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
}
配置 CoreDNS 服务就绪确认
新副本启动后,需确认其服务就绪,再加入 DNS 服务的后端列表。
1. 打开 ready 插件,按如下方式配置 CoreDNS 的 configmap(仅展示 CoreDNS 1.6.2版本的部分配置,其它版本配置参见 手动升级 CoreDNS): .:53 {
ready
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
}
2. 为 CoreDNS 增加配置 ReadinessProbe:
readinessProbe:
failureThreshold: 5
httpGet:
path: /ready
port: 8181
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
配置 CoreDNS 使用 UDP 访问上游 DNS
当 CoreDNS 需要与上游 DNS Server 通信时,它将默认使用客户端请求的协议(UDP 或者 TCP),而 TKE 中 CoreDNS 的上游默认为 VPC 内的 DNS 服务,该服务对 TCP 的支持在性能上比较有限,因此推荐做如下配置,显式指定 UDP(尤其在安装了 NodeLocal DNSCache 时):
.:53 {
forward . /etc/resolv.conf {
prefer_udp
}
}
配置 CoreDNS 过滤 HINFO 请求
VPC 内的 DNS 服务不支持 HINFO 类型的 DNS 请求,因此推荐做如下配置,在 CoreDNS 侧过滤此类请求(尤其在安装了 NodeLocal DNSCache 时):
.:53 {
template ANY HINFO . {
rcode NXDOMAIN
}
}
配置 CoreDNS 对 IPv6 类型的 AAAA 记录查询返回域名不存在
当业务不需要做 IPv6 的域名解析时,可以通过该配置降低通信成本:
.:53 {
template ANY AAAA {
rcode NXDOMAIN
}
}
配置自定义域名解析
手动升级
升级到1.7.0
1. 编辑 coredns configmap
kubectl edit cm coredns -n kube-system
修改为以下内容:
.:53 {
template ANY HINFO . {
rcode NXDOMAIN
}
errors
health {
lameduck 30s
}
ready
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf {
prefer_udp
}
cache 30
reload
loadbalance
}
2. 编辑 coredns deployment
kubectl edit deployment coredns -n kube-system
替换镜像为
image: ccr.ccs.tencentyun.com/tkeimages/coredns:1.7.0
升级到1.8.4
1. 编辑 coredns clusterrole
kubectl edit clusterrole system:coredns
修改为以下内容:
rules:
- apiGroups:
- '*'
resources:
- endpoints
- services
- pods
- namespaces
verbs:
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
2. 编辑 coredns configmap
kubectl edit cm coredns -n kube-system
修改为以下内容:
.:53 {
template ANY HINFO . {
rcode NXDOMAIN
}
errors
health {
lameduck 30s
}
ready
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf {
prefer_udp
}
cache 30
reload
loadbalance
}
3. 编辑 coredns deployment
kubectl edit deployment coredns -n kube-system
替换镜像为
image: ccr.ccs.tencentyun.com/tkeimages/coredns:1.8.4
配置业务建议
除了 DNS 服务的最佳实践外,在业务侧,也可以做适当的优化配置,来提升 DNS 的使用体验。
1. 默认情况下,Kubernetes 集群中的域名解析往往需要经过多次请求才能解析到。查看 pod 内 的 /etc/resolv.conf
可以知道 ndots
选项默认为 5。例如,在 debug 命名空间查询 kubernetes.default.svc.cluster.local
这个 service:
域名中有 4 个 .
,小于 5,尝试拼接上第一个 search 进行查询,即kubernetes.default.svc.cluster.local.debug.svc.cluster.local
,查不到该域名。
继续尝试 kubernetes.default.svc.cluster.local.svc.cluster.local
,查不到该域名。
继续尝试 kubernetes.default.svc.cluster.local.cluster.local
,仍然查不到该域名。
尝试不加后缀,即 kubernetes.default.svc.cluster.local
,查询成功,返回响应的 ClusterIP。
2. 上面一个简单的 service 域名解析需要经过 4 轮解析才能成功,集群中充斥着大量无用的 DNS 请求。因此需要根据业务配置的访问方式来为其设置合理的 ndots 来降低查询次数:
spec:
dnsConfig:
options:
- name: ndots
value: "2"
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: diagnosis
3. 同时,可以优化业务访问服务的域名配置:
Pod 访问本命名空间的 Service,使用 <service-name>
访问。
Pod 访问其它命名空间的 Service,使用 <service-name>.<namespace-name>
访问。
Pod 访问外部域名,使用 FQDN 类型域名访问,在域名最后添加 .
以减少无效搜索。
相关内容
配置介绍
errors
输出错误信息。
health
上报健康状态,用于配置健康检查,如 livenessProbe
,默认监听 8080 端口,路径为 http://localhost:8080/health
注意:
如果有多 Server 块,health 只能配置一次,或者配置在不同端口。
com {
whoami
health :8080
}
net {
erratic
health :8081
}
lameduck
用于配置优雅退出的时间,实现方式是 hook 在 CoreDNS 收到退出信号时,在其中执行 sleep,以保证时限内可以继续提供服务。
ready
上报插件状态,用于配置服务就绪检查,如readinessProbe
,默认监听 8181 端口,路径为http://localhost:8181/ready
kubernetes
Kubernetes 插件,支持集群内服务解析。
prometheus
metrics 数据接口,用于获取监控数据,路径为 http://localhost:9153/metrics
forward(proxy)
将无法处理的请求转发到上游 DNS 服务器。默认使用宿主机的 /etc/resolv.conf
配置。
根据 forward aaa bbb 的配置,内部会维护一个 udns 的列表 [aaa,bbb]
当有请求到来时,根据预设的策略(random|round_robin|sequential,默认 random)在列表 [aaa,bbb] 中找一个 udns 发请求,如果失败,则找出下一个 udns 进行尝试,同时针对失败的 udns 启动周期性的健康监测,直到其变为健康,停止健康监测。
在健康监测的过程中,如果连续几次(默认两次)监测失败,则将该 udns 状态置为 down,后面从列表中选 udns 时将跳过状态为 down 的 udns。
当所有的 udns 都 down 时,随机选一个 udns 做转发。
因此,可以认为 coredns 有在多个 upstream 间智能切换的能力,forward 列表里只要有一个可用的 udns,则请求可以成功。
cache
DNS 缓存。
reload
热加载 Corefile,修改 ConfigMap 后,会在两分钟内加载新配置。
loadbalance
提供基于 DNS 的负载均衡功能,随机响应记录的顺序。
CoreDNS 资源占用
主要取决于集群内 Pod 数和 Service 数。
受打开缓存大小的影响。
受 QPS 的影响。
以下数据来自于 CoreDNS 官方:
MB required (default settings) = (Pods + Services) / 1000 + 54
主要受 QPS 的影响。
以下数据来自于 CoreDNS 官方:
单副本 CoreDNS,运行节点规格:2 vCPUs, 7.5 GB memory。
本页内容是否解决了您的问题?