跳转至

K8s部署

一. 解决安装环境

1. 查看三台机器不能一致的项

即UUID,MAC地址,主机名,machine-id

# 先修改主机名
hostnamectl set-hostname K8s1
cat /sys/class/dmi/id/product_uuid
ip link show
hostname
cat /etc/machine-id
# 链接克隆制作的虚拟机,machine-id可能会一致,执行如下命令解决
sudo truncate -s 0 /etc/machine-id
sudo systemd-machine-id-setup

2. 安装chrony实现时间同步

执行该脚本

#!/bin/bash
set -e  # 任何命令失败则立即退出

echo "========== 开始配置 Chrony 时间同步 =========="

# 1. 检查网络连通性(确保能访问阿里云 NTP)
if ! ping -c 2 ntp.aliyun.com &>/dev/null; then
    echo "错误:无法 ping 通 ntp.aliyun.com,请检查网络!"
    exit 1
fi

# 2. 挂载光盘(如果已挂载则跳过)
if mount | grep -q "/media/cdrom"; then
    echo "光盘已挂载,跳过挂载步骤"
else
    mount /dev/sr0 /media/cdrom &>/dev/null || true
    sleep 2
fi

# 3. 安装 chrony
if ! rpm -q chrony &>/dev/null; then
    echo "正在安装 chrony..."
    dnf -y install chrony &>/dev/null
else
    echo "chrony 已安装,跳过安装"
fi

# 4. 备份原配置文件(如果未备份)
if [ ! -f /etc/chrony.conf.bak ]; then
    cp /etc/chrony.conf /etc/chrony.conf.bak
fi

# 5. 彻底清理旧配置,写入全新的干净配置(解决重复追加问题)
cat > /etc/chrony.conf << EOF
# 阿里云 NTP 服务器(国内首选)
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst

# 本地时间偏差记录文件
driftfile /var/lib/chrony/drift

# 如果本机网络时间偏差过大,允许快速跳跃修正
makestep 1.0 3

# 允许内网客户端同步(如果你后面要用其中一台做内网 NTP,可取消注释)
# allow 192.168.0.0/16
EOF

# 6. 重启 chronyd 并强制立即同步
systemctl restart chronyd
systemctl enable chronyd
sleep 3
chronyc -a makestep &>/dev/null || true

# 7. 验证同步状态
if chronyc sources -v | grep -q '^\^\*'; then
    echo "✅ chrony 同步成功!"
    echo "当前系统时间:$(date)"
    echo "详细同步状态:"
    chronyc tracking | grep -E "Reference ID|Stratum|Last offset"
else
    echo "❌ chrony 同步失败,请检查日志:journalctl -u chronyd -n 20"
    exit 1
fi

3. 编辑hosts文件

grep -q "192.168.100.99" /etc/hosts || cat << EOF >> /etc/hosts
192.168.100.99   K8s1
192.168.100.100  K8s2
192.168.100.101  K8s3
EOF

验证

[root@K8s1 ~]# ping -c 2 K8s2
PING K8s2 (192.168.100.100) 56(84) 比特的数据。
64 比特,来自 K8s2 (192.168.100.100): icmp_seq=1 ttl=64 时间=0.289 毫秒
64 比特,来自 K8s2 (192.168.100.100): icmp_seq=2 ttl=64 时间=1.23 毫秒

--- K8s2 ping 统计 ---
已发送 2 个包, 已接收 2 个包, 0% packet loss, time 1025ms
rtt min/avg/max/mdev = 0.289/0.760/1.231/0.471 ms

4. 关闭swap分区

sed -i '/swap/s@^@#@g' /etc/fstab
swapoff -a

二. 安装containerd

方案A:dnf 一键安装(推荐)

# 1. 添加阿里云 Docker CE 仓库
dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 2. 清理缓存并重新生成(确保新源生效)
dnf clean all && dnf makecache

# 3. 直接安装 containerd.io(会自动安装 runc 等依赖)
dnf install -y containerd.io

# 4. 验证安装是否成功
containerd --version;runc --version

安装完成后直接跳到 3. 配置镜像加速。

