Kubernetes The Hard Way:从零引导单节点 etcd 集群(kthw Lab 07 实战解析)
在 Kubernetes The Hard Way 教程中,Kubernetes 各控制面组件本身都是无状态的——它们的所有集群状态(Node、Service、Deployment、Secret 等对象的真实数据)都存储在一个名为 etcd 的分布式键值数据库中。本篇对应 Bootstrapping the etcd Cluster 实验,带你以“无脚本、纯手工”的方式在 server 机器上安装并引导一个单节点 etcd 集群,逐一剖析 units/etcd.service 中的每个启动参数的含义。读完本篇,你将掌握:etcd 二进制与 systemd 服务的部署流程、etcd 各监听端口的职责(2379/2380)、集群成员与数据目录的权限配置,以及后续 kube-apiserver 如何以 --etcd-servers 参数接入这个数据后端。
为什么 Kubernetes 需要 etcd
从 README.md 的组件清单可以看到,本教程使用的组件版本为:
- kubernetes v1.32.x(具体为 v1.32.3,见 downloads-amd64.txt)
- containerd v2.1.x
- cni v1.6.x
- etcd v3.6.x(本仓库下载列表锁定为 v3.6.0-rc.3)
Kubernetes API Server 是唯一与 etcd 直接通信的控制面组件。kube-scheduler、kube-controller-manager 等组件通过 API Server 间接读写集群状态。因此,引导 etcd 是引导整个控制平面之前最关键的一步:一旦 etcd 不可用,集群将失去其持久化状态。本教程选择在 server 单机上引导一个单节点 etcd 集群,足以支撑学习目的;生产环境则通常需要 3 个(或 5 个)成员构成 Raft 集群。
前置条件:拷贝 etcd 二进制与 systemd 单元文件
整个教程在四台 Debian 12 (bookworm) 机器上运行(jumpbox、server、node-0、node-1,硬件要求见 Prerequisites)。etcd 的二进制文件已在 Set Up The Jumpbox 阶段从 downloads-amd64.txt(或 downloads-arm64.txt)统一下载并解压到 jumpbox 的 downloads/ 目录下,其中:
downloads/controller/etcd:etcd 服务端二进制downloads/client/etcdctl:etcd 的命令行客户端工具
本 Lab 的第一步,是在 jumpbox 上把 etcd 二进制与 systemd 单元文件拷贝到 server 机器:
scp \
downloads/controller/etcd \
downloads/client/etcdctl \
units/etcd.service \
root@server:~/
之后登录 server 机器执行后续所有命令:
ssh root@server
注意:本 Lab 的后续命令都必须在
server机器上执行,而不是jumpbox。
安装 etcd 二进制
在 server 机器上,把 etcd(服务端)与 etcdctl(命令行工具)移动到 PATH 中的 /usr/local/bin/:
{
mv etcd etcdctl /usr/local/bin/
}
这一步完成后,两个二进制都可以直接通过命令名调用。
配置 etcd 服务目录与数据目录
接下来创建 etcd 的配置目录与数据目录,并把 TLS 证书放进配置目录:
{
mkdir -p /etc/etcd /var/lib/etcd
chmod 700 /var/lib/etcd
cp ca.crt kube-api-server.key kube-api-server.crt \
/etc/etcd/
}
逐条拆解这个操作的用意:
/etc/etcd/:存放 etcd 服务运行所需的证书等配置材料。这里复制了 Provisioning the CA and Generating TLS Certificates 实验在jumpbox生成并分发到server的三个文件:ca.crt(CA 根证书)、kube-api-server.key与kube-api-server.crt(kube-apiserver 的客户端证书/密钥对)。这些证书在后续控制面组件中会被用作身份凭证。/var/lib/etcd:etcd 的数据目录(BBolt 数据库与 WAL 日志所在处),对应 systemd 单元中的--data-dir=/var/lib/etcd。chmod 700 /var/lib/etcd:把数据目录权限收紧为仅 root 可读写执行。etcd 中存储着集群的全部状态,其中可能包含 Secret 等敏感数据(即便本教程后续用 生成数据加密配置 的 encryption-config 对其做静态加密),收紧目录权限是基本的纵深防御措施。
原文档还特别强调了一点:etcd 集群中的每个成员必须拥有唯一的 --name,教程将该成员名设置为与当前计算实例的 hostname 一致(本教程中为 controller)。这一点直接体现在下文的 systemd 单元里。
深入解析 units/etcd.service 的每个启动参数
把单元文件放入 systemd 目录:
mv etcd.service /etc/systemd/system/
本仓库提供的 units/etcd.service 内容如下,这也是理解 etcd 启动行为的核心:
[Unit]
Description=etcd
Documentation=https://github.com/etcd-io/etcd
[Service]
Type=notify
ExecStart=/usr/local/bin/etcd \
--name controller \
--initial-advertise-peer-urls http://127.0.0.1:2380 \
--listen-peer-urls http://127.0.0.1:2380 \
--listen-client-urls http://127.0.0.1:2379 \
--advertise-client-urls http://127.0.0.1:2379 \
--initial-cluster-token etcd-cluster-0 \
--initial-cluster controller=http://127.0.0.1:2380 \
--initial-cluster-state new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
参数逐一解析:
| 参数 | 取值 | 作用 |
|---|---|---|
--name |
controller |
本成员在集群内的唯一标识,教程要求其等于实例 hostname |
--initial-advertise-peer-urls |
http://127.0.0.1:2380 |
告知集群中其他成员用哪个地址与本节点通信(peer 流量) |
--listen-peer-urls |
http://127.0.0.1:2380 |
etcd 实际监听 peer/Raft 通信的端口(2380) |
--listen-client-urls |
http://127.0.0.1:2379 |
etcd 实际监听客户端 API 请求的端口(2379) |
--advertise-client-urls |
http://127.0.0.1:2379 |
对外通告的客户端接入地址,供 kube-apiserver 等客户端使用 |
--initial-cluster-token |
etcd-cluster-0 |
集群令牌,用于防止把两个不同集群的成员混在同一 Raft 集群里 |
--initial-cluster |
controller=http://127.0.0.1:2380 |
初始成员列表;只有 controller 一个成员,即单节点集群 |
--initial-cluster-state |
new |
声明这是一个全新集群(而非向已有集群加入) |
--data-dir |
/var/lib/etcd |
持久化数据目录 |
此外,单元文件还体现了几个 systemd 层面的设计:
Type=notify:etcd 会主动通过 systemd 的 sd_notify 协议汇报就绪状态,systemd 能准确判断服务真正完成启动,而不是只看进程是否拉起。Restart=on-failure与RestartSec=5:进程异常退出时 5 秒后自动重启,提供基本的自愈能力。- 全部地址绑定在
127.0.0.1:由于本教程把控制面组件全部部署在同一台server机器上,etcd 只需对本地回环接口可达即可,这也避免了数据端口暴露到网络。
值得对照的一点是:从 units/kube-apiserver.service 的 --etcd-servers=http://127.0.0.1:2379 参数可以看出,API Server 正是通过 2379 客户端端口访问本集群的——两个服务文件在端口约定上是互相咬合的。同时可以看到,这个用于教学的单节点集群在 peer 与 client 连接上都使用 http://(未启用 TLS 与客户端证书认证);教程目标是学习引导流程本身,生产环境通常还会加上 --cert-file、--key-file、--client-cert-auth 等参数来启用 TLS 与身份认证。
启动 etcd 服务
把单元文件就位后,重载 systemd 配置并启用、启动服务:
{
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
}
daemon-reload 让 systemd 重新读取 /etc/systemd/system/ 下新增的单元文件;enable 使 etcd 在机器重启后随 multi-user.target 自动拉起;start 立即启动服务。
验证:列出 etcd 集群成员
使用此前一并拷贝安装的 etcdctl 列出集群成员:
etcdctl member list
预期输出形如:
6702b0a34e2cfd39, started, controller, http://127.0.0.1:2380, http://127.0.0.1:2379, false
输出各字段的含义:
6702b0a34e2cfd39:成员 ID(十六进制),由 etcd 在成员加入时分配;started:成员状态正常、已参与 Raft 集群;controller:与--name controller对应的成员名;http://127.0.0.1:2380:该成员的 peer 地址;http://127.0.0.1:2379:该成员的客户端地址;false:非learner成员。
若输出中出现 unstarted 或地址对不上,通常意味着 --initial-cluster 与实际网络配置不一致,可回到单元文件逐项核对。你也可以用 systemctl status etcd 确认进程状态,配合单元文件中的 RestartSec=5 观察异常重启行为。
小结与下一步
本 Lab 以四个动作完成了单节点 etcd 集群的引导:拷贝二进制与单元文件 → 安装二进制并配置证书/数据目录 → 通过 systemd 单元启动服务 → 用 etcdctl member list 验证成员状态。etcd 就绪后,Kubernetes 集群状态的持久化后端就位了。
按照教程顺序,下一步是 Bootstrapping the Kubernetes Control Plane:在 server 上部署 kube-apiserver、kube-scheduler 与 kube-controller-manager,其中 kube-apiserver 会通过 --etcd-servers=http://127.0.0.1:2379(见 units/kube-apiserver.service)直接对接本实验建立的 etcd 实例。
适用前提与限制:本篇操作基于本仓库锁定的组件版本(Kubernetes v1.32.3 / etcd v3.6.0-rc.3,见 downloads-amd64.txt),操作系统为 Debian 12 (bookworm),全部命令以 root 用户执行,且控制面组件与 etcd 同机部署于
server。教程结果不应视为生产就绪方案,生产集群在成员数、TLS 与备份策略上均需另行设计。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00