2025-10-30 20:47:48 +08:00
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
|
|
# Kubernetes 容器运行时安装脚本
|
|
|
|
|
|
# 功能: 在所有节点安装 containerd 和 CNI 插件
|
|
|
|
|
|
|
|
|
|
|
|
echo "==== 安装容器运行时 (containerd) ===="
|
|
|
|
|
|
|
|
|
|
|
|
# 定义节点列表
|
|
|
|
|
|
NODES=("172.17.0.15:master" "172.17.0.43:node1" "172.17.0.34:node2")
|
|
|
|
|
|
|
|
|
|
|
|
# 本机 IP 与 SSH 选项
|
|
|
|
|
|
LOCAL_IP=$(ip route get 1 | awk '{print $7; exit}')
|
|
|
|
|
|
SSH_OPTS='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes'
|
|
|
|
|
|
# SSH 私钥(可用环境变量 SSH_KEY 覆盖),存在则自动携带
|
|
|
|
|
|
SSH_KEY_PATH=${SSH_KEY:-$HOME/.ssh/id_rsa}
|
|
|
|
|
|
[ -f "$SSH_KEY_PATH" ] && SSH_ID="-i $SSH_KEY_PATH" || SSH_ID=""
|
|
|
|
|
|
|
|
|
|
|
|
# 统一的工件目录与文件名(在 master 上下载一次后分发)
|
|
|
|
|
|
ARTIFACTS_DIR="$HOME/k8s-artifacts"
|
|
|
|
|
|
CNI_VERSION="v1.3.0"
|
|
|
|
|
|
CNI_TGZ="cni-plugins-linux-amd64-${CNI_VERSION}.tgz"
|
|
|
|
|
|
|
|
|
|
|
|
# 函数:在所有节点执行命令
|
|
|
|
|
|
execute_on_all_nodes() {
|
|
|
|
|
|
local command="$1"
|
|
|
|
|
|
local description="$2"
|
|
|
|
|
|
|
|
|
|
|
|
echo "==== $description ===="
|
|
|
|
|
|
for node in "${NODES[@]}"; do
|
|
|
|
|
|
IFS=':' read -r ip hostname <<< "$node"
|
|
|
|
|
|
echo "在 $hostname ($ip) 执行: $command"
|
|
|
|
|
|
if [ "$ip" = "$LOCAL_IP" ] || [ "$hostname" = "master" ]; then
|
|
|
|
|
|
bash -lc "$command"
|
|
|
|
|
|
else
|
|
|
|
|
|
ssh $SSH_OPTS $SSH_ID ubuntu@$ip "$command"
|
|
|
|
|
|
fi
|
|
|
|
|
|
done
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 函数:传输文件到所有节点
|
|
|
|
|
|
copy_to_all_nodes() {
|
|
|
|
|
|
local file="$1"
|
|
|
|
|
|
echo "==== 传输文件 $file 到所有节点 ===="
|
|
|
|
|
|
for node in "${NODES[@]}"; do
|
|
|
|
|
|
IFS=':' read -r ip hostname <<< "$node"
|
|
|
|
|
|
echo "传输到 $hostname ($ip)"
|
|
|
|
|
|
if [ "$ip" = "$LOCAL_IP" ] || [ "$hostname" = "master" ]; then
|
|
|
|
|
|
cp -f "$file" ~/
|
|
|
|
|
|
else
|
|
|
|
|
|
scp $SSH_OPTS $SSH_ID "$file" ubuntu@$ip:~/
|
|
|
|
|
|
fi
|
|
|
|
|
|
done
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 创建容器运行时安装脚本
|
|
|
|
|
|
cat > k8s-install-containerd.sh << 'EOF_OUTER'
|
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
|
|
echo "==== 安装容器运行时 (containerd) ===="
|
|
|
|
|
|
|
|
|
|
|
|
# 1. 安装 containerd
|
|
|
|
|
|
echo "安装 containerd..."
|
|
|
|
|
|
sudo apt update
|
|
|
|
|
|
sudo apt install -y containerd
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 配置 containerd
|
|
|
|
|
|
echo "配置 containerd..."
|
|
|
|
|
|
# ① 停止 containerd
|
|
|
|
|
|
sudo systemctl stop containerd
|
|
|
|
|
|
|
|
|
|
|
|
# ② 生成默认配置
|
2025-11-21 13:54:04 +08:00
|
|
|
|
sudo mkdir -p /etc/containerd
|
2025-10-30 20:47:48 +08:00
|
|
|
|
sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
|
|
|
|
|
|
|
|
|
|
|
|
# ③ 注入镜像加速配置(docker.io/quay.io:腾讯云,其它:高校镜像优先)
|
|
|
|
|
|
sudo sed -i '/\[plugins."io.containerd.grpc.v1.cri".registry.mirrors\]/a\
|
|
|
|
|
|
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n endpoint = ["https://mirror.ccs.tencentyun.com"]\n [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]\n endpoint = ["https://quay.tencentcloudcr.com"]\n [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]\n endpoint = ["https://ghcr.nju.edu.cn"]\n [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]\n endpoint = ["https://gcr.nju.edu.cn"]\n [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]\n endpoint = ["https://registry-k8s-io.mirrors.sjtug.sjtu.edu.cn"]\n [plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]\n endpoint = ["https://gcr.nju.edu.cn"]' /etc/containerd/config.toml
|
|
|
|
|
|
|
|
|
|
|
|
# ④ 重新加载并启动 containerd
|
|
|
|
|
|
sudo systemctl daemon-reexec
|
|
|
|
|
|
sudo systemctl daemon-reload
|
|
|
|
|
|
sudo systemctl restart containerd
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 在 master 预下载 CNI 压缩包并分发到各节点
|
|
|
|
|
|
echo "准备 CNI 工件并分发..."
|
|
|
|
|
|
if [ "$LOCAL_IP" = "172.17.0.15" ]; then
|
|
|
|
|
|
mkdir -p "$ARTIFACTS_DIR"
|
|
|
|
|
|
if [ ! -f "$ARTIFACTS_DIR/$CNI_TGZ" ]; then
|
|
|
|
|
|
echo "在 master 下载 $CNI_TGZ ..."
|
|
|
|
|
|
curl -L --fail --retry 3 --connect-timeout 10 \
|
|
|
|
|
|
-o "$ARTIFACTS_DIR/$CNI_TGZ" \
|
|
|
|
|
|
"https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/$CNI_TGZ"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "已存在 $ARTIFACTS_DIR/$CNI_TGZ,跳过下载"
|
|
|
|
|
|
fi
|
|
|
|
|
|
# 分发到所有节点 home 目录
|
|
|
|
|
|
copy_to_all_nodes "$ARTIFACTS_DIR/$CNI_TGZ"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 安装 CNI 插件(优先使用已分发的本地文件)
|
|
|
|
|
|
echo "安装 CNI 插件..."
|
|
|
|
|
|
sudo mkdir -p /opt/cni/bin
|
|
|
|
|
|
if [ -f "$CNI_TGZ" ]; then
|
|
|
|
|
|
echo "使用已分发的 $CNI_TGZ 进行安装"
|
|
|
|
|
|
sudo tar -xzf "$CNI_TGZ" -C /opt/cni/bin/
|
|
|
|
|
|
rm -f "$CNI_TGZ"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "未找到本地 $CNI_TGZ,尝试在线下载(网络慢时可能用时较长)..."
|
|
|
|
|
|
curl -L --fail --retry 3 --connect-timeout 10 \
|
|
|
|
|
|
-o "$CNI_TGZ" \
|
|
|
|
|
|
"https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/$CNI_TGZ"
|
|
|
|
|
|
sudo tar -xzf "$CNI_TGZ" -C /opt/cni/bin/
|
|
|
|
|
|
rm -f "$CNI_TGZ"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 6. 验证安装
|
|
|
|
|
|
echo "==== 验证 containerd 安装 ===="
|
|
|
|
|
|
sudo systemctl status containerd --no-pager -l
|
|
|
|
|
|
sudo ctr version
|
|
|
|
|
|
|
|
|
|
|
|
echo "==== containerd 安装完成 ===="
|
|
|
|
|
|
EOF_OUTER
|
|
|
|
|
|
|
|
|
|
|
|
chmod +x k8s-install-containerd.sh
|
|
|
|
|
|
copy_to_all_nodes k8s-install-containerd.sh
|
|
|
|
|
|
execute_on_all_nodes "./k8s-install-containerd.sh" "安装容器运行时"
|
|
|
|
|
|
|
|
|
|
|
|
echo "==== 容器运行时安装完成 ===="
|
|
|
|
|
|
|