方案B:二进制手动安装

1. 下载containerd二进制包

wget https://github.com/containerd/containerd/releases/download/v2.3.0/containerd-2.3.0-linux-amd64.tar.gz
tar -C /usr/local -xzf containerd-2.3.0-linux-amd64.tar.gz

2. 安装 runc 和 CNI 插件

# ========== 第一步:runc ==========
wget https://github.com/opencontainers/runc/releases/latest/download/runc.amd64
install -m 755 runc.amd64 /usr/local/bin/runc

# ========== 第二步:CNI 插件 ==========
wget https://github.com/containernetworking/plugins/releases/download/v1.5.1/cni-plugins-linux-amd64-v1.5.1.tgz
mkdir -p /opt/cni/bin
tar -C /opt/cni/bin -xzf cni-plugins-linux-amd64-v1.5.1.tgz

3. 生成 systemd 服务和默认配置

# 下载systemd服务
wget -O /usr/lib/systemd/system/containerd.service \
https://raw.githubusercontent.com/containerd/containerd/v2.3.0/containerd.service

# 生成配置
mkdir -p /etc/containerd
/usr/local/bin/containerd config default | sudo tee /etc/containerd/config.toml

3. 配置镜像加速(两种方案共用,三台机器都要执行)

⚠️ 1、2、3 三台都要做这一步,只配 master 会导致 node 节点拉取镜像失败。

mkdir -p /etc/containerd/certs.d/docker.io
cat << EOF > /etc/containerd/certs.d/docker.io/hosts.toml
server = "https://docker.io"

[host."https://docker.1panel.live"]     # 镜像加速器
capabilities = ["pull","resolve"]
skip_verify = true                      # 跳过证书
[host."https://docker.m.daocloud.io"]
    capabilities = ["pull","resolve"]
    skip_verify = true
EOF

# 用 @ 作分隔符,路径里的斜杠不用转义;\ 换行
sed -i "\@\[plugins.'io.containerd.cri.v1.images'.registry\]@,\@^\[@ \
   s@config_path = .*@config_path = \"/etc/containerd/certs.d\"@" \
  /etc/containerd/config.toml

# sed -i \
#  "/\[plugins.'io.containerd.cri.v1.images'.registry\]/,/^\[/ \
#   s|config_path = .*|config_path = \"/etc/containerd/certs.d\"|" \
#  /etc/containerd/config.toml

4. 修改 containerd 配置适配 K8s(两种方案共用)

# 改 cgroup 驱动为 systemd
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 改 pause 镜像为国内源
sed -i 's|sandbox = .*|sandbox = "registry.aliyuncs.com/google_containers/pause:3.9"|' /etc/containerd/config.toml

5. 先加载内核模块

cat > /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter

6. 添加内核模块及检查

cat > /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sysctl --system
[root@K8s1 ~]# lsmod|grep overlay
overlay               229376  0
[root@K8s1 ~]# lsmod|grep br_netfilter
br_netfilter           36864  0
bridge                417792  1 br_netfilter

三. 安装containerd的客户端nerdctl

1. 我们从GitHub上下载二进制包

wget https://github.com/containerd/nerdctl/releases/download/v2.0.4/nerdctl-2.0.4-linux-amd64.tar.gz
tar -C /usr/local/bin -xzf nerdctl-2.0.4-linux-amd64.tar.gz nerdctl

2. nerdctl命令自动补齐

# nerdctl命令自动补齐
source <(nerdctl completion bash)
echo "source <(nerdctl completion bash)" >>~/.bashrc && source ~/.bashrc

3. 启动containerd

systemctl start containerd
systemctl enable containerd

四. 安装K8S

1. 指定阿里云的yum源

cat << EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
        https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

dnf clean all && dnf makecache

2. 安装kubeadm、kubectl、kubelet

dnf -y install kubeadm kubectl kubelet

3. 自动补齐

grep -q "kubeadm completion bash" ~/.bashrc || cat << EOF | tee -a ~/.bashrc
source <(kubeadm completion bash)
source <(kubectl completion bash)
source <(crictl  completion bash)
EOF

4. 启用kubelet

