基于Containerd搭建 K8s

一、container

本实验环境是使用 Container安装 K8s

Docker 是容器运行时(Container Runtime)的一种,而 "Container 安装 K8s" 本质是指 "选择非 Docker 的容器运行时(如 containerd、CRI-O)部署 K8s"------ 两者的核心差异是 K8s 底层依赖的容器运行时不同,进而导致部署方式、兼容性、运维逻辑等层面的区别。

以下是维度化对比:

对比维度 Docker(作为 K8s 容器运行时) 非 Docker 容器运行时(containerd/CRI-O)
K8s 官方支持 K8s 1.24 + 已移除对 Docker 的直接支持(dockershim 废弃),需通过 cri-dockerd 适配 原生支持 K8s 的 CRI(容器运行时接口),是 K8s 官方推荐方案
资源开销 额外的 Docker Daemon 进程占用 CPU / 内存,资源消耗更高 仅运行核心运行时进程,资源占用更低(约减少 10-20%)
部署复杂度 需额外安装 cri-dockerd 适配 CRI,步骤更多 一键部署(如 kubeadm 默认使用 containerd),步骤更简单
运维成本 需同时维护 Docker 和 K8s,日志 / 故障排查需跨两层 直接对接 K8s 的 crictl 工具,运维链路更短
生态兼容性 兼容所有 Docker 镜像(OCI 标准),但部分 Docker 特有功能(如 Docker Compose)无法直接在 K8s 中使用 完全兼容 OCI 镜像标准,无额外兼容问题
社区趋势 逐步被淘汰,仅存量环境使用 主流方案(containerd 是 Docker 官方拆分的核心组件,CRI-O 为红帽主导)

二、环境初始化(所有节点执行)

步骤 1:系统基础配置

1.1 关闭防火墙 & SELinux & 交换分区

bash 复制代码
# 关闭ufw防火墙(Ubuntu默认防火墙)
ufw disable
# 验证防火墙状态(返回inactive则成功)
ufw status
# 临时关闭交换分区(K8s要求禁用swap)
swapoff -a
# 永久关闭swap(注释swap分区行)
sed -i '/swap/s/^/#/' /etc/fstab
# 验证swap(返回0则成功)
free -h | grep Swap

1.2配置主机名&域名解析

bash 复制代码
# 按节点执行(示例为k8s-master,node节点替换对应主机名/IP)
# 192.168.198.198执行
hostnamectl set-hostname k8s-master
# 192.168.198.199执行
hostnamectl set-hostname k8s-node01
# 192.168.198.200执行
hostnamectl set-hostname k8s-node02

# 所有节点配置hosts(避免DNS解析问题)
cat >> /etc/hosts << EOF
192.168.198.198 k8s-master
192.168.198.199 k8s-node01
192.168.198.200 k8s-node02
192.168.198.201 k8s-vip  # VIP地址
EOF

# 验证hosts
ping -c 2 k8s-master

1.3 配置内核参数(适配 K8s 网络)

bash 复制代码
# 加载内核模块
cat > /etc/modules-load.d/k8s.conf << EOF
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter

# 设置内核参数
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
EOF
# 生效参数
sysctl --system
# 验证参数(返回1则成功)
sysctl net.bridge.bridge-nf-call-iptables

内核模块:

  • overlay:支持 overlay 文件系统,这是容器镜像分层存储的基础(Docker/Containerd 使用)

  • br_netfilter:让 Linux 网桥能够处理 iptables 规则,这是 Kubernetes Service 网络(kube-proxy)正常工作的前提

每个参数的作用

参数 作用 必要性
net.bridge.bridge-nf-call-iptables = 1 让网桥流量经过 iptables 处理 K8s必需:Service 的流量转发依赖此功能
net.bridge.bridge-nf-call-ip6tables = 1 IPv6 版本的网桥流量处理 支持 IPv6 网络
net.ipv4.ip_forward = 1 启用 IP 转发(路由功能) 必需:Pod 跨节点通信需要路由

1.4配置时间同步

bash 复制代码
# 安装chrony
apt update && apt install -y chrony
# 启动并开机自启
systemctl enable --now chronyd
# 验证时间同步
chronyc sources -v

如果此时date出来的时间是美国时间需要更改下时区(默认为美国时间)

