Debian 安装 Kubernetes 集群指南
本文介绍如何在 Debian 11 (Bullseye) 上从零部署 Kubernetes v1.25.4 集群,涵盖镜像源配置、系统调优、容器运行时安装、K8s 组件部署、集群初始化与网络插件配置,以及 NFS 存储、资源回收策略和 TLS 证书更新等运维操作。
一、设置镜像源
Debian 默认可能使用 CD-ROM 源,国内环境下建议替换为阿里云镜像源,加速软件包下载。
首先注释掉 CD-ROM 源:
sed -ri 's/^deb\scdrom:\[Debian.*/#&/' /etc/apt/sources.list
添加阿里云镜像源:
cat <<EOF | tee -a /etc/apt/sources.list
deb http://security.debian.org/debian-security bullseye-security main contrib
deb-src http://security.debian.org/debian-security bullseye-security main contrib
deb https://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb https://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src https://mirrors.aliyun.com/debian-security/ bullseye-security main
deb https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
EOF
提示:此步骤需要在所有节点上执行。
二、系统配置
K8s 对系统环境有严格要求:必须关闭 Swap、确保网络桥接流量可被 iptables 处理。
2.1 设置时区
timedatectl set-timezone Asia/Shanghai
2.2 关闭 Swap
K8s 要求 Swap 必须关闭,否则 kubelet 无法正常启动:
swapoff -a
free # 确认 Swap 行全部为 0
sed -ri 's/.*swap.*/# &/' /etc/fstab # 持久化关闭
2.3 关闭防火墙
service iptables stop
systemctl stop firewalld.service
systemctl disable firewalld.service
ufw disable
iptables -F
2.4 配置内核网络参数
将桥接的 IPv4 流量转发到 iptables 链,这是 K8s 网络插件正常工作的前提:
# 加载内核模块
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 配置 sysctl 参数(重启后持久化)
cat <<EOF | 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
# 立即应用
sysctl --system
说明:
br_netfilter和overlay模块是 Calico 等 CNI 插件必需的内核模块。
三、容器运行时安装
K8s 支持两种容器运行时方案,任选其一即可:
| 方案 | 文件 | 适用场景 |
|---|---|---|
| Docker + containerd | 3、docker.sh |
需要 Docker CLI 和 Docker Compose |
| 纯 containerd | 3-1、安装containerd.sh |
仅作为 K8s 运行时,更轻量 |
3.1 方案 A:安装 Docker(推荐)
适用于需要 Docker CLI 和 Docker Compose 的环境:
# 清理旧版本
apt-get remove -y --allow-change-held-packages docker docker-engine docker.io containerd runc
# 安装依赖
apt-get update
apt-get install -y ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥和仓库
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装指定版本
apt-get update
VERSION_STRING=5:20.10.21~3-0~debian-bullseye
apt-get install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-compose-plugin
数据目录迁移
默认 /var/lib/docker 可能空间不足,迁移到 /home/docker/lib:
mkdir -p /home/docker/data /home/docker/lib /home/docker/etc /home/docker/compose
systemctl stop docker
mv /var/lib/docker /home/docker/lib
ln -s /home/docker/lib/docker /var/lib/docker
systemctl start docker
Docker 配置
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://<YOUR_MIRROR_URL>.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"insecure-registries": ["<YOUR_PRIVATE_REGISTRY_IP>"]
}
EOF
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
关键配置:
native.cgroupdriver=systemd— 必须与 K8s 的 cgroup 驱动保持一致registry-mirrors— 国内镜像加速log-opts.max-size— 防止日志撑满磁盘
3.2 方案 B:仅安装 containerd
更轻量的方案,适合纯 K8s 环境:
apt install containerd
systemctl start containerd
mkdir -p /etc/containerd/
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
systemctl enable containerd
systemctl restart containerd
注意:纯 containerd 方案还需单独安装 CNI 插件。
3.3 Containerd 详细配置
完整的 config.toml 配置关键项说明:
| 配置项 | 值 | 说明 |
|---|---|---|
SystemdCgroup |
true |
使用 systemd cgroup 驱动(与 K8s 保持一致) |
sandbox_image |
registry.aliyuncs.com/google_containers/pause:3.8 |
Pause 容器镜像(国内源) |
registry.mirrors."docker.io" |
阿里云 + 自建镜像站 | Docker Hub 加速 |
registry.mirrors."registry.k8s.io" |
阿里云 | K8s 官方镜像加速 |
数据目录迁移(containerd):
mkdir -p /home/containerd/run /home/containerd/lib
systemctl stop containerd
mv /var/lib/containerd /home/containerd/lib
ln -s /home/containerd/lib/containerd /var/lib/containerd
mv /run/containerd /home/containerd/run
ln -s /home/containerd/run/containerd /run/containerd
systemctl start containerd
配置 crictl:
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
crictl config image-endpoint unix:///run/containerd/containerd.sock
四、安装 K8s 组件
在所有节点上安装 kubelet、kubeadm、kubectl 三件套:
# 添加 K8s 阿里云镜像源
apt-get update
apt install -y apt-transport-https ca-certificates gnupg curl lsb-release
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
# 安装指定版本
apt-get update
apt-get install -y kubelet=1.25.4-00 kubeadm=1.25.4-00 kubectl=1.25.4-00
# 锁定版本,防止自动升级
apt-mark hold kubelet kubeadm kubectl
systemctl enable kubelet.service
systemctl start kubelet.service
数据目录迁移
默认 kubelet 数据在 /var/lib/kubelet,可迁移到 /home/kubelet/lib:
mkdir -p /home/kubelet/data /home/kubelet/lib
systemctl stop kubelet
tee /etc/default/kubelet <<-'EOF'
KUBELET_EXTRA_ARGS=--root-dir=/home/kubelet/lib
EOF
source /etc/default/kubelet
systemctl start kubelet
五、初始化 K8s 集群
5.1 Master 节点初始化
仅在主节点上执行:
# 预拉取镜像(使用阿里云源)
kubeadm config images pull \
--kubernetes-version=v1.25.4 \
--image-repository=registry.aliyuncs.com/google_containers
# 查看已拉取的镜像
crictl img
由于国内无法直接访问 registry.k8s.io,需要手动 tag pause 镜像:
crictl pull registry.aliyuncs.com/google_containers/pause:3.6
ctr -n k8s.io i tag registry.aliyuncs.com/google_containers/pause:3.6 registry.k8s.io/pause:3.6
crictl pull registry.aliyuncs.com/google_containers/pause:3.2
ctr -n k8s.io i tag registry.aliyuncs.com/google_containers/pause:3.2 k8s.gcr.io/pause:3.2
执行集群初始化:
kubeadm init \
--kubernetes-version=1.25.4 \
--image-repository registry.aliyuncs.com/google_containers \
--apiserver-advertise-address=<MASTER_IP> \
--service-cidr=172.27.0.0/12 \
--pod-network-cidr=172.28.0.0/16 \
--control-plane-endpoint=<MASTER_IP>
注意:请将
--apiserver-advertise-address和--control-plane-endpoint替换为你的 Master 节点实际 IP。
配置 kubectl:
export KUBECONFIG=/etc/kubernetes/admin.conf
cat <<EOF | tee -a ~/.bashrc
export KUBECONFIG=/etc/kubernetes/admin.conf
EOF
5.2 安装 Calico 网络插件
# 下载 Calico 配置
wget https://projectcalico.docs.tigera.io/manifests/calico.yaml
# 根据实际环境修改后应用
kubectl apply -f calico.yaml
提示:下载后需根据
--pod-network-cidr修改 Calico 的CALICO_IPV4POOL_CIDR配置,使其与初始化时的 Pod 网段一致。
5.3 Worker 节点加入集群
在每个 Worker 节点上执行初始化输出中的 join 命令:
kubeadm join <MASTER_IP>:6443 \
--token <YOUR_TOKEN> \
--discovery-token-ca-cert-hash sha256:<YOUR_HASH>
如果 token 过期(默认 24 小时),在 Master 上重建:
kubeadm token create --print-join-command
5.4 验证集群
# 查看节点状态
kubectl get nodes
# 查看所有 Pod
kubectl get pods -A
# 查看 kube-system Pod 详细信息
kubectl get pods -n kube-system -o wide
如果 Pod 状态异常,可查看日志排查:
# 查看 Pod 日志
kubectl -n kube-system logs etcd-<MASTER_NODE_NAME> --all-containers=true
# 查看 kubelet 启动日志
journalctl -xeu kubelet --no-pager
# 查看节点详情
kubectl describe nodes <NODE_NAME>
5.5 集群重置(如需重新初始化)
kubeadm reset
六、NFS 存储配置
为集群提供共享存储,用于备份等场景。
6.1 NFS 服务端
在指定服务器上安装:
apt-get update
apt-get install nfs-common nfs-kernel-server -y
mkdir -p /home/data/share
chmod 777 /home/data/share
cat <<EOF | tee -a /etc/exports
/home/data/share *(rw,sync,insecure,no_root_squash)
EOF
systemctl enable nfs-server
systemctl restart nfs-server
# 验证导出
showmount -e
6.2 NFS 客户端
在所有 K8s 节点上安装:
apt-get -y install nfs-common
七、资源回收策略配置
当节点磁盘空间不足时,K8s 会触发 Eviction 驱逐 Pod。默认阈值可能不适合生产环境,需要自定义。
7.1 修改 kubelet 启动参数
tee /etc/default/kubelet <<-'EOF'
KUBELET_EXTRA_ARGS=--root-dir=/home/kubelet/lib \
--eviction-soft=nodefs.available<5%,imagefs.available<5% \
--eviction-soft-grace-period=nodefs.available=2m,imagefs.available=2m \
--eviction-max-pod-grace-period=30
EOF
7.2 修改 kubelet 配置文件
tee /var/lib/kubelet/config.yaml <<-'EOF'
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
cgroupDriver: systemd
clusterDNS:
- 172.16.0.10
clusterDomain: cluster.local
kind: KubeletConfiguration
# 硬驱逐阈值
evictionHard:
nodefs.available: "5Gi"
imagefs.available: "5Gi"
# 最小回收量
evictionMinimumReclaim:
nodefs.available: "500Mi"
EOF
7.3 重启 kubelet
systemctl restart kubelet
策略说明:
- 硬驱逐 (evictionHard):磁盘可用空间 < 5Gi 时立即驱逐 Pod
- 软驱逐 (eviction-soft):磁盘可用空间 < 5% 时,给予 2 分钟优雅期后驱逐
- 最小回收 (evictionMinimumReclaim):每次驱逐至少回收 500Mi 空间
八、TLS 证书更新
K8s 集群证书默认有效期 1 年,需要定期更新。
8.1 查看证书过期时间
kubeadm certs check-expiration
8.2 更新证书
在Master 节点上执行:
# 备份
cp -r /etc/kubernetes /etc/kubernetes.old2025
# 更新所有证书
kubeadm certs renew all
8.3 重启控制面 Pod
证书更新后,需要重启使用这些证书的静态 Pod:
ns=kube-system
kubectl delete -n $ns pod etcd-<MASTER_NODE_NAME>
kubectl delete -n $ns pod kube-apiserver-<MASTER_NODE_NAME>
kubectl delete -n $ns pod kube-controller-manager-<MASTER_NODE_NAME>
kubectl delete -n $ns pod kube-scheduler-<MASTER_NODE_NAME>
8.4 更新 kubeconfig
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
8.5 重启 kubelet
systemctl restart kubelet
九、镜像仓库访问
9.1 Docker 登录阿里云镜像
docker login --username=<YOUR_USERNAME> --password=<YOUR_PASSWORD> registry.cn-beijing.aliyuncs.com
9.2 K8s 创建镜像拉取 Secret
# 默认命名空间
kubectl create secret docker-registry aliyunregsecret \
--docker-server=registry.cn-beijing.aliyuncs.com \
--docker-username=<YOUR_USERNAME> \
--docker-password=<YOUR_PASSWORD>
# 指定命名空间
kubectl create secret docker-registry aliyunregsecret \
--docker-server=registry.cn-beijing.aliyuncs.com \
--docker-username=<YOUR_USERNAME> \
--docker-password=<YOUR_PASSWORD> \
-n <NAMESPACE>
十、常见问题排查
| 问题 | 排查命令 |
|---|---|
| Pod 无法启动 | kubectl describe pod <pod-name> -n <ns> |
| kubelet 异常 | journalctl -xeu kubelet --no-pager |
| 网络不通 | kubectl get pods -n kube-system -o wide 查看 Calico 状态 |
| 镜像拉取失败 | crictl img 检查镜像;检查 containerd 镜像源配置 |
| 证书过期 | kubeadm certs check-expiration |
| 节点 NotReady | kubectl describe node <node-name> 查看 Conditions |
附录:关键参数汇总
| 参数 | 值 | 说明 |
|---|---|---|
| K8s 版本 | v1.25.4 | — |
| Debian 版本 | Bullseye (11) | — |
| 容器运行时 | Docker 20.10.21 或 containerd | 任选其一 |
| cgroup 驱动 | systemd | Docker/containerd/kubelet 保持一致 |
| Pod CIDR | 172.28.0.0/16 | 与 Calico 配置一致 |
| Service CIDR | 172.27.0.0/12 | — |
| 网络插件 | Calico | — |
| Pause 镜像 | registry.aliyuncs.com/google_containers/pause:3.8 | 国内源 |