kubeadm init 成功后会自动启动 kubelet,这里只需设置开机自启。

systemctl enable kubelet

5. 指定crictl调用接口

cat > /etc/crictl.yaml <<EOF
runtime-endpoint: "unix:///run/containerd/containerd.sock"
image-endpoint: "unix:///run/containerd/containerd.sock"
timeout: 10
debug: false
EOF
crictl images
crictl info | grep -i endpoint

6. 初始化

准备配置文件

kubeadm config print init-defaults>~/init.yaml
sed -i \
-e 's@advertiseAddress.*@advertiseAddress: 192.168.100.99@g' \
-e "s@^\([[:space:]]*name:\).*@\1 ${HOSTNAME}@" \
-e "s@imageRepository: registry.k8s.io@imageRepository: registry.aliyuncs.com/google_containers@" \
-e "s@kubernetesVersion.*@kubernetesVersion: v1.28.2@" \
-e '/serviceSubnet:/a\  podSubnet: 10.244.0.0/16' ~/init.yaml

初始化(只在主节点1上做)

kubeadm init --config=/root/init.yaml

# 如果速度太慢卡卡住了,可以ctrl+C终止并手动拉取镜像
# kubeadm config images pull --config=/root/init.yaml

# 如果失败清理缓存
# kubeadm reset -f
# rm -rf /etc/cni /var/lib/etcd /var/lib/kubelet

# 可以再开终端使用该命令查看进度
# watch -n 2 'crictl images && echo "---" && date'
mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

查看验证

[root@K8s1 ~]# kubectl get nodes
NAME   STATUS     ROLES           AGE   VERSION
k8s1   NotReady   control-plane   12m   v1.28.2

7. 将2和3加入

kubeadm join 192.168.100.99:6443 --token abcdef.0123456789abcdef \
        --discovery-token-ca-cert-hash sha256:0c6030dc284c78bfacc0b61d4301a0af42267d5dc21c5e463de851733af8515d 
[root@K8s1 /]# kubectl get nodes
NAME   STATUS     ROLES           AGE   VERSION
k8s1   NotReady   control-plane   20m   v1.28.2
k8s2   NotReady   <none>          31s   v1.28.2
k8s3   NotReady   <none>          29s   v1.28.2

8. 安装网络插件(只在1上做)

curl https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml -O

sed -i \
  -e 's|# - name: CALICO_IPV4POOL_CIDR|- name: CALICO_IPV4POOL_CIDR|' \
  -e 's|#   value: "192.168.0.0/16"|  value: "10.244.0.0/16"|' \
  /root/calico.yaml
kubectl apply -f /root/calico.yaml

9. 验证

[root@K8s1 ~]#  kubectl get pods -n kube-system | grep calico
calico-kube-controllers-787f445f84-rwq82   0/1     ContainerCreating   0             62s
calico-node-ptm4m                          0/1     Init:2/3            0             62s
calico-node-xfbmd                          1/1     Running             0             62s
calico-node-znpp5                          0/1     Init:2/3            0             62s
[root@K8s1 ~]# kubectl get nodes
NAME   STATUS   ROLES           AGE   VERSION
k8s1   Ready    control-plane   42m   v1.28.2
k8s2   Ready    <none>          23m   v1.28.2
k8s3   Ready    <none>          23m   v1.28.2

正常情况下三台机器都配置了加速器,kubelet 会自动拉取 calico 镜像,无需手动操作,等待 2-3 分钟变 Ready 即可。

若出现 ImagePullBackOff(说明某台 node 加速器没配好),按如下排查:

# 1. 在出错的节点上确认 hosts.toml 是否存在(回第3节重做)
cat /etc/containerd/certs.d/docker.io/hosts.toml
systemctl restart containerd

# 2. 确认哪台节点拉不下来
kubectl get pod -n kube-system -l k8s-app=calico-node -o wide

# 3. 在出错的节点上手动拉取(只拉 cni 和 node)
nerdctl -n k8s.io pull docker.io/calico/cni:v3.27.3
nerdctl -n k8s.io pull docker.io/calico/node:v3.27.3