bash 复制代码
root@ubuntu:~# # 查看当前时区
root@ubuntu:~# timedatectl
               Local time: Mon 2025-12-08 04:59:01 PST     
           Universal time: Mon 2025-12-08 12:59:01 UTC     
                 RTC time: Mon 2025-12-08 12:59:01         
                Time zone: America/Los_Angeles (PST, -0800)
System clock synchronized: yes                             
              NTP service: active                          
          RTC in local TZ: no                              
root@ubuntu:~# 
root@ubuntu:~# # 设置时区为上海(北京时间)
root@ubuntu:~# sudo timedatectl set-timezone Asia/Shanghai
root@ubuntu:~# date
Mon 08 Dec 2025 08:59:02 PM CST

步骤2:安装 K8s 组件(所有节点)

这里通过之前写的脚本进行安装,也可通过二进制或者sealos直接快速安装。这里建议弄个快照。

脚本:

bash 复制代码
#!/bin/bash

# 清理现有配置
sudo rm -f /etc/apt/keyrings/kubernetes-archive-keyring.gpg
sudo rm -f /etc/apt/sources.list.d/kubernetes.list

# 方法1:使用 apt-key 添加
echo "尝试方法1: 使用 apt-key 添加 GPG 密钥..."
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - || {
    echo "方法1失败,尝试方法2..."
    
    # 方法2:从 keyserver 添加
    sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B53DC80D13EDEF05 || {
        echo "方法2失败,使用方法3: 临时禁用验证..."
        
        # 方法3:禁用验证
        echo "deb [trusted=yes] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
    }
}

# 如果方法1或2成功,使用验证的源
if [ ! -f /etc/apt/sources.list.d/kubernetes.list ]; then
    echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
fi

# 更新源
sudo apt update

# 安装 Kubernetes
sudo apt install -y kubelet=1.24.0-00 kubeadm=1.24.0-00 kubectl=1.24.0-00

# 锁定版本
sudo apt-mark hold kubelet kubeadm kubectl

# 验证安装
kubelet --version
kubeadm version

三、安装k8s集群

3.1 停止并禁用 Docker(所有节点)

bash 复制代码
# 停止 Docker 服务
sudo systemctl stop docker
sudo systemctl disable docker

# 检查 Docker 状态确认已停止
sudo systemctl status docker

3.2 配置 Containerd(所有节点)

bash 复制代码
# 1. 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# 2. 修改配置使用国内镜像和 systemd cgroup
sudo sed -i 's|SystemdCgroup = false|SystemdCgroup = true|g' /etc/containerd/config.toml
sudo sed -i 's|sandbox_image = ".*"|sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7"|g' /etc/containerd/config.toml

# 3. 配置国内镜像仓库镜像
sudo tee -a /etc/containerd/config.toml << 'EOF'

# 添加国内镜像仓库配置
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = ["https://registry.cn-hangzhou.aliyuncs.com", "https://docker.mirrors.ustc.edu.cn"]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
    endpoint = ["https://registry.cn-hangzhou.aliyuncs.com/google_containers/"]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
    endpoint = ["https://registry.cn-hangzhou.aliyuncs.com/google_containers/"]
EOF

# 4. 重启并启用 containerd
sudo systemctl daemon-reload
sudo systemctl restart containerd
sudo systemctl enable containerd

# 5. 验证 containerd 状态
sudo systemctl status containerd

注意:如果这里containerd启动失败可以

bash 复制代码
# 1. 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 2. 验证集群状态
kubectl get nodes
kubectl get pods -n kube-system

# 3. 查看集群信息
kubectl cluster-info
# 修改 systemd cgroup 驱动
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 修改 sandbox 镜像
sudo sed -i 's|sandbox_image = ".*"|sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7"|g' /etc/containerd/config.toml

# 找到正确的行号添加镜像仓库配置
sudo grep -n "registry.mirrors" /etc/containerd/config.toml

