1.1 Architecture

1.1 Kubernetes architecture

核心架构图

1
2
3
4
5
6
7
8
9
10
11
graph TD
A[Master Node] -->|管理| B[Worker Nodes]
A -->|存储集群状态| C[ETCD Cluster]
A -->|调度决策| D[Kube-Scheduler]
A -->|控制循环| E[Controller Manager]
E -->|节点管理| F[Node-Controller]
E -->|副本管理| G[Replication-Controller]
A -->|API 入口| H[Kube-APIServer]
B -->|运行容器| I[Container Runtime]
B -->|代理网络| J[Kube-Proxy]
B -->|节点代理| K[Kubelet]

Master Node(控制平面)

负责集群的全局决策和调度,包含以下核心组件:

① Kube-APIServer
  • 作用:集群的“前台”,所有操作的唯一入口(RESTful API)。
  • 关键关系:
    • 接收用户或工具的请求(如 kubectl)。
    • 验证请求后,将状态写入 ETCD。
② ETCD Cluster
  • 作用:分布式键值数据库,存储集群所有状态(如 Pod、Node 配置)。
  • 关键关系:
    • 只有 APIServer 能直接读写 ETCD。
    • 高可用部署需 3 个以上节点。
③ Kube-Scheduler
  • 作用:决定 Pod 运行在哪个 Worker Node 上。
  • 调度策略:
    • 资源需求(CPU/Memory)。
    • 亲和性/反亲和性规则。
④ Controller Manager
  • 作用:通过控制循环确保集群实际状态与期望状态一致。
    • Node-Controller:
      • 监控 Node 状态(如宕机时标记为 NotReady)。
    • Replication-Controller:
      • 确保 Pod 副本数符合预期(已逐步被 Deployment 替代)。

Worker Nodes(工作节点)

运行容器化应用,包含以下组件:

① Kubelet
  • 作用:节点上的“代理”,负责:
    • 与 APIServer 通信(接收 Pod 定义)。
    • 管理容器生命周期(通过 Container Runtime)。
② Container Runtime
  • 常见实现:Docker、containerd、CRI-O。
  • 作用:实际运行容器的引擎(如拉取镜像、启动/停止容器)。
③ Kube-Proxy
  • 作用:维护节点网络规则(如 Service 的 IP 转发、负载均衡)。
  • 关键关系:
    • 实现 ClusterIP、NodePort 等网络功能。

核心概念关系总结

概念 功能简述 依赖/交互对象
Master 集群大脑,全局决策 所有 Worker Nodes
ETCD 集群状态存储 仅 APIServer 可读写
Kube-Scheduler 调度 Pod 到 Node 监听 APIServer 的未调度 Pod
Controller Manager 确保集群状态一致 通过 APIServer 监听 ETCD
Kubelet 执行 Pod 管理 接收 APIServer 指令
Kube-Proxy 处理 Service 网络流量 依赖节点网络配置

工作流程示例(以部署一个 Pod 为例)

  1. 用户提交请求:kubectl create -f pod.yaml → APIServer。
  2. 写入状态:APIServer 将 Pod 定义存入 ETCD。
  3. 调度决策:Scheduler 发现未调度的 Pod,选择合适 Node 并更新 ETCD。
  4. 执行创建:目标 Node 的 Kubelet 监听到变化,调用 Container Runtime 启动容器。
  5. 状态反馈:Kubelet 将 Pod 状态报告给 APIServer → 写入 ETCD。

常见疑问解答

  • Q:ETCD 和 APIServer 的关系?

    • APIServer 是 ETCD 的“门卫”,所有组件必须通过 APIServer 访问 ETCD。
  • Q:Controller Manager 和 Kubelet 的分工?

    • Controller Manager 确保集群级状态(如副本数),Kubelet 确保节点级状态(如容器运行)。
  • Q:为什么需要 Kube-Proxy?

    • Service 的虚拟 IP 需要被转换为实际 Pod IP,由 Kube-Proxy 维护 iptables/IPVS 规则, 使得pod之间得以通讯。

1.2&1.3 ETCD

1.2 ETCD for beginners

1. 下载与安装(Linux/macOS 示例)

1
2
3
4
5
6
7
8
9
# 1. 下载 ETCD 二进制包(国内镜像加速)
wget https://mirrors.aliyun.com/etcd/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz

# 2. 解压并进入目录
tar -xvf etcd-v3.5.0-linux-amd64.tar.gz
cd etcd-v3.5.0-linux-amd64

