主题
RKE2 集群通过 CoreDNS hosts 插件配置静态域名解析
在 Rancher 创建的 RKE2 集群中,经常遇到这样的需求:集群内的 Pod 需要把某个特定域名(最典型的就是 Rancher Server 自己的域名 rancher.example.com)解析到一个固定 IP,而不是走外部 DNS。比如集群节点无法访问企业 DNS、或希望集群内访问 Rancher 时绕过 LB 直接指向某台固定服务器。
这种场景不需要改每个 Pod 的 hostAliases,也不需要在每个节点改 /etc/hosts 后逐个维护,标准做法是直接修改 RKE2 内置 CoreDNS 的 Corefile,注入 hosts 插件,让整个集群的 DNS 解析层统一返回静态映射。本文基于生产环境的实际操作整理,覆盖 Corefile 修改、滚动重启、Pod 内验证以及 ConfigMap 被 Helm 管理时的持久化注意事项。
一、应用场景与整体思路
典型场景:
- 通过 Rancher 创建下游 RKE2 集群后,下游集群的 agent(cattle-cluster-agent 等)需要持续访问 Rancher Server 域名。
- 企业内网 DNS 尚未收录该域名,或希望集群内对该域名的解析固定指向
192.168.10.140。 - 宿主机层面可以在
/etc/hosts里加映射解决节点自身的解析,但 Pod 的 DNS 查询走的是 CoreDNS,不会读宿主机 hosts 文件,必须在 CoreDNS 层处理。
整体思路:
- 编辑 kube-system 命名空间下的 CoreDNS ConfigMap,在 Corefile 中加入
hosts插件块,写入「IP 域名」映射。 - 滚动重启 CoreDNS Deployment 使配置生效。
- 在 Pod 内用
nslookup验证解析结果。
二、修改 CoreDNS ConfigMap
2.1 准备 kubectl 环境
登录 RKE2 的 master 节点宿主机,配置 kubeconfig 和 kubectl:
bash
mkdir -p ~/.kube
cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
ln -sf /var/lib/rancher/rke2/bin/kubectl /usr/local/bin/kubectl2.2 编辑 ConfigMap 注入 hosts 插件
bash
kubectl edit configmap rke2-coredns-rke2-coredns -n kube-system说明:RKE2 通过 Helm chart 部署 CoreDNS,ConfigMap 名称在不同 RKE2 版本上可能是 rke2-coredns-rke2-coredns 或 rke2-coredns,以 kubectl get cm -n kube-system | grep coredns 实际查到的为准。
在 Corefile 中 .:53 区块内加入 hosts 插件,修改后的完整 Corefile 示例如下:
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: rke2-coredns-rke2-coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 10s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
hosts {
192.168.10.140 rancher.example.com
fallthrough
}
prometheus 0.0.0.0:9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}配置要点:
hosts块内每行一条映射,格式为IP 域名,与/etc/hosts语法一致,可写多行。fallthrough表示未匹配到的域名继续交给后续插件(这里是forward)处理,必须保留,否则只有映射表内的域名能解析,其他域名全部失败。- 除
hosts块外,其余插件保持 RKE2 默认配置不动,不要增删。
2.3 滚动重启 CoreDNS
CoreDNS 虽然配置了 reload 插件支持热加载,但 RKE2 场景下建议显式滚动重启,确保所有副本加载到新 Corefile:
bash
kubectl -n kube-system rollout restart deploy/rke2-coredns-rke2-coredns
kubectl -n kube-system rollout status deploy/rke2-coredns-rke2-coredns三、验证解析生效
起一个临时 Pod 验证集群内解析:
bash
kubectl run dns-test --rm -it --image=harbor.example.com/library/busybox:1.28 --restart=Never -- nslookup rancher.example.com预期输出中 Address 指向配置的静态 IP:
text
Server: 10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local
Name: rancher.example.com
Address 1: 192.168.10.140同时验证正常域名解析未受影响(确认 fallthrough 生效):
bash
kubectl run dns-test2 --rm -it --image=harbor.example.com/library/busybox:1.28 --restart=Never -- nslookup kubernetes.default.svc.cluster.local四、注意事项
4.1 ConfigMap 被 Helm 管理时的持久化问题
RKE2 的 CoreDNS 是通过 Helm chart(rke2-coredns)部署的,ConfigMap 上带有 Helm 的元数据标签。这带来一个风险:直接 kubectl edit 修改的 Corefile 属于"带外修改",当 RKE2 升级或 Helm chart 被重新 reconcile 时,ConfigMap 可能被 chart 的默认值覆盖,hosts 映射丢失。
持久化的正确做法是通过 HelmChartConfig 资源覆盖 chart 的 values,把自定义 Corefile 写进 chart 配置:
bash
kubectl apply -f - <<EOF
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-coredns
namespace: kube-system
spec:
valuesContent: |-
global:
clusterDNS: 10.43.0.10
servers:
- zones:
- zone: .
port: 53
plugins:
- name: errors
- name: health
configBlock: |-
lameduck 10s
- name: ready
- name: kubernetes
parameters: cluster.local in-addr.arpa ip6.arpa
configBlock: |-
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
- name: hosts
configBlock: |-
192.168.10.140 rancher.example.com
fallthrough
- name: prometheus
parameters: 0.0.0.0:9153
- name: forward
parameters: . /etc/resolv.conf
- name: cache
parameters: 30
- name: loop
- name: reload
- name: loadbalance
EOF说明:
- 如果不确定 chart values 结构,一个稳妥的折中办法是:先
kubectl edit改 ConfigMap 验证功能,确认生效后再把同样的内容落到 HelmChartConfig 中固化;同时在变更台账里登记"Corefile 有自定义 hosts 映射,RKE2 升级后需复核"。 - 每次 RKE2 版本升级后,执行
kubectl get cm rke2-coredns-rke2-coredns -n kube-system -o jsonpath='{.data.Corefile}' | grep hosts确认映射还在。
4.2 其他注意事项
- hosts 映射中的 IP 变更后需要同步修改 Corefile 并重启 CoreDNS,这类静态映射要登记台账,避免 IP 漂移后集群内解析悄悄指向旧地址。
- 宿主机
/etc/hosts的映射(解决节点自身解析)与 CoreDNS 的 hosts 插件(解决 Pod 解析)是两套独立机制,如两侧都需要,应同时维护并保持一致。 hosts插件在 Corefile 中的位置建议放在kubernetes之后、forward之前,确保静态映射优先于上游转发。
五、故障速查表
| 故障现象 | 可能原因 | 排查与处理 |
|---|---|---|
| Pod 内 nslookup 域名返回 NXDOMAIN | hosts 块缺少 fallthrough,或映射行格式错误 | 检查 Corefile 中 hosts 块语法;确认 IP 域名 之间是空格而非其他字符 |
| 修改 ConfigMap 后解析未生效 | CoreDNS 未重启,或改错了 ConfigMap(集群里同时存在 coredns 与 rke2-coredns 两个 cm) | kubectl get cm -n kube-system | grep coredns 确认生效的 cm;执行 rollout restart |
| 所有域名都无法解析,CoreDNS Pod CrashLoopBackOff | Corefile 语法错误(缩进、花括号不匹配) | kubectl logs -n kube-system deploy/rke2-coredns-rke2-coredns 看报错行;修正后重启 |
| RKE2 升级后静态解析丢失 | ConfigMap 被 Helm chart 重新渲染覆盖 | 按 4.1 节用 HelmChartConfig 固化自定义 Corefile |
| 静态域名可以解析,其他外部域名解析失败 | hosts 块误删了 fallthrough,或 forward 插件被改动 | 对比第二章的完整 Corefile 示例恢复默认插件链 |
| 宿主机上能解析,Pod 里不能解析 | 只改了宿主机 /etc/hosts,未改 CoreDNS | 按本文修改 CoreDNS ConfigMap;宿主机 hosts 对 Pod 无效 |