# 如果不存在 registry.mirrors 配置,在正确位置添加
if ! grep -q "registry.mirrors" /etc/containerd/config.toml; then
    # 找到 [plugins."io.containerd.grpc.v1.cri".registry] 的位置
    registry_line=$(grep -n '\[plugins\."io\.containerd\.grpc\.v1\.cri"\.registry\]' /etc/containerd/config.toml | cut -d: -f1)
    
    if [ ! -z "$registry_line" ]; then
        # 在下一行插入镜像仓库配置
        sudo sed -i "$((registry_line+1)) i[plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors]" /etc/containerd/config.toml
        sudo sed -i "$((registry_line+2)) i\ \ [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.io\"]" /etc/containerd/config.toml
        sudo sed -i "$((registry_line+3)) i\ \ \ \ endpoint = [\"https://registry.cn-hangzhou.aliyuncs.com\", \"https://docker.mirrors.ustc.edu.cn\"]" /etc/containerd/config.toml
        sudo sed -i "$((registry_line+4)) i\ \ [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"registry.k8s.io\"]" /etc/containerd/config.toml
        sudo sed -i "$((registry_line+5)) i\ \ \ \ endpoint = [\"https://registry.cn-hangzhou.aliyuncs.com/google_containers/\"]" /etc/containerd/config.toml
        sudo sed -i "$((registry_line+6)) i\ \ [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"k8s.gcr.io\"]" /etc/containerd/config.toml
        sudo sed -i "$((registry_line+7)) i\ \ \ \ endpoint = [\"https://registry.cn-hangzhou.aliyuncs.com/google_containers/\"]" /etc/containerd/config.toml
    fi
fi

# 验证配置文件语法
sudo containerd config dump > /dev/null && echo "✅ 配置文件语法正确" || echo "❌ 配置文件有语法错误"

# 重启 containerd
sudo systemctl daemon-reload
sudo systemctl restart containerd
sudo systemctl status containerd

# 验证 containerd 是否正常运行
sudo ctr version

3.3 预拉取 K8s 镜像(所有节点)

bash 复制代码
# 1. 查看 kubeadm 需要的镜像列表
sudo kubeadm config images list --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

# 2. 手动拉取所有必要镜像
images=(
    registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.24.0
    registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0
    registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.24.0
    registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.24.0
    registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7
    registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.3-0
    registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6
)

# 3. 使用 ctr 命令拉取镜像(containerd 的工具)
for image in "${images[@]}"; do
    echo "正在拉取镜像: $image"
    sudo ctr -n k8s.io images pull $image
    if [ $? -eq 0 ]; then
        echo "成功拉取: $image"
    else
        echo "拉取失败: $image"
    fi
done

# 4. 验证镜像是否拉取成功
echo "=== 验证已拉取的镜像 ==="
sudo ctr -n k8s.io images list | grep -E "(k8s|pause|etcd|coredns)"

3.4 初始化master节点

bash 复制代码
# 1. 重置之前的配置(如果是重新安装)
sudo kubeadm reset -f
sudo rm -rf /etc/kubernetes/ /var/lib/etcd/ ~/.kube/

# 2. 初始化集群
sudo kubeadm init \
  --apiserver-advertise-address=192.168.198.198 \
  --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
  --kubernetes-version=v1.24.0 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16 \
  --cri-socket=unix:///run/containerd/containerd.sock \
  --ignore-preflight-errors=all

# 3. 如果初始化成功,会显示以下信息,请保存好 join 命令:
# kubeadm join 192.168.198.198:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx

3.5配置kubectl

bash 复制代码
# 1. 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 2. 验证集群状态
kubectl get nodes
kubectl get pods -n kube-system

# 3. 查看集群信息
kubectl cluster-info

3.6安装calico网络插件

这里我是用的之前的修改版本,可以在网上找一下

相关推荐
Joren的学习记录2 小时前
【Linux运维进阶知识】Nginx负载均衡
linux·运维·nginx
阿里云云原生3 小时前
祝贺东航首飞全球最长单程航线!通义千问和 AI 网关助力推出首个行程规划 Agent
云原生
Jtti3 小时前
服务器防御SYN Flood攻击的方法
运维·服务器
2501_941982053 小时前
RPA 的跨平台部署与统一自动化策略
运维·自动化·rpa
b***25113 小时前
电池自动分选机:精密分选保障新能源产业质量核心
运维·自动化·制造
数数科技的数据干货3 小时前
游戏流失分析:一套经实战检验的「流程化操作指南」
大数据·运维·人工智能·游戏
腾讯云中间件3 小时前
Kafka 集群上云新突破:腾讯云 CKafka 联邦迁移方案
云原生·kafka·消息队列
蒟蒻要翻身4 小时前
在同一局域网内共享打印机设置指南
运维
华无丽言4 小时前
如何解决 413 Request Entity Too Large ?
nginx
chem41114 小时前
魔百盒 私有网盘seafile搭建
linux·运维·网络