# 3. 启动 ETCD 服务(单机模式) 2379为通用默认端口
./etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://localhost:2379 &

关键参数:

  • --listen-client-urls:监听客户端连接的地址。
  • --advertise-client-urls:对外宣告的客户端访问地址。

2. 基础键值操作

1
2
3
4
5
6
7
8
9
# 4. 写入键值 [./etcdctl put key value]
./etcdctl put /message "Hello ETCD"

# 5. 读取键值 [./etcdctl get key]
./etcdctl get /message
# 输出:/message Hello ETCD

# 6. 查看所有命令帮助
./etcdctl --help

注意:ETCD v3 需显式指定 API 版本(默认 v3):

1
export ETCDCTL_API=3

1.3 ETCD in K8S

ETCD 是 Kubernetes 的“唯一真相源”,存储所有集群状态数据,包括:

  • 集群资源:Pods、Deployments、Services 等对象的定义和状态。
  • 配置信息:ConfigMaps、Secrets。
  • 节点状态:Node 注册信息、资源容量。
  • 调度决策:Scheduler 的 Predicates/Priorities 结果缓存。

与 Kubernetes 组件的关系

1
2
3
4
5
graph LR
A[Kube-APIServer] -->|唯一读写| B[ETCD]
C[Controller Manager] -->|监听资源变化| A
D[Scheduler] -->|获取未调度 Pod| A
E[Kubelet] -->|上报状态| A
  • APIServer 是唯一入口:所有组件必须通过 APIServer 访问 ETCD,确保数据一致性和安全审计。
  • 数据格式:以 Key-Value 形式存储,Key 按资源类型分层(如 /registry/pods/default/nginx)。

数据生效流程示例(以创建 Pod 为例)

  1. 用户请求:kubectl create -f pod.yaml 发送到 APIServer。
  2. 写入 ETCD:APIServer 验证请求后,将 Pod 定义写入 ETCD(如 /registry/pods/default/nginx)。
  3. 事件触发:
    • Controller Manager 监听 Pod 变化,确保副本数符合预期。
    • Scheduler 发现未调度的 Pod,选择 Node 并更新 Pod 的 nodeName 字段(再次写入 ETCD)。
  4. 执行创建:目标 Node 的 Kubelet 监听到分配给它的 Pod,调用容器运行时启动容器。

Manual和使用Kuberadm部署ETCD

1.3.1 ETCD 手动安装步骤(Linux 示例)
1. 下载 ETCD 二进制文件
1
2
3
4
5
6
7
8
# 使用国内镜像加速下载
ETCD_VERSION="v3.5.0"
wget https://mirrors.aliyun.com/etcd/${ETCD_VERSION}/etcd-${ETCD_VERSION}-linux-amd64.tar.gz
tar -xvf etcd-${ETCD_VERSION}-linux-amd64.tar.gz
cd etcd-${ETCD_VERSION}-linux-amd64

# 将二进制文件移动到系统路径
sudo mv etcd etcdctl /usr/local/bin/
2. 创建 ETCD 数据和配置目录
1
2
sudo mkdir -p /var/lib/etcd /etc/etcd
sudo chown -R $USER:$USER /var/lib/etcd /etc/etcd

ETCD 服务文件详解(etcd.service)

1. 创建 Systemd 服务文件

编辑 /etc/systemd/system/etcd.service,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[Unit]
Description=etcd key-value store
Documentation=https://etcd.io/docs
After=network.target

