Chapter 02

集群架构:Control Plane 与 Node

深入理解 K8s 的大脑(控制平面)与身体(工作节点),以及各组件的职责分工与通信方式。

整体架构全景

一个 Kubernetes 集群由两类节点组成:负责决策的 Control Plane(控制平面) 和负责运行容器的 Worker Node(工作节点)

Kubernetes 集群架构

┌──────────────────────────────────────────────────────────────┐
                    Control Plane (Master)                    
  ┌─────────────────┐  ┌──────────┐  ┌──────────────────┐  
   kube-apiserver      etcd      kube-scheduler    
   集群大门,REST      状态存储     Pod 调度决策      
  └────────┬────────┘  └────┬─────┘  └────────┬─────────┘  
                                                          
  ┌────────▼────────────────▼───────────────▼──────────────┐  
              kube-controller-manager                         
     Deployment/ReplicaSet/Node/Job/... Controller            
  └────────────────────────────────────────────────────────┘  
└──────────────────────────┬───────────────────────────────────┘
                           │ HTTPS (kubeconfig)
          ┌──────────────────┴──────────────────┐
                                             
┌─────────────────┐                 ┌─────────────────┐
  Worker Node 1                     Worker Node 2  
  kubelet                           kubelet        
  kube-proxy                        kube-proxy     
  容器运行时                         容器运行时      
  ┌───┐ ┌───┐                       ┌───┐ ┌───┐    
  │Pod│ │Pod│                       │Pod│ │Pod│    
  └───┘ └───┘                       └───┘ └───┘    
└─────────────────┘                 └─────────────────┘

Control Plane 组件详解

kube-apiserver — 集群的统一入口

API Server 是集群中唯一能直接读写 etcd 的组件,是所有操作的唯一入口。所有组件(包括 kubectl、kubelet、各 Controller)都通过 API Server 通信,而不是互相直连。这保证了一致性与安全性。

REST API
API Server 暴露标准 RESTful HTTP API。每种资源对应一组 URL:GET /api/v1/pods(列出),POST /api/v1/namespaces/{ns}/pods(创建),PATCH 更新,DELETE 删除。
认证 / 鉴权
请求经过:① 认证(Authentication,你是谁)→ ② 鉴权(Authorization,RBAC 你能做什么)→ ③ 准入控制(Admission,请求内容是否合法)。
Watch 机制
客户端可以对资源建立长连接 Watch,API Server 将增量变更事件推送给客户端,避免轮询。Controller 正是通过 Watch 响应资源变化的。

etcd — 集群的状态存储

etcd 是一个分布式键值存储数据库(基于 Raft 共识算法),Kubernetes 将所有集群状态(Pod、Service、ConfigMap 等所有对象)都持久化到 etcd 中。

etcd 是最重要的备份目标

etcd 中存储了整个集群的状态。一旦 etcd 数据丢失,集群中的所有对象信息都将消失(但已运行的容器不受影响)。生产环境必须定期备份 etcd,并采用至少 3 节点的 etcd 集群保障高可用。

# 查看 etcd 中存储的 Pod 信息(需要 etcdctl 工具)
etcdctl get --prefix /registry/pods/default --keys-only

# 创建 etcd 快照备份
etcdctl snapshot save backup.db

# 验证快照
etcdctl snapshot status backup.db

kube-scheduler — 调度决策者

Scheduler 负责将新创建的 Pod 分配到合适的节点上。它不负责运行 Pod,只负责做决策——将 Pod 的 spec.nodeName 字段写入 API Server,然后由目标节点的 kubelet 负责拉起容器。

调度过程分两个阶段:

  1. 过滤(Filtering):筛选出满足 Pod 资源请求的节点(CPU/内存足够、标签匹配、污点容忍等)
  2. 打分(Scoring):对过滤后的节点打分,选择分数最高的节点(考虑资源均衡、镜像已缓存等因素)

kube-controller-manager — 控制器大集合

Controller Manager 是一个进程,内部运行着数十个 Controller(每个都是一个 goroutine),包括:

Controller职责
Deployment Controller管理 ReplicaSet,实现滚动更新/回滚
ReplicaSet Controller保证指定数量的 Pod 副本运行
Node Controller监控节点健康,标记 NotReady,驱逐 Pod
Job Controller管理一次性任务 Pod 的完成状态
Endpoints Controller维护 Service 与 Pod 的 IP 映射关系
Namespace Controller清理被删除 Namespace 下的所有资源
ServiceAccount Controller为每个 Namespace 创建默认 ServiceAccount

