文章目录
Calico 与 CoreDNS 网络组件详解
场景:执行
kubectl apply -f calico.yaml后,kube-system中新增了 3 个calico-node、1 个calico-kube-controllers,加上原有的 2 个coredns,一共 6 个 Pod 尚未正常运行。本文按「各自负责什么 → 为什么是这个数量 → 起不来怎么查」的顺序,把 Calico、CoreDNS 与集群内部通信机制串起来。
一、组件速览
| 组件 | 数量 | 部署方式 | 核心职责 |
|---|---|---|---|
calico-node | 3 | DaemonSet | 每节点上的网络执行者:配置 Pod 网络、维护路由、落实网络策略 |
calico-kube-controllers | 1 | Deployment | 集群级控制器:监听 K8s 资源,协调 Calico 的节点、端点、IPAM 等状态 |
coredns | 2 | Deployment | 集群 DNS:把 Service 域名解析成 ClusterIP |
数量关系很简单:4 个 Pod 来自 Calico 清单(3 + 1),2 个 CoreDNS 是集群自带的 DNS 组件。两者职责不同,也不存在「CoreDNS 必须等 Calico 控制器启动后才能启动」的硬依赖。
二、calico-node:每个节点一个网络执行者
集群是 1 个 Master + 2 个 Worker,因此出现 3 个 calico-node。原因是 Calico 以 DaemonSet 部署,默认在每个节点上运行一个实例(控制面节点通过 toleration 容忍污点)。
![[03_云原生/云原生技术栈/Kubernetes/image/d21847a62c797f486e0525ba8614cbdd_MD5.jpg]]
Pod 到 Pod 的流量路径示意(来源:community.ops.io)
假设集群中有以下 Pod:
| 节点 | Pod | 示例 Pod IP |
|---|---|---|
| Master | Pod A | 10.244.1.10 |
| Worker 1 | Pod B | 10.244.2.10 |
| Worker 2 | Pod C | 10.244.3.10 |
表中 IP 仅为示例,不代表实际集群地址。Calico 从 IP Pool(如
10.244.0.0/16)按节点切块分配,所以同一节点的 Pod 往往共享同一个 /24 前缀。
当 Pod A 访问 Pod C 时,正是 Calico 负责让数据包从源节点到达目标节点。calico-node 的主要工作包括:
- 配置 Pod 网络:作为 CNI 插件,在 Pod 创建/删除时创建网络接口、分配 IP、写入路由。
- 建立转发路径:按所选数据平面(Linux 路由、BGP、VXLAN、IP-in-IP 等)转发跨节点流量。
- 执行网络策略:把 NetworkPolicy 翻译成主机数据平面的访问控制规则。
- 维护节点网络状态:注册节点信息,参与 Calico 网络状态同步。
Calico 不等于 BGP。BGP 只是可选模式之一,具体使用哪种数据平面取决于安装配置。
与 kube-proxy 的分工
| 对比项 | kube-proxy | calico-node |
|---|---|---|
| 关注对象 | Service → Pod 的转发规则 | Pod ↔ Pod 的连通性与访问策略 |
| 典型实现 | iptables / IPVS / nftables | 路由、BGP、VXLAN、IP-in-IP、eBPF |
| 两者关系 | 互补:Service 规则最终仍要把包送进 Pod 网络 | 提供 Pod 网络本身 |
二者不是替代关系,缺一不可。
三、calico-kube-controllers:为什么只需要一个
该组件是 Calico 的控制器,通常以 Deployment 运行,默认 1 个副本。
它不参与数据面转发,也不负责给节点配置网卡,而是通过 Kubernetes API 监听资源变化并对账。常见的控制器职责包括:
- 节点控制器:同步 Kubernetes Node 与 Calico 节点资源。
- 工作负载端点控制器:协调 Pod 与 Calico 网络端点信息。
- 网络策略控制器:按启用的类型维护部分策略相关数据。
- IPAM 控制器:在支持并启用时,协助处理 IP 地址管理状态。
具体启用哪些控制器取决于 Calico 版本与安装配置,并非每个版本都包含上述全部功能。
为什么不需要每节点一个?
因为它做的是集群级的集中协调:读取 API 中的资源状态,再回写 Calico 需要的数据,不直接操作本机网络设备。一个 Deployment 即可完成;需要高可用时可以增加副本(通过选主机制工作)。
一句话区分:
calico-node是「干活的」,calico-kube-controllers是「对账的」。
四、CoreDNS:解决「名字 → 地址」
CoreDNS 只负责域名解析,不建立 Pod 之间的网络通道。
假设业务 Pod 要访问后端服务:
curl http://order-service.default.svc.cluster.local:8080
这个域名各部分的含义:
| 片段 | 含义 |
|---|---|
order-service | Service 名称 |
default | 所在 Namespace |
svc | 资源类型 |
cluster.local | 集群域名后缀 |
业务 Pod 需要先通过 DNS 拿到 Service 的 ClusterIP,再经由 Service 的转发机制访问后端 Pod。简化后的路径是:
业务 Pod
│ ① 查询 order-service.default.svc.cluster.local
▼
CoreDNS(位于 kube-dns Service 之后)
│ ② 返回 Service 的 ClusterIP
▼
Service 转发规则(kube-proxy 或对应数据平面)
│ ③ 转发到某个后端 Pod
▼
后端 Pod
实际访问中还会涉及 DNS 缓存、EndpointSlice、不同 Service 类型等因素,但主干就是上面这条链路。
为什么需要两个 CoreDNS
因为它以 Deployment 运行,副本数通常设为 2:
- 提高可用性:一个副本故障时,另一个仍可提供解析服务。
- 分担查询压力:多个副本共同处理 DNS 请求。
- 支持滚动更新:更新期间始终有副本在线。
两个副本是集群级 DNS 的两个实例,并不对应两个 Worker,也不要求每节点一个。它们通常通过反亲和配置尽量分散到不同节点,但最终是否分散取决于调度结果。
CoreDNS 通过名为 kube-dns 的 ClusterIP Service 对外提供服务——即使实际 DNS 实现是 CoreDNS,Service 名称仍沿用 kube-dns。
没有 CoreDNS 就不能通信吗
不是。
- 如果 Pod 已经知道目标 IP,且网络与访问规则正常,仍然可以通信。
- 但应用通常使用 Service 名称而非固定 IP。没有可用的集群 DNS,
mysql.default.svc.cluster.local这类域名会解析失败,表现为「网络是通的,服务却连不上」。
因此 CoreDNS 是服务发现的关键,但它不是 Pod 网络本身。
五、Calico 部署后,CoreDNS 为什么还 Pending
这里要区分两个问题。
1. 为什么新增了 4 个 Pod
Calico 清单会创建网络插件所需的两类资源:
- DaemonSet:在每个符合条件的节点部署,产生 3 个
calico-node。 - Deployment:产生 1 个
calico-kube-controllers。
2. 为什么原来的 2 个 CoreDNS 没有自动 Running
部署 Calico 并不等于网络立刻可用。常见因果链是:
节点缺少 CNI 配置
→ 节点 NotReady,带 node.kubernetes.io/not-ready 污点
→ CoreDNS 没有可调度节点,一直 Pending
→ calico-node 就绪、节点转为 Ready、污点移除
→ CoreDNS 才会被调度并启动
若 Calico 已部署但 CoreDNS 仍 Pending,可按下面的顺序定位。
排查命令
# 1. 节点是否 Ready,节点 IP 与角色
kubectl get nodes -o wide
# 2. 网络组件是否全部就绪
kubectl get pod -n kube-system -o wide
kubectl get ds -n kube-system
# 3. 查看 Pending Pod 的调度事件
kubectl describe pod -n kube-system coredns-66f779496c-fb7qd
# 4. 查看 calico-node 的初始化容器状态
kubectl get pod -n kube-system calico-node-8cmfp \
-o jsonpath='{range .status.initContainerStatuses[*]}{.name}{" : "}{.state}{"\n"}{end}'
# 5. 根据初始化容器名称查看日志
kubectl logs -n kube-system calico-node-8cmfp -c <初始化容器名称>
Pod 名称请替换为实际值,可用
kubectl get pod -n kube-system获取。
第 4 条命令只展示初始化容器状态,不直接给出失败原因;拿到容器名后再用第 5 条查看日志。
按现象分流
| 现象 | 优先排查 |
|---|---|
Pod Pending,事件为 FailedScheduling | 节点是否 Ready、污点与容忍、资源请求、亲和性 |
Init:ImagePullBackOff | 镜像地址、网络代理、私有仓库凭据 |
Init:CrashLoopBackOff | 初始化容器日志:CNI 配置、IP Pool、API Server 连通性 |
calico-node Running 但节点 NotReady | /etc/cni/net.d 下的 CNI 配置、kubelet 日志 |
| 节点 Ready 但 CoreDNS 仍 Pending | CoreDNS 的资源请求、污点容忍、反亲和约束 |
六、一页总结
| 组件 | 一句话理解 | 关键点 |
|---|---|---|
calico-node | 每台机器上的网络工作者 | 配置和维护 Pod 网络,执行网络策略 |
calico-kube-controllers | 集群级状态协调器 | 监听资源变化,维护 Calico 侧状态 |
CoreDNS | 集群内部的 DNS 服务 | 把 Service 域名解析成 ClusterIP |
kube-proxy | Service 流量转发规则的维护者 | 具体实现受集群配置影响 |
整体认知:Calico 让网络「通起来」,CoreDNS 让服务「找得到」,kube-proxy 或对应数据平面让 Service「转得过去」。它们不是六个必须同时就绪的通信进程,而是网络、服务发现与转发机制中的不同部分。
本文深入解析Kubernetes 1.28中Calico网络插件与CoreDNS服务发现组件的协同机制。Calico负责Pod网络连通性,包括IP分配、跨节点路由及NetworkPolicy执行;CoreDNS则专注集群内域名解析,支撑Service服务发现。二者职责分离:Calico是CNI数据面执行者(calico-node DaemonSet)与集群状态协调者(calico-kube-controllers Deployment),CoreDNS为高可用DNS服务实例。部署后CoreDNS Pending通常源于网络未就绪或调度依赖,需结合kubectl排查初始化容器与日志。

2511

被折叠的 条评论
为什么被折叠?