[Service]
Type=notify
User=root
EnvironmentFile=-/etc/etcd/etcd.conf
ExecStart=/usr/local/bin/etcd \
--name ${ETCD_NAME} \
--data-dir ${ETCD_DATA_DIR} \
--listen-client-urls ${ETCD_LISTEN_CLIENT_URLS} \
--advertise-client-urls ${ETCD_ADVERTISE_CLIENT_URLS} \
--listen-peer-urls ${ETCD_LISTEN_PEER_URLS} \
--initial-advertise-peer-urls ${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
--initial-cluster ${ETCD_INITIAL_CLUSTER} \
--initial-cluster-token ${ETCD_INITIAL_CLUSTER_TOKEN} \
--initial-cluster-state ${ETCD_INITIAL_CLUSTER_STATE}
Restart=always
RestartSec=5s
LimitNOFILE=40000

[Install]
WantedBy=multi-user.target

2. 关键参数解析

参数 作用 示例值
--name 当前节点名称(集群内唯一) etcd-node1
--data-dir 数据存储目录 /var/lib/etcd
--listen-client-urls 监听客户端请求的 URL(需包含 http://0.0.0.0:2379 以允许所有 IP) http://0.0.0.0:2379,http://localhost:2379
--advertise-client-urls 对外宣告的客户端访问地址(需为外部可访问 IP) http://192.168.1.100:2379
--listen-peer-urls 监听其他 ETCD 节点通信的 URL(集群模式必需) http://0.0.0.0:2380
--initial-cluster 初始集群成员列表(格式:name1=http://ip1:2380,name2=http://ip2:2380) etcd-node1=http://192.168.1.100:2380
--initial-cluster-token 集群唯一标识符(防止不同集群意外合并) my-etcd-cluster
--initial-cluster-state 集群初始状态(new 或 existing) new

3. 环境变量文件 /etc/etcd/etcd.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 节点配置
ETCD_NAME="etcd-node1"
ETCD_DATA_DIR="/var/lib/etcd"

# 网络配置
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.100:2379"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.100:2380"

# 集群配置
ETCD_INITIAL_CLUSTER="etcd-node1=http://192.168.1.100:2380,etcd-node2=http://192.168.1.101:2380"
ETCD_INITIAL_CLUSTER_TOKEN="my-etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

三、启动 ETCD 并验证

1. 启动服务

1
2
3
4
5
6
7
8
9
10
11
# 重载 Systemd 配置
sudo systemctl daemon-reload

# 启动 ETCD
sudo systemctl start etcd

# 设置开机自启
sudo systemctl enable etcd

# 查看状态
sudo systemctl status etcd

2. 验证 ETCD 功能

1
2
3
4
5
6
7
8
# 写入键值
ETCDCTL_API=3 etcdctl --endpoints=http://192.168.1.100:2379 put /testkey "hello"

# 读取键值
ETCDCTL_API=3 etcdctl --endpoints=http://192.168.1.100:2379 get /testkey

# 查看集群成员
ETCDCTL_API=3 etcdctl --endpoints=http://192.168.1.100:2379 member list

四、与 Kubernetes 集成

1. 配置 kube-apiserver 连接 ETCD

编辑 kube-apiserver 启动参数(通常在 /etc/kubernetes/manifests/kube-apiserver.yaml):

1
2
3
4
5
6
7
8
spec:
containers:
- command:
- kube-apiserver
- --etcd-servers=http://192.168.1.100:2379
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt # TLS 证书(若启用)
- --etcd-certfile=/etc/kubernetes/pki/etcd/server.crt
- --etcd-keyfile=/etc/kubernetes/pki/etcd/server.key

2. TLS 加密配置(生产环境必需)

1
2
3
4
5
6
7
8
9
10
# 使用 cfssl 生成证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server etcd-csr.json | cfssljson -bare etcd

# 更新 ETCD 启动参数
--listen-client-urls=https://0.0.0.0:2379 \
--advertise-client-urls=https://192.168.1.100:2379 \
--cert-file=/etc/etcd/etcd.pem \
--key-file=/etc/etcd/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ca.pem

五、常见问题排查

1. 服务启动失败

  • 日志查看:
    1
    journalctl -u etcd -f
  • 常见错误:
    • 端口冲突:确保 2379(客户端)和 2380(节点间通信)未被占用。
    • 证书权限:TLS 证书需对 ETCD 进程用户可读。

2. 集群节点无法加入

  • 检查网络:确保防火墙放行 2379/tcp 和 2380/tcp。
  • 一致性校验:所有节点的 --initial-cluster 列表必须一致。

手动部署优势:完全控制配置,适合生产环境定制化需求。

核心要点:

  1. 正确配置 etcd.service 的启动参数(尤其是网络和集群参数)。
  2. 生产环境必须启用 TLS 加密。
  3. 通过 etcdctl 和 journalctl 快速诊断问题。

通过以上步骤,可以搭建一个高可用的 ETCD 集群,并为 Kubernetes 提供稳定的数据存储服务。

1.3.1 使用Kubeadm部署ETCD服务器

1. 部署方式对比

对比项 kubeadm 部署 ETCD 手动部署 ETCD
安装复杂度 全自动,通过 kubeadm init 一键完成 需手动下载二进制、配置证书、编写 systemd 服务文件
配置文件生成 自动生成 /etc/kubernetes/manifests/etcd.yaml 需手动编写 /etc/systemd/system/etcd.service
证书管理 自动生成(有效期 1 年),支持 kubeadm certs renew 需手动用 cfssl 或 openssl 生成并管理
集群模式 默认集成在 Kubernetes 控制平面,高需需额外配置 需手动配置 --initial-cluster 参数实现高可用
网络插件依赖 依赖 kubeadm 的 --pod-network-cidr 配置 完全独立,需手动配置网络规则
升级维护 通过 kubeadm upgrade 统一升级 需逐个替换二进制文件并重启服务

2. kubeadm 部署 ETCD 的核心特点

  • 隐式部署:
    kubeadm 默认将 ETCD 作为静态 Pod 部署在 Master 节点上,无需用户直接操作。

    • 配置文件路径:/etc/kubernetes/manifests/etcd.yaml
    • 数据目录:/var/lib/etcd
  • 查看 ETCD 状态:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    # (查询 kube-system 命名空间中带有标签 component=etcd 的 Pod(通常是 Kubernetes 集群的 ETCD 实例)
    # -n kube-system 指定命名空间(namespace)为 kube-system(系统组件默认部署在此)
    # -l component=etcd 筛选标签(Label)中 component 值为 etcd 的资源
    kubectl get pods -n kube-system -l component=etcd

    # 输出示例
    # NAME READY STATUS RESTARTS AGE
    # etcd-master-node1 1/1 Running 0 5d
    # etcd-master-node2 1/1 Running 0 5d

    # 在名为 etcd-master 的 Pod 中执行 etcdctl 命令,列出 ETCD 中所有键
    # exec etcd-master 在指定 Pod(etcd-master)中执行命令。
    # -- 分隔符,表示后续参数传递给容器内的命令(而非 kubectl)。
    # etcdctl get / --prefix 递归获取所有以 / 开头的键(即全部键)。
    # --keys-only 仅输出键名,不输出值(节省输出空间)。
    kubectl exec etcd-master -n kube-system etcdctl get / --prefix -keys-only

    # 输出示例
    # "/registry/:Kubernetes 资源存储前缀,后续路径按资源类型分层(如 apiregistration.k8s.io/apiservices 表示 API 服务)"
    # /registry/apiregistration.k8s.io/apiservices/v1.
    # /registry/apiregistration.k8s.io/apiservices/v1.apps
    # /registry/clusterrolebindings/cluster-admin
    # /registry/pods/kube-system/etcd-master

    # 查看 ETCD 集群状态(需在 Master 节点执行)
    sudo docker exec -it $(sudo docker ps | grep etcd | awk '{print $1}') etcdctl endpoint health
  • 修改配置:
    直接编辑 /etc/kubernetes/manifests/etcd.yaml,kubelet 会自动重启 Pod。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    apiVersion: v1
    kind: Pod
    metadata:
    name: etcd
    namespace: kube-system
    spec:
    containers:
    - command:
    - etcd
    - --data-dir=/var/lib/etcd
    - --listen-client-urls=https://127.0.0.1:2379
    - --advertise-client-urls=https://127.0.0.1:2379
    - --cert-file=/etc/kubernetes/pki/etcd/server.crt
    - --key-file=/etc/kubernetes/pki/etcd/server.key
    - --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt

3. 如何选择?

场景 推荐方式 理由
快速搭建测试/生产集群 kubeadm 避免手动配置错误,内置最佳实践(如证书轮换、高可用方案)
学习 ETCD 原理或定制开发 手动部署 深入理解参数含义(如 --heartbeat-interval、--election-timeout)
需要与 Kubernetes 解耦 手动部署独立集群 避免 Kubernetes 控制平面故障影响 ETCD
大规模生产环境 kubeadm + 外部 ETCD 将 ETCD 集群与 Kubernetes 分离,提升稳定性和可扩展性

4. 性能与稳定性注意事项

  • kubeadm 默认限制:

    • ETCD 默认未配置资源限制(需手动添加 resources 到 etcd.yaml)。
    • 数据目录未自动挂载独立磁盘(生产环境建议手动挂载 SSD)。
  • 手动部署优势:

    • 可调优参数(如 --snapshot-count、--max-request-bytes)。
    • 灵活选择存储引擎(默认 boltdb,可测试 etcd v3.5+ 的 --backend 选项)。

5. 故障恢复对比

操作 kubeadm 手动部署
数据备份 etcdctl snapshot save (需进入容器) 直接操作主机上的 etcdctl
数据恢复 通过 etcd.yaml 挂载备份卷恢复 手动替换数据目录并重启服务
节点故障替换 kubeadm reset + 重新加入节点 手动修改 --initial-cluster 参数