在这个时代,没有人能忽视 Kubernetes(K8s)。现在就开始搭建 K8s 的基础环境,后续也可以看看基于 K8s 能否玩出更多花样。
本次准备了三台 Ubuntu 系统,一台作为 master,两台作为 worker,全部基于 PVE 虚拟平台搭建。一切准备就绪后,即可开始操作。
---
1. 重置 Machine ID
Machine ID 是 Linux 系统的全局唯一标识符。在 PVE 上通过克隆得到三台相同的 Ubuntu 机器,但由于克隆的原因,这三台机器的 Machine-ID 是一样的。K8s 中的 CNI 插件正是通过 Machine-ID 来区分不同节点的,ID 一致会导致 K8s 认为它们是一个节点,从而造成路由表混乱、形成黑洞,Pod 跨节点通信失败。
bash
删除系统生成的 ID,避免出现一致
sudo rm -f /etc/machine-id /var/lib/dbus/machine-id
生成全新的 ID
sudo dbus-uuidgen --ensure=/etc/machine-id
文件初始化
sudo dbus-uuidgen --ensure
查看 ID,确保所有节点 ID 不一致
cat /etc/machine-id2. 主机名与 Hosts 映射
主机名的设置原理与 Machine-ID 类似,目的是防止 K8s 集群将重复的主机名视为同一个节点,避免后期报错。
/etc/hosts 的静态映射可以让所有节点通过主机名解析到对应的 IP 地址,无需依赖 DNS 服务,防止 DNS 问题导致整个集群调度异常甚至瘫痪。
bash
在 master 上设置
sudo hostnamectl set-hostname master-01
在 worker-01 上设置
sudo hostnamectl set-hostname worker-01
在 worker-02 上设置
sudo hostnamectl set-hostname worker-02配置静态 Hosts 映射(每个节点都需要操作一次):
bash
配置对应的静态映射
cat <<EOF | sudo tee -a /etc/hosts
<master IP> master-01
<worker-01 IP> worker-01
<worker-02 IP> worker-02
EOF


完成后可通过 ping 主机名进行简单验证,应该都能通过主机名解析。
3. 关闭 Swap
Kubernetes 要求关闭 Swap,主要目的是保证资源管理的确定性、性能和稳定性。关闭操作需在所有节点上执行。
bash
所有节点执行
sudo swapoff -a
永久关闭 Swap,注释掉 Swap 行,防止重启后恢复
sudo sed -i '/swap/s/^/#/' /etc/fstab4. 加载内核模块与设置网络参数
overlay:Kubernetes 容器运行时需要 overlay 来高效管理容器镜像层和容器可写层,没有 overlay 则容器无法正常启动和运行。
br_netfilter:让 Linux 桥接流量能够通过 Netfilter 规则,否则桥接流量会绕过,导致网络策略、Service 转发等失效。
bash
声明在系统启动时自动加载的内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
加载 overlay 与 br_netfilter 模块
sudo modprobe overlay
sudo modprobe br_netfilter
配置网络参数:
bash
设置网络参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
生效配置
sudo sysctl --system
5. 安装 Containerd
K8s 在 1.24 版本之前原生支持 Docker,当时的启动流程为:
Kubelet → dockershim → dockerd → containerd → runc → 容器进程
其中 dockershim 是 K8s 为兼容 Docker 而写的临时适配器,dockerd 是 Docker 的守护进程,功能繁多。这两层可以省略,以减少进程数和报错可能。
从 1.24 版本开始,K8s 改用 Containerd,流程简化为:
Kubelet → containerd → runc → 容器进程
这一改动使 K8s 性能更好、故障点更少。
bash
所有节点安装 Containerd 及依赖
sudo apt-get update
sudo apt-get install -y containerd apt-transport-https ca-certificates curl gpg
生成默认配置文件
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
启用 SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
替换 sandbox 镜像为阿里云源
sudo sed -i "s|registry.k8s.io/pause|registry.aliyuncs.com/google_containers/pause|g" /etc/containerd/config.toml
重启 containerd 并设置开机自启
sudo systemctl restart containerd
sudo systemctl enable containerd验证:


