Debian 安装 Kubernetes 集群指南

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_netfilteroverlay 模块是 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 国内源

阅读更多

Ghost 邮箱订阅功能在中国大陆的困境:Mailgun 注册受阻实录

Ghost 邮箱订阅功能在中国大陆的困境:Mailgun 注册受阻实录

本文记录了 Ghost 博客邮箱订阅功能因 Mailgun 在中国大陆无法注册而被迫关闭的完整过程,包括注册尝试、工单沟通及最终应对方案。 一、背景:Ghost 与 Mailgun Ghost 博客平台内置了邮箱订阅(Newsletter)功能,读者可以通过输入邮箱地址订阅博客更新,Ghost 会自动将新文章以邮件形式推送给订阅者。这一功能的邮件发送能力依赖于第三方邮件服务——Mailgun。 Ghost 官方推荐使用 Mailgun 作为邮件传输层,配置方式如下: 配置项 说明 示例值 mail.from 发件人地址 newsletter@yourdomain.com mail.transport 传输协议 SMTP mail.options.host SMTP 主机 smtp.mailgun.org mail.options.port

By 菱角
Kubernetes 全栈监控体系:kube-prometheus-stack + 7 大 Exporter 生产实践

Kubernetes 全栈监控体系:kube-prometheus-stack + 7 大 Exporter 生产实践

本文基于 kube-prometheus-stack Helm Chart 在 Kubernetes 上构建完整监控体系的实战,覆盖 Prometheus、Grafana、Alertmanager 及 7 个专用 Exporter 的部署与配置。 一、监控体系全景架构 整套监控以 kube-prometheus-stack 为核心,通过 ServiceMonitor CRD 自动发现并采集 7 大数据源,配合 Alertmanager 分级告警与 Grafana 可视化: 组件 版本 作用 Prometheus v2.45.0 指标采集与存储,10 天数据保留 Alertmanager v0.25.0 告警路由与邮件推送,2 副本 HA

By 菱角
基于 Docker Compose 部署 Apache APISIX:全栈 API 网关实践

基于 Docker Compose 部署 Apache APISIX:全栈 API 网关实践

本文基于 APISIX 3.9.1 + Dashboard 3.0.1 + etcd 3.5.15 + Prometheus + Grafana 的生产级 Docker Compose 部署实践。 一、整体架构 本次部署采用 Docker Compose 编排五大组件,形成从配置管理到流量监控的完整闭环: 组件 版本 作用 端口 APISIX 3.9.1-debian API 网关核心,路由转发、插件执行 9080/9443 Dashboard 3.0.1-alpine 可视化配置管理界面 9000 etcd 3.5.15

By 菱角
在 Kubernetes 上部署 Apache Flink:生产实战指南

在 Kubernetes 上部署 Apache Flink:生产实战指南

本文基于 Flink 1.15.2 + Kubernetes 的生产环境部署实践。 一、架构概览 Flink 在 Kubernetes 上采用经典的 JobManager + TaskManager 主从架构,JobManager 负责作业调度与协调,TaskManager 承载实际的计算任务。 资源分配一览 组件 作用 副本数 Task Slots 内存配置 JobManager 作业调度、Checkpoint 管理、协调 1 — 8G TaskManager 执行计算任务 3 80/Pod 48G 总计 — 4 240 — 二、Namespace 隔离 为 Flink 创建独立 Namespace,

By 菱角