用kubectl管理Kubernetes域名配置与解析,核心是操作Service、Ingress和CoreDNS三类资源,Service负责集群内域名解析,Ingress负责外部域名路由,CoreDNS负责自定义解析规则。 掌握了这三者的查看和修改命令,你就能独立处理大部分K8s域名相关的场景。
域名解析在Kubernetes里的三条路径
想用好kubectl,先得明白域名在集群里是怎么走的,Kubernetes的域名体系不像传统物理机靠改/etc/hosts,它由三套机制协同工作:Service生成A记录,Ingress绑定外部域名,CoreDNS负责整张解析表。
Service:集群内域名解析的默认答案
集群内每个Service都会自动获得一条形如<service-name>.<namespace>.svc.cluster.local的DNS记录,这条记录指向Service的ClusterIP,Pod之间通过它互相访问,比如my-app.default.svc.cluster.local,在任何Pod里都能直接解析到对应的Service IP。
Ingress:把外部域名引进来的门卫
Ingress是外部域名进入集群的入口,它定义的是“域名+路径”到后端Service的映射,一个Ingress可以挂多个域名,每个域名下面挂多个路径,kubectl管理域名配置时,最常见的操作就是查看和修改Ingress规则。
CoreDNS:解析规则的执行者
CoreDNS是集群内的DNS服务器,Service记录是它自动生成的,但它的能力不止于此,你可以通过修改CoreDNS的ConfigMap,添加自定义域名、hosts映射、转发上游DNS等规则。
用kubectl查看域名配置排障第一步
域名解析出问题,第一步永远是“看清楚现状”,下面这几个命令,是排查时的主力。
kubectl查看ingress域名配置
想知道某个域名被路由到哪个Service,用kubectl get ingress加-o yaml最直接。
kubectl get ingress -n production kubectl get ingress my-ingress -n production -o yaml
前者列出所有Ingress的域名和对应后端,后者展示完整规则,你会在输出的spec.rules里看到host字段,那就是域名,http.paths.backend.service.name就是它转发的目标Service。
查Service的DNS记录怎么用
Service的DNS记录是自动生成的,kubectl没有专门的“查询DNS记录”子命令,但你可以通过kubectl get svc拿到IP,再确认解析是否正确,搭配dig或nslookup在Pod里验证更准确:
kubectl get svc -n production kubectl run test --image=busybox --restart=Never -- rm -rf /etc/resolv.conf && kubectl exec -it test -- nslookup my-app.production.svc.cluster.local
注意第二行用了rm -rf /etc/resolv.conf,这是临时绕过默认DNS搜索域,强制走完整FQDN查询,能帮你确认记录是否存在。
快速验证pod的域名解析结果
其实kubectl exec到任意Pod里直接解析就行了。
kubectl exec -it my-pod -- nslookup my-app kubectl exec -it my-pod -- cat /etc/resolv.conf
/etc/resolv.conf里会写着CoreDNS的Service地址,一般是一个ClusterIP,比如96.0.10,看到它,说明Pod已经被正确配置了DNS搜索域。
用kubectl修改域名配置的实战
光看不改不具备生产力,实际操作中,我经常遇到两种改动需求:改Ingress的域名规则,或者创建一个新的解析记录。
改ingress规则:kubectl edit还是patch
假设你要把app.example.com这个域名从旧Service切到新Service,最稳妥的方式是kubectl edit ingress my-ingress -n production,它会弹出默认编辑器,你直接改backend.service.name字段,保存后自动热更新。
但如果你在脚本或CI里改,用kubectl patch更干净。
kubectl patch ingress my-ingress -n production --type='json' -p='[{"op": "replace", "path": "/spec/rules/0/http/paths/0/backend/service/name", "value": "new-service"}]'
注意/spec/rules/0是第一条规则的索引,路径里的0和paths/0也要对应上真实结构,这个操作不会触发Ingress控制器重建,规则生效大概需要几秒到十几秒。
kubectl创建externalname服务指向外部域名
有时候你想让集群内的服务通过一个内部域名去访问外部系统,比如数据库在云厂商RDS上,这时可以用ExternalName类型的Service,它不创建ClusterIP,而是把DNS记录直接CNAME到外部域名,创建文件external-db.yaml:
apiVersion: v1 kind: Service metadata: name: external-db namespace: production spec: type: ExternalName externalName: mydb.cluster-ro.aws.example.com
然后执行:
kubectl apply -f external-db.yaml
随后Pod里访问external-db.production.svc.cluster.local,会自动解析到mydb.cluster-ro.aws.example.com的IP,这个方式用来迁移老系统挺好,不改代码就能把内部调用指向外部服务。
让service域名解析指向固定IP
除了ExternalName,你还可以用无Selector的Service搭配Endpoints来手动指定IP,Service的DNS记录照样存在,但解析结果是你自己控制的IP,操作方法:
kubectl create service clusterip my-custom --tcp=3306
然后手动创建Endpoints资源,指向目标IP,这在对接集群外VM时非常常用,相当于用kubectl搭了一座桥。
kubectl修改coredns配置,自定义解析规则
大多数场景下,Service和Ingress已经够用了,但遇到跨命名空间、自定义域名或者内部域名解析延迟高的时候,就得动CoreDNS。
kubectl修改coredns配置的正确姿势
CoreDNS的配置存在ConfigMap里,路径是kube-system命名空间下的coredns,你可以这样看当前配置:
kubectl get configmap coredns -n kube-system -o yaml
修改它有两种姿势,第一种是kubectl edit configmap coredns -n kube-system,直接改YAML里的Corefile字段,第二种是先用kubectl get导出到本地,改完再kubectl apply,我推荐第二种,因为可以对比改动前后。
比如想给集群加一条hosts映射,让internal.example.com解析到168.10.20,就在Corefile的.:53块下加一段:
hosts {
192.168.10.20 internal.example.com
fallthrough
}
改完保存,CoreDNS不会自动加载新配置,需要滚一下Pod:
kubectl rollout restart deployment/coredns -n kube-system
再等一下,用kubectl exec进任意Pod解析验证。
配置转发上游DNS的策略
团队内部有独立的DNS服务器,想让集群内的特定域名走它解析,CoreDNS可以配置forward和policy,例如把internal.example.com的查询转发到内网DNS:
internal.example.com:53 {
forward . 10.200.1.2
}
这段加在Corefile根块上方,表示这个域名区段的请求不交给集群内Service解析,直接转发到200.1.2,修改后同样需要重启CoreDNS,据Kubernetes官方文档,Corefile的改动默认不会热加载,必须重启Pod。
Q&A:kubectl域名解析常见问题
改了Service为什么域名还是老IP?
Service的DNS记录有缓存机制,CoreDNS根据Service的IP变化会更新A记录,但客户端(比如/etc/resolv.conf指到的DNS缓存)可能暂存旧结果,先确认kubectl get svc里的CLUSTER-IP是否变化;如果没有变化,是客户端缓存问题,在业务Pod里检查nscd或Java的JVM DNS缓存,改Service的clusterIP需要在创建前设置,或删掉重建,实际生产里多为方法缓存,不是DNS记录慢。
Ingress和Service的域名配置有什么区别?
Service的域名是集群内部的,格式固定,只能被集群内Pod解析,外部无法直接访问,Ingress的域名是集群外部的,由Ingress Controller监听并创建转发规则,解析到入口IP后,再按规则路由到Service,简单说,Service解决“内部怎么找服务”,Ingress解决“外部怎么进来”。
kubectl修改coredns配置后需要重启吗?
需要,kubectl修改ConfigMap只会更新配置数据,CoreDNS进程不会主动读取新配置,执行kubectl rollout restart deployment/coredns -n kube-system后,新Pod会重新加载ConfigMap,如果配置语法有误,CoreDNS会启动失败,排查时先看日志:kubectl logs -n kube-system deployment/coredns。
回到开头的结论:kubectl管理域名配置不是单一命令,而是围绕Service、Ingress、CoreDNS的一套组合拳,遇到域名解析问题,先用查看命令定位,再用修改命令落地,最后用Pod实测验证,这套流程走下来,集群域名配置就能牢牢掌握在你手里。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/926617.html


评论列表(3条)
这篇文章的内容非常有价值,我从中学习到了很多新的知识和观点。作者的写作风格简洁明了,却又不失深度,让人读起来很舒服。特别是记录部分,给了我很多新的思路。感谢分享这么好的内容!
@悲伤ai408:这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于记录的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!
@雨雨798:读了这篇文章,我深有感触。作者对记录的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!