bash
验证 containerd 是否正常运行
sudo systemctl status containerd
验证 SystemdCgroup 是否开启
grep "SystemdCgroup" /etc/containerd/config.toml
验证是否已更换为阿里云源
containerd config dump | grep sandbox
6. 安装 kubeadm / kubelet / kubectl
- kubeadm:集群的安装器和升级器,不负责实际运行业务 Pod。
- kubelet:每个节点的管家,负责在本节点上管理 Pod 和容器。
- kubectl:用户的遥控器,用于与集群交互。
可以这样理解:用 kubeadm 搭建集群,靠 kubelet 驱动每个节点,用 kubectl 指挥整个集群。
bash
所有节点都需要执行以下操作
导入阿里云 Kubernetes 仓库的 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/Release.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
添加阿里云 Kubernetes 仓库
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/ /" \
| sudo tee /etc/apt/sources.list.d/kubernetes.list
安装三大组件
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
锁定版本,防止系统自动升级导致不兼容
sudo apt-mark hold kubelet kubeadm kubectl
启动 kubelet
sudo systemctl enable --now kubelet
验证
kubeadm version
kubelet --version
kubectl version --client7. 初始化并运行 K8s(在 master-01 上)
首先对 master-01 进行初始化,生成证书和配置文件,以便后续节点可以加入集群。
bash
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.30.14


参数说明:
- pod-network-cidr=10.244.0.0/16:Pod 网络的 IP 地址段(默认)。
- image-repository:指定为阿里云镜像源。
- kubernetes-version:指定版本。
初始化完成后,需要记录 Token 与 Hash 值(后续加入集群时需要)。
接下来配置 kubectl,使其通过 kubeconfig 文件获取 API Server 的地址和认证凭据:
bash
在 master 上配置
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
验证并查看当前节点(未部署网络插件前状态为 NotReady)
kubectl get nodes
查看 Pod 状态
kubectl get pods -n kube-system8. 加入集群(在 worker 节点上)
前面记录的 Token 和 Hash 在这里使用。注意 Token 有效期为 24 小时,过期后需重新生成。
bash
如需重新申请 Token(在 master 上执行)
sudo kubeadm token create --print-join-command
在所有 worker 上执行
sudo kubeadm join <master_IP:6443> \
--token <token值> \
--discovery-token-ca-cert-hash sha256:<hash值>执行后可在 master 上验证节点是否成功加入。
9. 部署网络插件
Kubernetes 对集群网络有三个硬性要求:
- Pod→Pod:每个 Pod 拥有真实 IP,不同节点上的 Pod 可通过 IP 直接互相访问。
- Pod→Service:Pod 可通过 Service 的 ClusterIP 或 DNS 名称访问后端 Pod。
- External→Service:外部客户端可通过 NodePort、LoadBalancer 或 Ingress 访问集群内的 Service。
常见的网络插件:
- Flannel(适合学习/小型环境):默认使用 VxLAN 在节点间构建叠加网络,每个节点分配一个子网。
- Calico(生产首选):采用三层路由,Pod 子网通过 BGP 广播到其他节点,由节点路由器或 BGP 客户端负责转发。
- Cilium(高性能):利用 Linux 内核的 eBPF 技术,在 socket 层或网卡驱动层直接处理数据包,性能极强,但对内核版本要求较高(≥5.1),配置复杂。
本次选择生产环境中使用最多的 Calico。Calico 在每个节点上运行以下组件:
- Felix:每个节点上的“大脑”,编程路由和 iptables 规则。
- BIRD:BGP 客户端,将节点上 Pod 网段宣告给其他节点。
- calico-node:以 DaemonSet 方式运行在每个节点上的 Pod,包含 Felix 和 BIRD。
- calico-kube-controllers:监听 K8s API 中的 NetworkPolicy 变更,并同步到 Calico。
bash
下载 calico.yaml
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml
启用环境变量
sed -i 's|# - name: CALICO_IPV4POOL_CIDR|- name: CALICO_IPV4POOL_CIDR|' calico.yaml
修改 Calico 默认网段(192.168.0.0)为 kubeadm init 指定的 10.244.0.0
sed -i 's|# value: "192.168.0.0/16"| value: "10.244.0.0/16"|' calico.yaml
替换为国内镜像源
sed -i 's|docker.io|docker.m.daocloud.io|g' calico.yaml
部署
kubectl apply -f calico.yaml
等待 Calico 部署完成
kubectl get pods -n kube-system -l k8s-app=calico-node -w
查看节点状态(应变为 Ready)
kubectl get nodes
至此,K8s 的基础部署已经完成,后续可以在该集群上继续实现更多功能。
