K8s部署¶
一. 解决安装环境¶
1. 查看三台机器不能一致的项¶
即UUID,MAC地址,主机名,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分区¶
二. 安装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¶
四. 安装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¶
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,这里只需设置开机自启。
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
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