Worker Node 组件详解

kubelet — Node 的代理

kubelet 运行在每个 Worker Node 上,是 Node 与 Control Plane 的桥梁。它从 API Server 拿到分配给本节点的 Pod 定义,调用容器运行时(如 containerd)拉起容器,并持续上报 Pod 和 Node 的状态。

kubelet 不由 K8s 管理

kubelet 是唯一不以容器形式运行的核心组件,它作为系统服务(systemd)运行在 Node 上。这是故意的设计——如果 kubelet 自己是 Pod,当容器运行时出问题时 kubelet 也无法工作。

kube-proxy — 网络代理

kube-proxy 负责实现 Service 的网络规则。当你访问一个 Service 的 ClusterIP:Port 时,kube-proxy 在每个节点上配置的 iptables/ipvs 规则会将流量转发到对应的 Pod。

容器运行时(Container Runtime)

实际创建和运行容器的组件。K8s 通过 CRI(Container Runtime Interface) 标准接口与运行时交互,支持:

containerd
目前最主流的容器运行时,从 Docker 中剥离出来,是 K8s 1.24+ 默认推荐的运行时(Docker shim 已移除)。轻量、高性能。
CRI-O
专为 K8s 设计的轻量级运行时,Red Hat 主导,OpenShift 默认使用。
Docker
K8s 1.24 后移除了对 Docker 的直接支持(dockershim)。但 Docker 构建的镜像完全兼容 K8s,因为底层镜像格式是标准的 OCI 格式。
CRI
Container Runtime Interface。K8s 定义的容器运行时标准 gRPC 接口,任何实现了 CRI 的运行时都可以接入 K8s。

kubectl 安装与配置

安装 kubectl

# macOS (Homebrew)
brew install kubectl

# Linux
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# 验证安装
kubectl version --client

kubeconfig 配置文件

kubectl 通过 ~/.kube/config 文件知道要连接哪个集群、使用哪个身份。

apiVersion: v1
kind: Config
clusters:              # 集群列表
- cluster:
    server: https://192.168.1.100:6443    # API Server 地址
    certificate-authority-data: LS0t...   # CA 证书 (base64)
  name: my-cluster
users:                 # 用户列表
- user:
    client-certificate-data: LS0t...     # 客户端证书
    client-key-data: LS0t...             # 客户端私钥
  name: admin
contexts:             # 上下文 = 集群 + 用户 + namespace 的组合
- context:
    cluster: my-cluster
    user: admin
    namespace: default
  name: my-context
current-context: my-context  # 当前使用的上下文
# 查看所有上下文
kubectl config get-contexts

# 切换上下文(切换集群)
kubectl config use-context my-context

# 查看当前上下文
kubectl config current-context

# 设置默认 namespace
kubectl config set-context --current --namespace=production

常用 kubectl 命令速查

# ── 查看资源 ──
kubectl get nodes                          # 查看所有节点
kubectl get pods -A                       # 查看所有 namespace 的 Pod
kubectl get pods -o wide                  # 显示 Pod IP 和所在节点
kubectl describe node worker-1            # 节点详细信息(CPU/内存/事件)
kubectl describe pod my-pod               # Pod 详细信息(调度、事件)

# ── 日志与调试 ──
kubectl logs my-pod                        # 查看 Pod 日志
kubectl logs -f my-pod                    # 实时跟踪日志
kubectl exec -it my-pod -- /bin/sh        # 进入 Pod Shell
kubectl port-forward pod/my-pod 8080:80  # 端口转发到本地

# ── 节点管理 ──
kubectl cordon worker-1                   # 标记节点不可调度
kubectl drain worker-1 --ignore-daemonsets  # 驱逐节点 Pod(维护前)
kubectl uncordon worker-1                 # 恢复节点可调度
本地学习集群推荐

学习时推荐使用 minikube(单节点,支持多种驱动)或 kind(Kubernetes in Docker,适合 CI/多节点测试)。生产环境推荐 kubeadm 自建或使用云厂商托管服务(EKS/GKE/AKS)。

# 使用 kind 创建多节点集群
# kind-config.yaml:
# kind: Cluster
# apiVersion: kind.x-k8s.io/v1alpha4
# nodes:
#   - role: control-plane
#   - role: worker
#   - role: worker
kind create cluster --config kind-config.yaml --name my-cluster