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 转发、负载均衡)。
  • 关键关系
    • 实现 ClusterIPNodePort 等网络功能。

核心概念关系总结

概念 功能简述 依赖/交互对象
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 集群初始状态(newexisting 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/tcp2380/tcp
  • 一致性校验:所有节点的 --initial-cluster 列表必须一致。

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

核心要点

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

通过以上步骤,可以搭建一个高可用的 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 需手动用 cfsslopenssl 生成并管理
集群模式 默认集成在 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 默认未配置资源限制(需手动添加 resourcesetcd.yaml)。
    • 数据目录未自动挂载独立磁盘(生产环境建议手动挂载 SSD)。
  • 手动部署优势

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

5. 故障恢复对比

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