kubernetes(K8s)学习笔记(第二期):Kubernetes 集群部署实战(kubeadm)
本笔记为 Kubernetes 系列第二期,聚焦生产级 Kubernetes 集群的完整部署流程。采用 kubeadm 官方工具,基于 Ubuntu 24.04 操作系统和 containerd 容器运行时,从环境准备到集群初始化、网络插件部署、节点加入,完整搭建一个可用的 Kubernetes 1.30 集群。全文约 6000 字 ,包含 90+ 命令示例 和 15 张对比表格,是一份可直接用于生产环境部署的实战指南。
--- Compiled and Authored by Whisky --- June 23 rd, 2026
目录
- 部署方式对比与选型
- 环境准备(模板机)
- 内核模块与参数配置
- 容器运行时配置(containerd)
- 安装 Kubernetes 组件
- 克隆节点与配置
- 集群初始化(Master 节点)
- 部署网络插件(Calico)
- Worker 节点加入集群
- 验证集群
- 总结与知识点一览表
一、部署方式对比与选型
1.1 Kubernetes 部署方式全景图
| 安装方式 | 核心特点 | 难度 | 适用场景 | 推荐指数 |
|---|---|---|---|---|
| kubeadm | 官方标准、无魔改、兼容性强 | 中等 | 生产自建、CKA/CKAD 考试、标准集群 | ⭐⭐⭐⭐⭐ |
| 二进制手工部署 | 全手动、底层可控、无封装 | 极高 | 原理研究、深度定制、教学演示 | ⭐⭐ |
| Sealos / KubeKey | 一键部署、高可用、自带插件 | 低 | 快速搭建生产/测试环境 | ⭐⭐⭐⭐ |
| k3s / k0s | 轻量、单二进制、适合边缘 | 低 | 边缘节点、低配机器、开发测试 | ⭐⭐⭐⭐ |
| minikube / kind | 单机实验环境、一键启动 | 极低 | 本地开发、快速验证 | ⭐⭐⭐ |
| 云厂商托管(ACK/EKS) | Master 托管、免运维、高可用 | 低 | 云上生产业务 | ⭐⭐⭐⭐ |
1.2 为什么选择 kubeadm?
kubeadm 是 Kubernetes 官方提供的集群部署工具,其核心优势在于:
- 官方标准:遵循 Kubernetes 最佳实践,所有组件配置均经过验证
- 无魔改:没有任何封装和隐藏逻辑,部署过程完全透明
- 易于升级:支持集群的平滑升级,无需重新部署
- 生态完善:文档丰富,社区支持广泛,故障排查容易
- 兼容性强:支持多种操作系统和容器运行时
我们的选择 :对于学习 + 未来上生产,优先选择 kubeadm。它既能让你深入理解 Kubernetes 各组件的协作关系,又能直接用于生产环境。
1.3 部署方式选择建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 学习 + 标准生产 | kubeadm | 官方标准,兼容性最好,社区支持最强 |
| 快速测试/边缘场景 | k3s | 轻量级,单二进制,资源占用低 |
| 云上生产业务 | ACK / EKS / TKE | Master 免运维,与云服务深度集成 |
| 原理学习/深度定制 | 二进制部署 | 完全可控,无任何封装 |
1.4 本期部署方案概览
| 项目 | 选择 |
|---|---|
| 操作系统 | Ubuntu 24.04 LTS |
| Kubernetes 版本 | 1.30.2 |
| 容器运行时 | containerd.io 1.7.20 |
| 网络插件 | Calico v3.30.7 |
| Pod 网络 CIDR | 10.224.0.0/16 |
| 集群规模 | 1 Master + 2 Worker |
1.5 部署环境要求
在开始部署之前,需要确认以下硬件和软件要求:
| 要求项 | 最低配置 | 推荐配置 |
|---|---|---|
| CPU | 2 核心 | 4 核心+ |
| 内存 | 2 GB | 4 GB+ |
| 磁盘 | 20 GB | 100 GB+ |
| 操作系统 | Ubuntu 22.04 | Ubuntu 24.04 |
| 网络 | 节点间互通 | 千兆网络 |
| 时间同步 | NTP 服务 | chrony |
1.6 本部署方式与生产环境的适配性说明
kubeadm 部署的集群可直接用于生产环境,这也是它区别于 minikube 等本地开发工具的核心特点。生产环境中,只需在此基础上增加:
- 高可用控制平面:部署 3 个或 5 个 Master 节点,实现控制平面高可用
- 负载均衡器:在多个 Master 节点前部署 LB(如 HAProxy、云厂商 LB)
- 持久化存储:部署 CSI 存储插件(如 Ceph、NFS、云厂商存储)
- 监控告警:部署 Prometheus + Grafana + AlertManager
- 日志收集:部署 ELK/EFK 日志栈
二、环境准备(模板机)
策略说明:先准备一台"模板机",完成所有基础配置,然后克隆出 Master 和 Worker 节点,避免重复劳动。
2.1 虚拟机硬件配置
| 配置项 | 规格 | 说明 |
|---|---|---|
| CPU | 2 核心 | 最少 2 核,否则 kubelet 可能启动失败 |
| 内存 | 4 GB | 至少 2GB,推荐 4GB+ |
| 网卡 | 1 个 NAT 网卡 | 用于节点间通信 |
| 磁盘 | 100 GB | 至少 20GB,用于存储镜像和日志 |
| 分区 | /boot 2GB,/ 90GB | 不需要 swap 分区 |
2.2 配置软件仓库源
操作系统仓库换成华为云镜像(速度更快):
bash
[root@ubuntu2404 ~]# cat > /etc/apt/sources.list.d/ubuntu.sources <<'EOF'
Types: deb
URIs: http://mirrors.huaweicloud.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
配置 containerd 仓库(来自 Docker CE 源,版本更新):
bash
# 导入 containerd 仓库 key
[root@ubuntu2404 ~]# curl -fsSL https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu/gpg | gpg --dearmour -o /etc/apt/trusted.gpg.d/containerd.gpg
# 添加 containerd 仓库
[root@ubuntu2404 ~]# cat << 'EOF' > /etc/apt/sources.list.d/docker-ce.list
deb [arch=amd64] https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu noble stable
EOF
配置 Kubernetes 仓库(阿里云镜像,支持 v1.24-v1.35):
bash
# 添加 kubernetes 仓库 key
[root@ubuntu2404 ~]# curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# 添加 kubernetes 仓库
[root@ubuntu2404 ~]# echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/ /" > /etc/apt/sources.list.d/kubernetes.list
版本替换说明 :如需安装其他版本(如 v1.29),将上述配置中的
v1.30替换为v1.29即可。目前该源支持 v1.24 - v1.35 版本。
2.3 安装基础软件包
bash
[root@ubuntu2404 ~]# apt update && apt install -y \
vim \ # 强大的终端文本编辑器
lrzsz \ # 便于 Xshell 上传/下载文件
bash-completion \ # 命令行自动补全
open-vm-tools \ # VMware 虚拟机工具(时间同步、文件拖拽)
apt-transport-https \ # 让 apt 支持 HTTPS 下载
sshpass # 非交互式 SSH 登录(脚本自动化用)
2.4 设置静态 IP 地址
bash
[root@ubuntu2404 ~]# mkdir /etc/netplan/origin
[root@ubuntu2404 ~]# mv /etc/netplan/*yaml /etc/netplan/origin
[root@ubuntu2404 ~]# cat > /etc/netplan/00-static.yaml <<EOF
network:
ethernets:
ens32:
dhcp4: no
addresses:
- 10.1.8.30/24
routes:
- to: default
via: 10.1.8.2
nameservers:
addresses:
- 223.5.5.5
version: 2
EOF
[root@ubuntu2404 ~]# chmod 600 /etc/netplan/00-static.yaml
[root@ubuntu2404 ~]# netplan apply
2.5 配置 /etc/hosts(集群 DNS 解析)
bash
[root@ubuntu2404 ~]# cat << 'EOF' >> /etc/hosts
###### kubernetes #####
10.1.8.30 master30.whisky.cloud master30
10.1.8.31 worker31.whisky.cloud worker31
10.1.8.32 worker32.whisky.cloud worker32
EOF
为什么要配置 hosts? 集群内部组件通过主机名互相通信,配置 hosts 可以避免依赖外部 DNS,提高集群稳定性。特别是在内网 DNS 不稳定的情况下,hosts 解析是最可靠的方式。Kubernetes 的 TLS 证书中包含主机名信息,如果主机名无法解析,API Server 会拒绝连接。可以这样理解:hosts 文件相当于集群内部的"电话簿",每个节点需要知道其他节点的"联系方式"(IP 地址)。
2.6 关闭 swap
Kubernetes 要求关闭 swap,原因如下:
- kubelet 的 QoS(服务质量)保障机制依赖于内存的确定性
- 开启 swap 会导致 Pod 内存统计不准确,影响调度决策
- 容器运行时(containerd)也建议关闭 swap
- 简单来说:swap 让内存看起来比实际更大,但会拖慢性能,Kubernetes 需要精确的内存管理
bash
bash
[root@ubuntu2404 ~]# swapoff -a && sed -i '/^.*swap/d' /etc/fstab
[root@ubuntu2404 ~]# rm -f /swap.img
2.7 配置时间同步(chrony)
bash
[root@ubuntu2404 ~]# apt-get install -y chrony
[root@ubuntu2404 ~]# systemctl enable chrony --now
为什么需要时间同步? Kubernetes 集群中的证书(如 API Server 证书)依赖时间戳验证,时间不一致会导致证书校验失败。证书验证失败则 kubelet 无法与 API Server 正常通信,集群会处于异常状态。节点间时间差超过 5 分钟(默认)会导致 TLS 握手失败。可以这样理解:证书是有"有效期"的,节点之间时间不一致,就会像两个人手表时间不同,导致"预约"(连接)失败。
2.8 优化 SSH 配置
bash
# 禁用 SSH 反向 DNS 解析(加速连接)
[root@ubuntu2404 ~]# echo 'UseDNS no' >> /etc/ssh/sshd_config
# 禁用客户端 SSH 主机密钥检查(自动化脚本免交互)
[root@ubuntu2404 ~]# echo 'StrictHostKeyChecking no' >> /etc/ssh/ssh_config
# 生成 SSH 密钥对
[root@ubuntu2404 ~]# ssh-keygen -N '' -f ~/.ssh/id_rsa -t rsa
# 配置本机免密登录(替换 password 为实际密码)
[root@ubuntu2404 ~]# sshpass -p password ssh-copy-id root@localhost
SSH 优化的作用:
UseDNS no:避免每次 SSH 连接时进行反向 DNS 查询,提升连接速度StrictHostKeyChecking no:自动化脚本中无需手动确认主机密钥,便于批量操作
三、内核模块与参数配置
3.1 加载基础网络模块
bash
# 临时加载(立即生效)
[root@ubuntu2404 ~]# modprobe overlay
[root@ubuntu2404 ~]# modprobe br_netfilter
# 永久加载(重启生效)
[root@ubuntu2404 ~]# cat > /etc/modules-load.d/k8s-net.conf << EOF
br_netfilter
overlay
EOF
模块功能说明:
| 模块 | 功能 |
|---|---|
overlay |
Overlay 文件系统,容器镜像分层存储必需 |
br_netfilter |
允许 Linux 网桥上的流量经过 iptables 过滤,K8s 网络通信必需 |
3.2 加载 IPVS 内核模块
IPVS(IP Virtual Server) 是 Linux 内核的负载均衡模块,kube-proxy 的 IPVS 模式比 iptables 模式性能更高,适合大规模集群(1000+ Service)。
IPVS vs iptables 性能对比:
| 对比维度 | iptables 模式 | IPVS 模式 |
|---|---|---|
| 规则复杂度 | 线性链表,规则越多越慢 | 哈希表,O(1) 查询 |
| Service 数量限制 | 2000 以下 | 50000+ |
| 负载均衡算法 | 仅轮询 | 支持 8 种算法 |
| 连接跟踪 | 无 | 有(nf_conntrack) |
| 适用场景 | 小规模集群 | 大规模、高并发集群 |
bash
# 临时加载
[root@ubuntu2404 ~]# modprobe ip_vs
[root@ubuntu2404 ~]# modprobe ip_vs_rr
[root@ubuntu2404 ~]# modprobe ip_vs_wrr
[root@ubuntu2404 ~]# modprobe ip_vs_lc
[root@ubuntu2404 ~]# modprobe ip_vs_sh
[root@ubuntu2404 ~]# modprobe nf_conntrack
# 永久加载
[root@ubuntu2404 ~]# cat >> /etc/modules-load.d/k8s-net.conf << EOF
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_lc
ip_vs_sh
nf_conntrack
EOF
IPVS 调度算法说明:
| 模块 | 算法 | 说明 | 适用场景 |
|---|---|---|---|
ip_vs_rr |
轮询 | 按顺序轮流分发请求 | 后端能力均衡 |
ip_vs_wrr |
加权轮询 | 按权重比例分发请求 | 后端能力不均 |
ip_vs_lc |
最少连接 | 优先发给连接数最少的后端 | 长连接场景 |
ip_vs_sh |
源地址哈希 | 同一客户端始终访问同一后端 | 需要会话保持 |
3.3 配置 sysctl 内核参数
bash
[root@ubuntu2404 ~]# cat > /etc/sysctl.d/k8s.conf << 'EOF'
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
[root@ubuntu2404 ~]# sysctl -p /etc/sysctl.d/k8s.conf
参数说明:
| 参数 | 值 | 作用 | 类比 |
|---|---|---|---|
bridge-nf-call-iptables |
1 | 网桥流量经过 iptables 规则 | 桥梁上的车经过检查站 |
bridge-nf-call-ip6tables |
1 | 网桥流量经过 ip6tables 规则 | IPv6 版本的检查站 |
ip_forward |
1 | 开启路由转发,Pod 间跨节点通信必需 | 路由器允许数据包转发 |
swappiness |
0 | 禁止使用 swap,保证内存确定性 | 宁可内存不足也不用慢速磁盘 |
四、容器运行时配置(containerd)
4.1 安装 containerd.io
bash
[root@ubuntu2404 ~]# apt-get install -y containerd.io=1.7.20-1 cri-tools
为什么选择 containerd.io 而不是 Ubuntu 仓库的 containerd? containerd.io 由 Docker Inc. 维护,版本更新更快,与 Kubernetes 的兼容性更好。生产环境建议使用此版本。
4.2 配置 crictl 对接 containerd
bash
[root@ubuntu2404 ~]# crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock
crictl 的作用:crictl 是 CRI(容器运行时接口)的客户端工具,用于调试 K8s 节点上的容器和镜像。它不依赖 kubectl,直接在节点上操作 containerd。当 Pod 无法启动时,可以使用 crictl 排查节点上的容器状态。可以这样理解:kubectl 是"管理员的遥控器",从集群层面控制;crictl 是"维修工的工具箱",在节点本地排查问题。
4.3 生成并修改 containerd 配置
生成默认配置:
bash
[root@ubuntu2404 ~]# containerd config default > /etc/containerd/config.toml
修改 SystemdCgroup(与系统 cgroup 驱动保持一致):
bash
[root@ubuntu2404 ~]# sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
为什么要改 SystemdCgroup? Kubernetes 使用 systemd 作为 cgroup 驱动,containerd 必须与 kubelet 保持一致。不一致会导致 Pod 资源限制失效,甚至节点异常。具体错误表现为 Pod 的内存限制不生效或 CPU 配额无法正确分配。简单来说:cgroup 是 Linux 限制资源的方式,systemd 是管理这些限制的工具,两者必须匹配,否则"管理员"和"工具"说的不是同一种语言。
修改 sandbox_image(Pause 容器镜像):
bash
[root@ubuntu2404 ~]# sed -i 's|sandbox_image = ".*"|sandbox_image = "registry.k8s.io/pause:3.9"|' /etc/containerd/config.toml
Pause 容器的作用:在 Kubernetes 中,每个 Pod 会先启动一个 Pause 容器,它负责持有 Pod 的网络命名空间(Network Namespace),其他业务容器共享这个网络命名空间,从而实现 Pod 内多个容器共享 IP 和端口空间。Pause 容器虽小(约 700KB),但却是 Pod 网络的基础。如果 Pause 容器无法启动,整个 Pod 都无法运行。Pause 容器就像"公寓的公共门厅",业务容器是"各个房间",所有房间共享同一个门牌号(IP 地址)。
4.4 配置镜像加速(CRI 插件方式)
编辑 /etc/containerd/config.toml,在 mirrors 部分添加:
toml
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.m.daocloud.io","https://docker.1ms.run","https://docker.xuanyuan.me"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
endpoint = ["https://k8s.m.daocloud.io","https://registry.cn-hangzhou.aliyuncs.com/google_containers"]
提示 :这种
mirrors配置方式只对 CRI 接口生效 (即crictl和 Kubernetes 节点),nerdctl需要独立的certs.d配置(见下一节)。两者分工不同,不能互相替代。
重启 containerd:
bash
[root@ubuntu2404 ~]# systemctl restart containerd.service
验证镜像加速:
bash
[root@ubuntu2404 ~]# crictl pull busybox
Image is up to date for sha256:925ff61909...
4.5 安装 nerdctl 和 CNI 插件
下载并安装 nerdctl:
bash
[root@ubuntu2404 ~]# wget http://192.168.42.200/course-materials/softwares/stage03/nerdctl-1.7.7-linux-amd64.tar.gz
[root@ubuntu2404 ~]# tar -xf nerdctl-1.7.7-linux-amd64.tar.gz -C /usr/bin/
下载并安装 CNI 插件:
bash
[root@ubuntu2404 ~]# wget http://192.168.42.200/course-materials/softwares/stage03/cni-plugins-linux-amd64-v1.6.0.tgz
[root@ubuntu2404 ~]# mkdir -p /opt/cni/bin
[root@ubuntu2404 ~]# tar -xf cni-plugins-linux-amd64-v1.6.0.tgz -C /opt/cni/bin
配置 nerdctl 镜像加速 (certs.d 方式):
bash
# 配置 docker.io 加速
mkdir -p /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://registry-1.docker.io"
[host."https://09def58152000fc00ff0c00057bad7e0.mirror.swr.myhuaweicloud.com"]
capabilities = ["pull", "resolve"]
EOF
# 配置 registry.k8s.io 加速
mkdir -p /etc/containerd/certs.d/registry.k8s.io
cat > /etc/containerd/certs.d/registry.k8s.io/hosts.toml << EOF
server = "https://registry.k8s.io"
[host."https://k8s.m.daocloud.io"]
capabilities = ["pull", "resolve"]
[host."https://registry.cn-hangzhou.aliyuncs.com/google_containers"]
capabilities = ["pull", "resolve"]
override_path = true
EOF
五、安装 Kubernetes 组件
5.1 查看可用版本
bash
[root@ubuntu2404 ~]# apt list kubeadm -a | head
kubeadm/unknown 1.30.2-1.1 amd64
kubeadm/unknown 1.30.1-1.1 amd64
kubeadm/unknown 1.30.0-1.1 amd64
5.2 安装 kubeadm、kubelet、kubectl
bash
[root@ubuntu2404 ~]# apt install -y \
kubeadm=1.30.2-1.1 \
kubelet=1.30.2-1.1 \
kubectl=1.30.2-1.1
# 设置 kubelet 开机自启(此时会处于等待状态,集群初始化后变为 active)
[root@ubuntu2404 ~]# systemctl enable kubelet --now
组件说明:
kubeadm:集群部署工具,用于初始化和加入集群kubelet:节点代理,管理 Pod 生命周期kubectl:命令行客户端,与集群交互
kubelet 状态说明:安装完成后 kubelet 会不断重启等待集群初始化,这是正常现象。可以这样理解:kubelet 是"雇佣兵",必须等"指挥官"(kubeadm)下达指令后才开始正式工作。
5.3 配置命令补全
bash
# crictl 补全
[root@ubuntu2404 ~]# mkdir -p /etc/bash_completion.d
[root@ubuntu2404 ~]# crictl completion bash > /etc/bash_completion.d/crictl
[root@ubuntu2404 ~]# source /etc/bash_completion.d/crictl
# nerdctl 补全(关键:设置命名空间为 k8s.io)
[root@ubuntu2404 ~]# nerdctl completion bash > /etc/bash_completion.d/nerdctl
[root@ubuntu2404 ~]# echo 'export CONTAINERD_NAMESPACE=k8s.io' >> /etc/bash_completion.d/nerdctl
[root@ubuntu2404 ~]# source /etc/bash_completion.d/nerdctl
# kubectl 补全
[root@ubuntu2404 ~]# kubectl completion bash > /etc/bash_completion.d/kubectl
[root@ubuntu2404 ~]# source /etc/bash_completion.d/kubectl
# kubeadm 补全
[root@ubuntu2404 ~]# kubeadm completion bash > /etc/bash_completion.d/kubeadm
[root@ubuntu2404 ~]# source /etc/bash_completion.d/kubeadm
⚠️ 重要 :设置
CONTAINERD_NAMESPACE=k8s.io非常关键!Kubernetes 默认使用k8s.io命名空间中的镜像。如果不设置,nerdctl 默认将镜像导入到default命名空间,会导致 kubelet 无法找到镜像(会报failed to pull image错误)。在 K8s 节点上使用 nerdctl 时,务必确认命名空间为k8s.io。命名空间可以理解为"冰箱里的不同隔层",kubelet 只认k8s.io这个隔层里的东西。
5.4 关闭模板机
bash
[root@ubuntu2404 ~]# init 0
六、克隆节点与配置
6.1 克隆虚拟机
采用 VMware 完全克隆方法,克隆出 3 台虚拟机(1 Master + 2 Worker)。
6.2 Master 节点配置(10.1.8.30)
yaml
# 设置主机名
[root@master30 ~]# hostnamectl set-hostname master30.whisky.cloud
# 配置静态 IP
[root@master30 ~]# cat > /etc/netplan/00-static.yaml <<EOF
network:
ethernets:
ens32:
dhcp4: no
addresses:
- 10.1.8.30/24
routes:
- to: default
via: 10.1.8.2
nameservers:
addresses:
- 223.5.5.5
version: 2
EOF
[root@master30 ~]# netplan apply
6.3 Worker 节点配置(10.1.8.31 / 10.1.8.32)
Worker31:
yaml
[root@worker31 ~]# hostnamectl set-hostname worker31.whisky.cloud
[root@worker31 ~]# cat > /etc/netplan/00-static.yaml <<EOF
network:
ethernets:
ens32:
dhcp4: no
addresses:
- 10.1.8.31/24
routes:
- to: default
via: 10.1.8.2
nameservers:
addresses:
- 223.5.5.5
version: 2
EOF
[root@worker31 ~]# netplan apply
Worker32(同理,IP 设为 10.1.8.32)。
七、集群初始化(Master 节点)
7.1 预下载镜像(可选但推荐)
方式一:使用官方仓库:
bash
[root@master30 ~]# kubeadm config images pull --kubernetes-version=v1.30.2
[config/images] Pulled registry.k8s.io/kube-apiserver:v1.30.2
[config/images] Pulled registry.k8s.io/kube-controller-manager:v1.30.2
[config/images] Pulled registry.k8s.io/kube-scheduler:v1.30.2
[config/images] Pulled registry.k8s.io/kube-proxy:v1.30.2
[config/images] Pulled registry.k8s.io/coredns/coredns:v1.11.1
[config/images] Pulled registry.k8s.io/pause:3.9
[config/images] Pulled registry.k8s.io/etcd:3.5.12-0
方式二:使用阿里云镜像仓库(国内网络更快):
bash
[root@master30 ~]# kubeadm config images pull \
--kubernetes-version=v1.30.2 \
--image-repository registry.aliyuncs.com/google_containers
7.2 Worker 节点预下载必要镜像
Worker 节点只需 kube-proxy 和 pause 镜像:
bash
[root@worker31 ~]# nerdctl pull registry.k8s.io/kube-proxy:v1.30.2
[root@worker31 ~]# nerdctl pull registry.k8s.io/pause:3.9
[root@worker32 ~]# nerdctl pull registry.k8s.io/kube-proxy:v1.30.2
[root@worker32 ~]# nerdctl pull registry.k8s.io/pause:3.9
7.3 初始化集群
bash
[root@master30 ~]# kubeadm init \
--kubernetes-version=v1.30.2 \
--pod-network-cidr=10.224.0.0/16
参数说明:
| 参数 | 说明 |
|---|---|
--kubernetes-version |
指定 Kubernetes 版本 |
--pod-network-cidr |
指定 Pod 网络地址范围,必须与网络插件配置一致 |
--image-repository |
(可选)指定镜像仓库,默认 registry.k8s.io |
--apiserver-advertise-address |
(可选)指定 API Server 通信 IP,默认自动选择 |
7.4 初始化过程详解
初始化过程包含以下关键阶段,每个阶段都有明确的职责:
[preflight]--- 执行预检查- 检查系统版本、内核参数、swap 是否关闭
- 检查端口是否被占用(6443、2379、2380、10250 等)
- 检查容器运行时是否可用
[certs]--- 生成证书- CA 证书(集群根证书)
- API Server 证书
- kubelet 客户端证书
- etcd 相关证书
- 证书有效期默认为 1 年
[kubeconfig]--- 生成 kubeconfig 配置文件- admin.conf(管理员用)
- kubelet.conf(kubelet 用)
- controller-manager.conf、scheduler.conf
[etcd]--- 部署 etcd 静态 Pod- etcd 作为集群数据库,存储所有集群状态数据
[control-plane]--- 部署控制平面组件- kube-apiserver、kube-controller-manager、kube-scheduler
- 以静态 Pod 形式运行在
/etc/kubernetes/manifests/目录下
[addons]--- 部署 CoreDNS 和 kube-proxy- CoreDNS 为集群提供内部 DNS 解析
- kube-proxy 为 Service 提供网络代理
7.5 初始化成功输出
bash
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc \
--discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd
7.6 配置 kubectl 凭据
方式一:默认位置(推荐):
bash
[root@master30 ~]# mkdir -p $HOME/.kube
[root@master30 ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master30 ~]# chown $(id -u):$(id -g) $HOME/.kube/config
方式二:环境变量:
bash
[root@master30 ~]# export KUBECONFIG=/etc/kubernetes/admin.conf
方式三:命令行参数:
bash
[root@master30 ~]# kubectl get nodes --kubeconfig /etc/kubernetes/admin.conf
八、部署网络插件(Calico)
8.1 为什么需要网络插件?
Kubernetes 集群初始化后,CoreDNS 等 Pod 会处于 Pending 状态,节点状态为 NotReady。这是因为缺少网络插件(CNI),Pod 无法获得 IP 地址。
CNI(Container Network Interface) 是 Kubernetes 的网络标准,所有网络插件都遵循此规范。可以这样理解:CNI 是"网络插座的统一规格",Calico、Flannel 等是"不同品牌的插头",都遵循同一个标准,所以可以即插即用。
Calico 是 Kubernetes 最流行的网络插件之一,支持网络策略(Network Policy),性能优秀,适合生产环境。它基于 BGP 协议实现跨节点 Pod 通信,无需 NAT,性能损耗小。
8.2 下载 Calico 配置
bash
[root@master30 ~]# wget --no-check-certificate \
https://raw.githubusercontent.com/projectcalico/calico/v3.30.7/manifests/calico.yaml
8.3 修改 Pod 网络 CIDR
确认集群 Pod 网络范围:
bash
[root@master30 ~]# kubectl get cm -n kube-system kubeadm-config -o yaml | grep podSubnet
podSubnet: 10.224.0.0/16
修改 calico.yaml ,确保 CALICO_IPV4POOL_CIDR 与集群配置一致:
bash
[root@master30 ~]# sed -i "s|# - name: CALICO_IPV4POOL_CIDR|- name: CALICO_IPV4POOL_CIDR|g" calico.yaml
[root@master30 ~]# sed -i "s|# value: \"192.*| value: \"10.224.0.0/16\"|g" calico.yaml
8.4 所有节点下载 Calico 镜像
bash
[root@master30 ~]# grep image: calico.yaml | uniq
image: docker.io/calico/cni:v3.30.7
image: docker.io/calico/node:v3.30.7
image: docker.io/calico/kube-controllers:v3.30.7
# 所有节点执行
[root@master30 ~]# nerdctl pull docker.io/calico/cni:v3.30.7
[root@master30 ~]# nerdctl pull docker.io/calico/node:v3.30.7
[root@master30 ~]# nerdctl pull docker.io/calico/kube-controllers:v3.30.7
8.5 部署 Calico
bash
[root@master30 ~]# kubectl apply -f calico.yaml
8.6 验证网络插件部署
bash
[root@master30 ~]# kubectl get pods -n kube-system -l k8s-app=calico-node
NAME READY STATUS RESTARTS AGE
calico-node-vc9v6 1/1 Running 0 2m
九、Worker 节点加入集群
9.1 获取加入命令
如果忘记保存初始化输出,可通过以下命令重新生成:
bash
[root@master30 ~]# kubeadm token create --print-join-command
kubeadm join 10.1.8.30:6443 --token dzpuca.8lqxqqydwskroabx --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd
9.2 Worker 节点加入
bash
# Worker31
[root@worker31 ~]# kubeadm join 10.1.8.30:6443 \
--token mi0yt8.1tzza4q64dr8y3pc \
--discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[kubelet-start] Writing kubelet configuration...
[kubelet-start] Starting the kubelet
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
# Worker32 同理
十、验证集群
10.1 查看集群信息
bash
[root@master30 ~]# kubectl cluster-info
Kubernetes control plane is running at https://10.1.8.30:6443
CoreDNS is running at https://10.1.8.30:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
10.2 查看版本
bash
[root@master30 ~]# kubectl version
Client Version: v1.30.2
Server Version: v1.30.2
10.3 查看节点状态
bash
[root@master30 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master30.whisky.cloud Ready control-plane 9h v1.30.2
worker31.whisky.cloud Ready <none> 8h v1.30.2
worker32.whisky.cloud Ready <none> 8h v1.30.2
节点状态为 Ready 的前提条件:
- ✅ 网络插件部署成功(Calico/Flannel)
- ✅ kubelet 服务正常运行
- ✅ swap 已关闭
- ✅ 内核参数正确
10.4 查看 Pod 状态
bash
[root@master30 ~]# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-7cb4fd5784-jx2xl 1/1 Running 0 11m
kube-system calico-node-4b6s8 1/1 Running 0 11m
kube-system calico-node-bsr7v 1/1 Running 0 11m
kube-system calico-node-v8jdn 1/1 Running 0 11m
kube-system coredns-66f779496c-4j88h 1/1 Running 0 13m
kube-system coredns-66f779496c-fnb8m 1/1 Running 0 13m
kube-system etcd-master30.whisky.cloud 1/1 Running 0 13m
kube-system kube-apiserver-master30.whisky.cloud 1/1 Running 0 13m
kube-system kube-controller-manager-master30.whisky.cloud 1/1 Running 0 13m
kube-system kube-proxy-27vl2 1/1 Running 0 11m
kube-system kube-proxy-npv9h 1/1 Running 0 11m
kube-system kube-proxy-q2qrs 1/1 Running 0 11m
kube-system kube-scheduler-master30.whisky.cloud 1/1 Running 0 13m
10.5 部署测试应用验证集群功能
bash
[root@master30 ~]# kubectl create deployment nginx-test --image=nginx --replicas=2
deployment.apps/nginx-test created
[root@master30 ~]# kubectl expose deployment nginx-test --port=80 --type=NodePort
service/nginx-test exposed
[root@master30 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-test-xxxxxxxxx-xxxxx 1/1 Running 0 30s 10.224.113.xxx worker31
nginx-test-xxxxxxxxx-xxxxx 1/1 Running 0 30s 10.224.114.xxx worker32
[root@master30 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-test NodePort 10.96.xxx.xxx <none> 80:30080/TCP 10s
# 测试访问(在集群内任一节点执行)
[root@master30 ~]# curl http://10.224.113.xxx:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</html>
十一、总结与知识点一览表
11.1 部署流程速查表
| 阶段 | 关键操作 | 关键命令 |
|---|---|---|
| 环境准备 | 配置仓库、安装软件、关闭 swap | apt update, swapoff -a |
| 内核配置 | 加载模块、配置 sysctl | modprobe, sysctl -p |
| 容器运行时 | 安装 containerd、配置加速 | crictl config, containerd config default |
| 安装 K8s | 安装 kubeadm/kubelet/kubectl | apt install kubeadm |
| 克隆节点 | 克隆 VM、配置 IP/主机名 | hostnamectl, netplan apply |
| 集群初始化 | kubeadm init | kubeadm init --pod-network-cidr |
| 网络插件 | 部署 Calico | kubectl apply -f calico.yaml |
| 加入节点 | worker 加入集群 | kubeadm join |
11.2 核心配置汇总
| 组件 | 配置文件 | 关键参数 |
|---|---|---|
| containerd | /etc/containerd/config.toml |
SystemdCgroup=true, sandbox_image |
| kubelet | /var/lib/kubelet/config.yaml |
由 kubeadm 自动生成 |
| Calico | calico.yaml |
CALICO_IPV4POOL_CIDR=10.224.0.0/16 |
| kubectl | ~/.kube/config |
从 admin.conf 复制 |
11.3 常见错误排查
| 错误 | 原因 | 解决方法 |
|---|---|---|
[ERROR Swap] |
swap 未关闭 | swapoff -a 并注释 fstab |
[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables] |
内核参数未配置 | sysctl -p /etc/sysctl.d/k8s.conf |
crictl 连接失败 |
runtime-endpoint 未配置 | crictl config runtime-endpoint unix:///... |
kubelet 无法启动 |
命名空间配置错误 | 确认 CONTAINERD_NAMESPACE=k8s.io |
kubectl get nodes 显示 NotReady |
网络插件未部署 | 部署 Calico 并等待 Pod 就绪 |
failed to pull image |
镜像拉取超时或命名空间错误 | 配置镜像加速,检查命名空间 |
| 节点加入超时 | token 过期或网络不通 | 重新生成 token,检查网络连通性 |
11.4 节点状态说明
| 状态 | 含义 | 可能原因 |
|---|---|---|
| Ready | 节点正常 | 所有组件健康 |
| NotReady | 节点不可用 | kubelet 未运行、网络插件未部署 |
| Unknown | 状态未知 | 网络中断、节点宕机 |
| SchedulingDisabled | 调度禁用 | 节点被 cordon(维护模式) |
11.5 扩容与后续步骤
集群部署完成后,你可以:
- 增加 Worker 节点:重复"克隆节点 → 配置 IP → kubeadm join"流程
- 部署应用:通过 Deployment 部署 Nginx 等测试应用
- 配置存储:部署 CSI 存储插件(如 NFS、Ceph)
- 配置 Ingress:部署 Ingress Controller(如 Nginx Ingress)
- 启用 Dashboard:部署 Kubernetes Dashboard 可视化界面
- 配置监控:部署 Prometheus + Grafana 监控体系
下一期预告:Kubernetes 集群基础管理------节点管理、Namespace 隔离、上下文切换、多集群配置等日常运维操作。
--- Compiled and Authored by Whisky --- June 23 rd, 2026