K8s离线环境CoreDNS v1.8.0安装与避坑指南

发布时间:2026/11/6 2:04:29
K8s离线环境CoreDNS v1.8.0安装与避坑指南 简介面向 Kubernetes 集群部署与运维场景的 CoreDNS v1.8.0 镜像离线包主要服务于需要在 k8s v1.21.2 环境中搭建或修复集群 DNS 服务的工程师尤其适合内网、离线环境或镜像拉取受限时使用可解决集群初始化阶段 DNS 组件无法正常拉取的问题。压缩包共 8 个文件以 4 个 json 清单与配置描述文件、2 个 tar 层数据包及 2 个 version 版本标识文件为主整体约 40.62MB结构符合容器镜像分层存储规范便于直接导入本地镜像仓库或节点。已有 409 人学习下载具备一定参考基础。借助该包可快速完成 CoreDNS 镜像的离线加载与版本核对配合清单文件确认镜像层完整性减少因网络问题导致的部署阻塞适合作为 k8s 集群 DNS 组件部署与排错的配套素材。1. 从一次 CoreDNS 镜像拉不下来说起k8s 集群里最容易被忽略的组件去年帮一个团队排查 k8s 集群里 DNS 解析间歇性超时的问题翻遍 Service、Endpoint、NetworkPolicy 都没毛病最后定位到 CoreDNS 的 Pod 一直卡在 ImagePullBackOff——节点在内网官方镜像仓库根本连不上。这种场景太常见了k8s 集群能起来业务也能跑唯独 DNS 这个“黑匣子”组件装不好表现就是服务间调用偶发 5 秒超时、headless Service 解析不到、StatefulSet 的 Pod 之间互相找不到。CoreDNS v1.8.0 是 k8s 1.191.21 时代配套的经典版本很多离线环境和老集群至今还在用它而coredns_v1.8.0.tar.gz这种离线包正是为“节点不能出网”的场景准备的。这篇笔记按我实际装过一遍的顺序写先列环境、再导镜像、配 Corefile、改 Deployment最后验证解析链路中间把踩过的坑一并记下来。2. 装前把环境列清楚版本、节点、镜像三件事2.1 版本对齐CoreDNS 和 k8s 的配套关系CoreDNS 不是随便挑个版本就能往集群里塞的。k8s 各版本对 CoreDNS 有推荐配套v1.8.0 大致对应 k8s 1.191.21 这一段再往后的集群官方推荐已经推到 1.8.4、1.8.6 甚至 1.9.x。版本错配的典型症状不是起不来而是“起来了但解析行为不对”——比如某些 k8s 版本依赖 CoreDNS 的kubernetes插件返回特定格式的 SRV 记录老版本插件行为有差异业务侧表现为 gRPC 服务发现失败。我一般先确认集群版本再决定要不要用这个包# 查看集群服务端版本决定 CoreDNS 配套版本 kubectl version --short # 查看当前集群里 CoreDNS 的镜像和副本状态 kubectl -n kube-system get deploy coredns -o wide kubectl -n kube-system get pods -l k8s-appkube-dns -o wide第一条命令输出里的 Server Version 是判断依据后两条用来确认集群里是否已经有 CoreDNS 在跑。如果已经有这次操作本质是“替换镜像版本”不是全新安装后面改 Deployment 时要保留原有的 tolerations、affinity 等字段别整段覆盖。提示如果集群版本明显高于 1.21用 v1.8.0 之前先想清楚——不是不能跑而是官方配套已经变了遇到解析异常时排查成本会高很多。2.2 节点与运行时镜像要导到每一台可能调度的节点离线包的核心价值在镜像。coredns_v1.8.0.tar.gz解开后通常是docker save出来的镜像 tar导入方式取决于节点用的是 Docker 还是 containerd。这一步最容易翻车的地方是只往 master 导了镜像结果 CoreDNS 被调度到 worker 节点照样 ImagePullBackOff。先确认运行时类型# 判断节点容器运行时输出含 docker:// 还是 containerd:// kubectl get nodes -o wide # 在目标节点上确认运行时命令是否存在 which docker ctr nerdctl 2/dev/nullkubectl get nodes -o wide的 CONTAINER-RUNTIME 列直接告诉你答案。Docker 节点用docker loadcontainerd 节点用ctr -n k8s.io images import注意命名空间必须是k8s.io否则 kubelet 看不到导入的镜像——这是 containerd 环境里最高频的坑之一。2.3 解包与镜像清单核对动手前先把包解开看清楚里面有什么别急着 load# 解包并查看内容确认是镜像 tar 还是带 yaml 的整套文件 tar -tzf coredns_v1.8.0.tar.gz # 解压到工作目录 mkdir -p /opt/coredns-offline tar -xzf coredns_v1.8.0.tar.gz -C /opt/coredns-offline ls -lh /opt/coredns-offlinetar -tzf只列目录不解压用来快速判断包结构确认无误再解压。如果包里同时带了 Deployment yaml 和 ConfigMap后面配置 Corefile 时可以直接参考但不要盲目 apply——离线包里的 yaml 往往带着打包者自己的副本数、资源限制直接套到你的集群上可能资源不够或副本过多。3. 导入镜像与替换 Deployment把 v1.8.0 塞进集群3.1 Docker 运行时节点的镜像导入Docker 节点最省事docker load之后镜像 tag 就还原了# 在每一台可能运行 CoreDNS 的节点上执行 docker load -i /opt/coredns-offline/coredns_v1.8.0.tar # 确认镜像已导入tag 应为 coredns/coredns:1.8.0 docker images | grep coredns-i指定输入文件。load 完成后务必用docker images核对 tag——有些离线包在打包时改过 tag比如打成coredns:latest或带私有仓库前缀这时候要么重新 tag要么改 Deployment 里的 image 字段两边必须对上。我一般倾向于重新 tag 成官方名字保持和上游 yaml 一致减少后续维护时的困惑。3.2 containerd 运行时节点的导入方式containerd 节点没有 docker 命令用 ctr# 注意 -n k8s.io这是 kubelet 使用的命名空间 ctr -n k8s.io images import /opt/coredns-offline/coredns_v1.8.0.tar # 核对导入结果 ctr -n k8s.io images ls | grep coredns-n k8s.io不能省省了镜像会进 default 命名空间kubelet 完全看不见表现就是“明明导入了还是拉不到”。如果节点上装了 nerdctl也可以用nerdctl -n k8s.io load -i效果一样。导入后如果 tag 不对用ctr -n k8s.io images tag修正。3.3 修改 Deployment 的镜像与拉取策略镜像到位后改 Deployment。关键是imagePullPolicy必须设成IfNotPresent或Never否则 kubelet 还是会尝试联网拉取# 直接改镜像保留其余字段不动 kubectl -n kube-system set image deploy/coredns \ corednscoredns/coredns:1.8.0 # 把拉取策略改成 IfNotPresent避免离线环境反复重试 kubectl -n kube-system patch deploy coredns --typejson -p[ {op:replace,path:/spec/template/spec/containers/0/imagePullPolicy,value:IfNotPresent} ]set image的语法是容器名镜像容器名要从kubectl get deploy coredns -o yaml里确认默认叫coredns。patch 用 JSON Patch 精确改一个字段比edit安全不会误改其他配置。改完观察滚动更新kubectl -n kube-system rollout status deploy/coredns --timeout120s kubectl -n kube-system get pods -l k8s-appkube-dns -o widerollout status会阻塞到更新完成或超时超时说明新 Pod 没起来接着看 describe 和 logs。3.4 Corefile 配置v1.8.0 的插件顺序有讲究CoreDNS 的行为全在 Corefile 里。v1.8.0 的默认配置大致是kubernetes、prometheus、forward、cache、loop、reload、loadbalance这一套插件顺序影响处理链路不能随意调换# 查看当前 Corefile kubectl -n kube-system get configmap coredns -o yaml # 编辑 Corefile改完保存即生效reload 插件会热加载 kubectl -n kube-system edit configmap coredns一个能跑通的典型 Corefile 长这样.:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance }kubernetes插件的pods insecure决定 Pod 记录是否返回ttl 30控制记录缓存时间调小能更快感知 Endpoint 变化但会增加 apiserver 压力forward . /etc/resolv.conf把集群外域名转给节点 DNS离线环境里如果节点 DNS 不可达外部域名解析会超时这时候要改成内网 DNS 地址loop插件用来检测转发环路缺了它遇到环路会直接把 CPU 打满。改完 ConfigMap 后reload插件大约 30 秒内热加载不用重启 Pod。4. 避坑与排查装 CoreDNS 时最容易翻车的五件事4.1 现象Pod 一直 ImagePullBackOff节点上明明有镜像原因通常是三种镜像导入了但 tag 和 Deployment 里写的不一致containerd 节点导入时漏了-n k8s.ioimagePullPolicy还是Always。解决顺序是先crictl images或docker images核对 tag再kubectl describe pod看事件里的完整镜像名最后确认拉取策略。我遇到过打包时 tag 带docker.io/前缀、Deployment 里写的是短名的情况两边字符串必须完全一致。4.2 现象CoreDNS 起来了但集群内域名解析全部超时先看 CoreDNS 日志里有没有plugin/loop报错。loop检测到转发环路会直接让实例不健康典型原因是节点/etc/resolv.conf指向的 DNS 又把查询转回了 CoreDNS 自己。解决是把forward的目标改成明确的内网 DNS IP而不是依赖/etc/resolv.conf。另一个常见原因是 NetworkPolicy 把 kube-system 的 53 端口封了用kubectl exec进业务 Pod 手动nslookup验证。4.3 现象滚动更新卡住新 Pod Pending多半是节点资源不够或亲和性不满足。v1.8.0 默认 requests 是 100m CPU / 70Mi 内存小集群里如果节点已经很满新 Pod 调度不上去旧 Pod 又因为滚动策略不会先删。用kubectl describe pod看 Events 里的调度失败原因临时调低 requests 或加节点都能解。离线环境里还要注意如果集群开了 Pod 安全策略新镜像的 securityContext 可能不满足。4.4 现象解析偶发 5 秒超时日志里大量 SERVFAIL这是 k8s 里经典的 conntrack 竞争问题和 CoreDNS 版本关系不大但 v1.8.0 时代特别常见。表现是业务侧偶发 5 秒延迟CoreDNS 日志里能看到重传。缓解手段是给 CoreDNS Pod 加dnsConfig里的options ndots:5调整、或者在内核侧调 conntrack 参数。另一个方向是确认cache插件的 TTL 是否过短导致查询量过大适当调大能降低压力。4.5 现象改完 Corefile 不生效reload插件有轮询间隔默认 30 秒改完立刻测可能还是旧配置。另外 ConfigMap 更新后 kubelet 同步到 Pod 内文件也有延迟两个延迟叠加等一分钟再验证比较稳妥。如果超过两分钟还不生效检查 Corefile 语法——reload插件遇到语法错误会保留旧配置并打日志kubectl logs里能看到具体行号。5. 装完怎么验证从 Pod 到解析链路走一遍验证不能只看 Pod 是不是 Running要按链路逐层确认。第一步看副本和就绪状态kubectl -n kube-system get pods -l k8s-appkube-dns -o wide kubectl -n kube-system get endpoints kube-dnsPod 必须是Running且READY 1/1Endpoints 里要有对应 IP。第二步从集群内发起真实解析起一个临时 Pod 测# 解析集群内 Service应返回 ClusterIP kubectl run dns-test --rm -it --imagebusybox:1.28 --restartNever -- \ nslookup kubernetes.default.svc.cluster.local # 解析外部域名验证 forward 链路 kubectl run dns-test --rm -it --imagebusybox:1.28 --restartNever -- \ nslookup www.example.com第一条验证kubernetes插件第二条验证forward插件两条都通说明主链路没问题。第三步看指标v1.8.0 的prometheus插件在 9153 端口暴露指标端口转发出来看几个关键值kubectl -n kube-system port-forward svc/kube-dns 9153:9153 curl -s localhost:9153/metrics | grep -E coredns_dns_(requests_total|responses_total)requests_total持续增长说明流量进来了responses_total里rcodeNOERROR占绝大多数才正常SERVFAIL 比例高就要回头查 4.4 那条。最后一步是压力下的稳定性连续解析几十次看有没有偶发超时我一般用循环跑nslookup二十次出现一次 5 秒延迟就说明 conntrack 或上游有问题别急着收工。从那以后我每次换 CoreDNS 镜像都强制走一遍“Pod 就绪 → 集群内解析 → 外部解析 → 指标核对 → 循环压测”这五步少一步都可能在上线后半夜被叫起来。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询