K8s架构详解:控制平面与工作节点全解析
文章目录
- 1. K8s 架构总览
- 2. 控制平面组件详解
- 3. 工作节点组件详解
- 4. 组件交互全流程(以创建 Pod 为例)
- 5. 端口速查表
1. K8s 架构总览
1.1 两大平面的协作关系
Kubernetes 采用「声明式 API + 控制器循环」的核心设计哲学,整体分为两大平面:
- 控制平面(大脑):负责决策和存储,不运行业务容器。
- 工作节点(手脚):负责执行,真正运行容器。
关键设计原则:
- 声明式 API:用户只描述“期望状态”(如 3 个副本),不描述“怎么做”。
- 控制器循环:控制器不断 Watch 资源变化,将“实际状态”调和到“期望状态”。
- 唯一入口:所有组件只和
kube-apiserver通信,apiserver是唯一操作etcd的组件。 - 水平扩展:
apiserver、scheduler、controller-manager均支持多实例 + 选主。
1.2 实操:查看集群整体状态
# 查看集群节点状态
kubectl get nodes -o wide
# 查看控制平面组件(静态 Pod)
kubectl get pods -n kube-system | grep -E "etcd|kube-apiserver|kube-controller|kube-scheduler"
# 查看工作节点组件(DaemonSet 与 Deployment)
kubectl get pods -n kube-system | grep -E "kube-proxy|calico|coredns"
# 查看集群信息
kubectl cluster-info
# 一键检查所有组件健康状态
kubectl get --raw=/healthz?verbose
2. 控制平面组件详解
2.1 kube-apiserver —— 集群的唯一入口
2.1.1 作用
- 大白话:集群的“前台接待”,负责认证、授权、准入控制,所有操作必须经过它。
- 专家视角:提供 REST API 入口;唯一操作 etcd 的组件;支持 Watch 机制;无状态可水平扩展。
2.1.2 配置文件
# 静态 Pod 清单(kubeadm 部署)
cat /etc/kubernetes/manifests/kube-apiserver.yaml
# 管理员 kubeconfig
cat /etc/kubernetes/admin.conf
# v1.24+ 超级管理员配置
cat /etc/kubernetes/super-admin.conf
2.1.3 关键启动参数
| 参数 | 说明 | 典型值 |
|---|---|---|
--etcd-servers | etcd 地址列表 | https://127.0.0.1:2379 |
--secure-port | 安全端口 | 6443 |
--service-cluster-ip-range | Service ClusterIP 网段 | 10.96.0.0/12 |
--authorization-mode | 授权模式 | Node,RBAC |
--enable-admission-plugins | 准入插件 | NodeRestriction |
2.1.4 端口
| 端口 | 协议 | 作用 |
|---|---|---|
| 6443 | HTTPS | 安全端口,所有客户端访问入口 |
| 8080 | HTTP | 不安全端口(v1.20+ 默认禁用) |
2.1.5 实操验证
实操1:查看进程和监听端口
ps -ef | grep kube-apiserver | grep -v grep
ss -tlnp | grep 6443
实操2:健康检查
curl -k https://127.0.0.1:6443/healthz
curl -k https://127.0.0.1:6443/healthz?verbose
实操3:直接调用 API(需证书)
curl -k --cert /etc/kubernetes/pki/apiserver-kubelet-client.crt \
--key /etc/kubernetes/pki/apiserver-kubelet-client.key \
https://127.0.0.1:6443/api/v1/nodes
实操4:查看 API 版本和资源
kubectl api-versions | head -20
kubectl api-resources | head -20
实操5:查看 apiserver 日志
kubectl logs -n kube-system kube-apiserver-$(hostname) --tail=50
# 或使用 crictl
crictl logs $(crictl ps | grep kube-apiserver | awk '{print $1}') | tail -50
实操6:测试认证授权流程
# 无权限用户(预期 403)
kubectl auth can-i create pods --as=system:serviceaccount:default:default
# 管理员(预期 yes)
kubectl auth can-i create pods
2.1.6 日常巡检指令
# 检查 apiserver 就绪探针
kubectl get --raw=/readyz?verbose
# 检查 API 优先级和公平性(APF)
kubectl get flowschemas -A
2.1.7 常见故障排查
| 现象 | 可能原因 | 排查命令 |
|---|---|---|
| kubectl 超时 | apiserver 挂了 / 端口不通 | systemctl status kubelet、ss -tlnp | grep 6443 |
| x509 证书错误 | 证书过期 | openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates |
| 403 Forbidden | RBAC 权限不足 | kubectl auth can-i <verb> <resource> |
2.2 etcd —— 集群的“数据库”
2.2.1 作用
- 大白话:K8s 的数据库,存储所有资源对象(Pod、Service、ConfigMap 等)。
- 专家视角:分布式 KV 存储,基于 Raft 共识算法(CP 系统);仅 apiserver 可读写;需定期备份。
2.2.2 配置文件与目录
cat /etc/kubernetes/manifests/etcd.yaml
ls -la /var/lib/etcd/ # 数据目录(重中之重)
ls -la /etc/kubernetes/pki/etcd/
2.2.3 关键参数
| 参数 | 说明 |
|---|---|
--listen-client-urls | 客户端监听地址 |
--data-dir | 数据存储目录 |
--trusted-ca-file | 客户端 CA 证书 |
2.2.4 端口
| 端口 | 协议 | 作用 |
|---|---|---|
| 2379 | HTTPS | 客户端通信(apiserver 连接) |
| 2380 | HTTPS | 节点间 Raft 共识通信 |
2.2.5 实操验证
实操1:设置 etcdctl 环境变量
export ETCDCTL_API=3
export ETCDCTL_ENDPOINTS=https://127.0.0.1:2379
export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt
export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/server.crt
export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/server.key
实操2:查看集群健康状态
etcdctl endpoint health
etcdctl endpoint status --write-out=table
实操3:列出所有 key
etcdctl get /registry/pods --prefix --keys-only | head -20
etcdctl get /registry/services --prefix --keys-only | head -20
实操4:查看具体对象
etcdctl get /registry/minions/k8s-node01 | python3 -m json.tool | head -30
实操5:etcd 备份(生产必做)
etcdctl snapshot save /root/etcd-backup-$(date +%Y%m%d).db
etcdctl snapshot status /root/etcd-backup-$(date +%Y%m%d).db --write-out=table
实操6:查看 etcd 日志
kubectl logs -n kube-system etcd-$(hostname) --tail=50 | grep -E "raft|election|error"
实操7:监控性能指标
curl -k --cert /etc/kubernetes/pki/etcd/server.crt \
--key /etc/kubernetes/pki/etcd/server.key \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
https://127.0.0.1:2379/metrics | grep -E "etcd_server_has_leader|etcd_mvcc_db_total_size"
2.2.6 常见故障排查
| 现象 | 排查命令 |
|---|---|
| apiserver 启动失败 | etcdctl endpoint health |
| 频繁选主 | etcdctl endpoint status、iostat -x 1 |
| DB 空间告警(默认 2GB 限额) | etcdctl endpoint status 看 DB SIZE |
2.2.7 生产最佳实践
① 3/5 节点奇数部署;
② 必须使用 SSD 磁盘;
③ 每日定时备份;
④ 监控 DB 大小和选主频率。
2.3 kube-scheduler —— “调度员”
2.3.1 作用
- 大白话:给新 Pod 找“家”(合适的 Node)。
- 专家视角:两阶段调度(过滤 → 打分),可插拔框架,多实例选主。
2.3.2 配置文件
cat /etc/kubernetes/manifests/kube-scheduler.yaml
2.3.3 关键参数
| 参数 | 说明 |
|---|---|
--leader-elect | 多实例选主(true) |
--secure-port | 安全端口(10259) |
2.3.4 端口
| 端口 | 作用 |
|---|---|
| 10259 | HTTPS 安全端口(健康检查、Metrics) |
2.3.5 实操验证
实操1-2:查看进程与健康检查
ps -ef | grep kube-scheduler | grep -v grep
ss -tlnp | grep 10259
curl -k https://127.0.0.1:10259/healthz
实操3:查看调度事件
kubectl get events --sort-by='.lastTimestamp' | grep -i schedule | tail -20
kubectl describe pod <pod-name> | grep -A5 -i "scheduled\|events"
实操4:查看调度器 Leader
kubectl get leases -n kube-system kube-scheduler -o yaml | grep holderIdentity
实操5:模拟调度失败
cat > /tmp/test-schedule.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: test-schedule-fail
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "100"
memory: "100Gi"
EOF
kubectl apply -f /tmp/test-schedule.yaml
kubectl describe pod test-schedule-fail | grep -A10 Events
# 清理
kubectl delete pod test-schedule-fail
实操6-7:查看日志与节点资源
kubectl logs -n kube-system kube-scheduler-$(hostname) --tail=50
kubectl describe nodes | grep -A5 -E "Name:|Allocated resources"
2.3.6 常见故障排查
| 现象 | 排查命令 |
|---|---|
| Pod 一直 Pending | kubectl describe pod <pod> 看 Events |
| Scheduler 不工作 | kubectl get leases -n kube-system kube-scheduler |
2.4 kube-controller-manager —— “控制器大总管”
2.4.1 作用
- 大白话:管理数十个控制器(Deployment、ReplicaSet、Node 等),不断调谐实际状态至期望状态。
- 专家视角:核心执行者,通过 Watch 机制工作,多实例选主。
2.4.2-2.4.4 配置与端口
cat /etc/kubernetes/manifests/kube-controller-manager.yaml
# 端口:10257 (HTTPS)
2.4.5 实操验证
实操1-3:查看进程、健康与日志
ps -ef | grep kube-controller-manager | grep -v grep
curl -k https://127.0.0.1:10257/healthz
kubectl logs -n kube-system kube-controller-manager-$(hostname) --tail=50
实操4:验证 Deployment 控制器
kubectl create deployment test-ctrl --image=nginx --replicas=3
kubectl delete pod -l app=test-ctrl
kubectl get pods -l app=test-ctrl -w # 观察自动重建
kubectl delete deployment test-ctrl
实操5:验证 Endpoint 控制器
kubectl expose deployment test-ctrl --port=80
kubectl get endpoints test-ctrl # 自动生成
kubectl delete deployment test-ctrl
kubectl get endpoints test-ctrl # 自动清空
kubectl delete svc test-ctrl
实操6:验证 Namespace 控制器
kubectl create ns test-ns
kubectl delete ns test-ns
kubectl get ns test-ns # 观察 Terminating 直至消失
实操7:查看 Leader 选举
kubectl get leases -n kube-system kube-controller-manager -o yaml | grep holderIdentity
2.4.6 常见故障排查
| 现象 | 排查命令 |
|---|---|
| Pod 删除后不重建 | kubectl logs -n kube-system kube-controller-manager-xxx |
| Endpoints 不更新 | kubectl describe svc、检查 selector 匹配 |
2.5 cloud-controller-manager(可选)
自建集群通常不部署。
kubectl get pods -n kube-system | grep cloud-controller # 预期无输出
3. 工作节点组件详解
3.1 kubelet —— Node 上的“管家”
3.1.1 作用
- 大白话:Node 的“管家”,从 apiserver 打听分配到本节点的 Pod,调用容器运行时启动/停止容器,上报状态。
- 专家视角:唯一不运行为 Pod 的核心组件(systemd 服务);管理生命周期、健康检查、资源限制。
3.1.2 配置文件
cat /var/lib/kubelet/config.yaml # 主配置
cat /etc/kubernetes/kubelet.conf # kubeconfig
ls -la /var/lib/kubelet/pki/ # 证书目录
3.1.3 关键配置(config.yaml)
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
cgroupDriver: systemd # ★ 必须与 containerd 一致
containerRuntimeEndpoint: unix:///run/containerd/containerd.sock
evictionHard:
memory.available: "100Mi"
3.1.4 端口
| 端口 | 作用 |
|---|---|
| 10250 | HTTPS API(Node 状态、exec/log/metrics) |
3.1.5 实操验证
实操1-3:服务状态、端口与健康
systemctl status kubelet
ss -tlnp | grep 10250
curl -k https://127.0.0.1:10250/healthz
实操4-5:查看配置与节点资源
kubectl get --raw /api/v1/nodes/$(hostname)/proxy/configz | python3 -m json.tool
kubectl describe node $(hostname) | grep -A10 "Allocated resources"
实操6:查看 kubelet 日志(最重要)
journalctl -u kubelet -f --since "10 minutes ago"
journalctl -u kubelet --no-pager | tail -100 | grep -E "Failed|Error|PLEG"
实操7-8:查看本节点 Pod 与状态详情
kubectl get pods --all-namespaces --field-selector spec.nodeName=$(hostname) -o wide
kubectl describe node $(hostname)
实操9:验证 cgroupDriver 一致性(关键坑)
grep cgroupDriver /var/lib/kubelet/config.yaml
grep SystemdCgroup /etc/containerd/config.toml
# 两者必须一致(均为 systemd 或均为 cgroupfs)!
3.1.6 常见故障排查
| 现象 | 排查命令 |
|---|---|
| Node NotReady | systemctl status kubelet、journalctl -u kubelet |
| 启动失败 cgroup 错误 | 对比 config.yaml 和 config.toml 的 cgroup 配置 |
| Pod 一直 ContainerCreating | journalctl -u kubelet、crictl ps |
3.2 kube-proxy —— “网络转发员”
3.2.1 作用
- 大白话:实现 Service 的 ClusterIP/NodePort 访问,转发流量到后端 Pod。
- 专家视角:监听 Service/Endpoint,配置 iptables 或 IPVS 规则;以 DaemonSet 运行。
3.2.2-3.2.3 配置
kubectl -n kube-system get cm kube-proxy -o yaml
# 关键字段:mode: "iptables" 或 "ipvs"
3.2.4 端口
| 端口 | 作用 |
|---|---|
| 10256 | 健康检查 HTTP 端口 |
3.2.5 实操验证
实操1-3:状态与模式查看
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o wide
curl http://127.0.0.1:10256/healthz
kubectl -n kube-system get cm kube-proxy -o jsonpath='{.data.config}' | grep mode
实操4:查看 iptables 规则
iptables -t nat -nL KUBE-SERVICES | head -30
iptables -t nat -nL KUBE-SERVICES | grep 10.96.0.10 # 查看 CoreDNS 规则
iptables -t nat -nL KUBE-NODEPORTS
实操5:查看 IPVS 规则
ipvsadm -Ln
实操6-7:日志与负载均衡验证
kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=50
# 创建测试 Service 验证负载均衡
kubectl create deployment test-proxy --image=nginx --replicas=3
kubectl expose deployment test-proxy --port=80
CLUSTER_IP=$(kubectl get svc test-proxy -o jsonpath='{.spec.clusterIP}')
for i in $(seq 1 10); do curl -s http://$CLUSTER_IP | grep -o "server.*" ; done | sort | uniq -c
# 清理
kubectl delete deploy test-proxy && kubectl delete svc test-proxy
实操8:切换到 IPVS 模式(进阶)
# 安装 ipset 和 ipvsadm,加载内核模块
yum install -y ipset ipvsadm
modprobe -- ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack
# 修改 ConfigMap
kubectl edit configmap kube-proxy -n kube-system # mode: "" -> mode: "ipvs"
# 重启 Pod
kubectl delete pod -n kube-system -l k8s-app=kube-proxy
# 验证
ipvsadm -Ln | head -20
3.2.6 常见故障排查
| 现象 | 排查命令 |
|---|---|
| Service 访问不通 | kubectl get endpoints、iptables -t nat -L KUBE-SERVICES |
| IPVS 不生效 | lsmod | grep ip_vs、ipvsadm -Ln |
3.3 容器运行时 containerd
3.3.1 作用
- 大白话:真正“跑容器”的软件。v1.24 起取代 Docker。
- 专家视角:实现 CRI 标准;通过 Unix Socket 通信;负责镜像拉取与容器生命周期。
3.3.2-3.3.3 配置
cat /etc/containerd/config.toml
# 关键:SystemdCgroup = true # 必须与 kubelet 一致
3.3.4 通信方式
无对外端口,使用 Unix Socket:/run/containerd/containerd.sock
3.3.5 实操验证
实操1:服务状态
systemctl status containerd
实操2-3:查看容器与镜像(crictl)
crictl ps -a # 所有容器
crictl pods # Pod 沙箱
crictl images | grep nginx
实操4:ctr 命令(必须加 -n k8s.io)
ctr -n k8s.io images ls | head -20
ctr -n k8s.io containers ls
实操5:导入离线镜像
ctr -n k8s.io images import /root/centos-httpd-v1.tar
实操6:查看日志
journalctl -u containerd --no-pager | tail -50
实操7:验证 cgroup 驱动一致
grep SystemdCgroup /etc/containerd/config.toml
grep cgroupDriver /var/lib/kubelet/config.yaml
实操8:清理未使用镜像
crictl rmi --prune
3.3.6 常见故障排查与重要坑
| 现象 | 排查命令 |
|---|---|
| Pod 一直 ContainerCreating | crictl pull <镜像>、journalctl -u containerd |
| crictl 看不到镜像 | 镜像在 Docker 里,需 docker save → ctr import (需加 -n k8s.io) |
| cgroup 错误 | 对比两个配置文件的驱动设置 |
3.4 CoreDNS —— 集群 DNS
3.4.1 作用
- 大白话:集群内 DNS 服务器,解析 Service 域名(如
my-svc.default.svc.cluster.local)。
3.4.2 配置文件
kubectl -n kube-system get cm coredns -o yaml
3.4.3 实操验证
实操1:查看状态
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
kubectl get svc -n kube-system kube-dns # ClusterIP 通常为 10.96.0.10
实操2:测试 DNS 解析
kubectl run dns-test --image=busybox:1.28 --rm -it --command -- nslookup kubernetes.default
实操3-5:日志、Corefile 与 Pod 内配置
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50
kubectl -n kube-system get cm coredns -o jsonpath='{.data.Corefile}'
kubectl run dns-test --image=busybox:1.28 --rm -it --command -- cat /etc/resolv.conf
3.4.4 常见故障排查
| 现象 | 排查命令 |
|---|---|
| 域名解析失败 | kubectl get pods -n kube-system -l k8s-app=kube-dns |
| 解析慢 | 检查 CoreDNS 副本数及 ndots 配置 |
3.5 网络插件(CNI)—— Calico / Flannel
3.5.1 作用
实现 Pod 跨节点通信,分配 Pod IP,支持 NetworkPolicy(Calico)。
3.5.2 端口(以 Calico 为例)
| 端口 | 协议 | 作用 |
|---|---|---|
| 179 | TCP | BGP peer 通信 |
| 4789 | UDP | VXLAN 数据封装 |
| IP 协议 4 | - | IPIP 模式封装(非 UDP 端口) |
3.5.3 实操验证
实操1:查看组件
kubectl get pods -n kube-system | grep calico # calico-node (DS), calico-kube-controllers (Deploy)
实操2:查看 Pod CIDR 分配
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
实操3:查看 BGP 状态
kubectl exec -n kube-system calico-node-xxx -- calicoctl node status
实操4-5:查看 IP 分布与跨节点通信
kubectl get pods --all-namespaces -o wide | grep -v "kube-system" | head -20
# 在 Pod 内 ping 另一个节点的 Pod IP
kubectl exec -it <pod-name> -- ping -c 3 <other-pod-ip>
实操6:查看日志
kubectl logs -n kube-system -l k8s-app=calico-node --tail=50
3.5.4 常见故障排查
| 现象 | 排查命令 |
|---|---|
| 跨节点 Pod 不通 | calicoctl node status、检查防火墙 |
| Pod 无 IP | kubectl describe pod、查看 CNI 日志 |
4. 组件交互全流程(以创建 Pod 为例)
4.1 完整流程拆解(8步流程)
- kubectl → apiserver:认证、授权、准入控制。
- apiserver → etcd:写入 Pod 对象(nodeName 为空)。
- scheduler:Watch 到未调度 Pod,过滤+打分,选定 Node,调用 binding。
- apiserver → etcd:更新 Pod 的 nodeName。
- kubelet(Node 上):Watch 到分配给自己的 Pod,调用 containerd 拉镜像、启动容器(Pause + 业务容器)。
- kubelet → apiserver:上报 Pod 状态(Running)。
- apiserver → etcd:更新 Pod status。
- Endpoint Controller + kube-proxy:若匹配 Service,更新 Endpoints 和 iptables/IPVS 规则。
4.2 分步详解与实操验证
第1步:kubectl 发送请求到 apiserver
kubectl run nginx-test --image=nginx --v=6 2>&1 | head -30 # 查看详细请求
kubectl config view --minify | grep user
kubectl delete pod nginx-test
第2步:apiserver 写入 etcd
# 设置 etcdctl 环境变量(参考 2.2.5 实操1)
etcdctl get /registry/pods/default/nginx-test | head -5
第3步:scheduler 调度
# 终端1:kubectl get events -w | grep -i schedule &
# 终端2:kubectl run nginx-test --image=nginx
kubectl describe pod nginx-test | grep -A3 Events
kubectl delete pod nginx-test
第4步:apiserver 更新 nodeName
kubectl get pod nginx-test -o jsonpath='{.spec.nodeName}'
第5步:kubelet 启动容器
journalctl -u kubelet -f | grep nginx-test &
kubectl run nginx-test --image=nginx
crictl ps | grep nginx-test
crictl pods | grep nginx-test
kubectl delete pod nginx-test
第6-7步:状态上报与更新
kubectl get pod nginx-test -w # 观察 Pending -> ContainerCreating -> Running
第8步:Endpoints 更新
kubectl create deployment nginx-svc --image=nginx --replicas=2
kubectl expose deployment nginx-svc --port=80
kubectl get endpoints nginx-svc
kubectl scale deployment nginx-svc --replicas=3
kubectl get endpoints nginx-svc -w
iptables -t nat -L KUBE-SERVICES | grep nginx-svc
kubectl delete deploy nginx-svc && kubectl delete svc nginx-svc
5. 端口速查表
| 组件 | 端口 | 协议 | 作用 |
|---|---|---|---|
| kube-apiserver | 6443 | HTTPS | 集群 API 入口 |
| etcd | 2379 | HTTPS | 客户端读写(apiserver 连接) |
| etcd | 2380 | HTTPS | Peer 共识通信 |
| kube-scheduler | 10259 | HTTPS | 安全端口/健康检查 |
| kube-controller-manager | 10257 | HTTPS | 安全端口/健康检查 |
| kubelet | 10250 | HTTPS | Node API(exec/log/metrics) |
| kube-proxy | 10256 | HTTP | 健康检查 |
| CoreDNS | 53 | UDP/TCP | DNS 解析 |
| Calico (BGP) | 179 | TCP | BGP peer |
| Calico (VXLAN) | 4789 | UDP | VXLAN 数据 |
| NodePort 范围 | 30000-32767 | TCP/UDP | Service NodePort |
记忆口诀:6443 大门,2379/2380 数据库,10257/10259 大脑,10250 管家,10256 网络员,53 DNS。
更多推荐
所有评论(0)