部署没有配置镜像源,均采用官方源。
基础准备
# 配置并刷新主机名 (sinon 只是为示例 hostname)
sudo hostnamectl set-hostname sinon
exec bash
# /etc/hosts 正确解析:把“VPS内网/主IP -> 主机名”映射好
IP=$(hostname -I | awk '{print $1}')
sudo sed -i "/${IP//./\\.}\s\+/d" /etc/hosts
echo "$IP sinon" | sudo tee -a /etc/hosts
# 验证(这三条都应该有正确输出,且 hostname -f 能解析到 sinon)
hostname
hostname -f || true
getent hosts $(hostname)
# 关闭 swap(k8s 1.16 对 swap 非常敏感)
sudo swapoff -a
sudo sed -ri 's/^\s*([^#]\S*\s+)swap(\s+)/#\1swap\2/g' /etc/fstab
# Kubernetes 网络需要开启 ipv4 转发
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
sudo sysctl --system
安装 containerd 并设为 systemd cgroup
# 安装 containerd
sudo apt-get install -y containerd
# 生成默认配置并开启 systemd cgroup
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
# 确认安装的 containerd 版本
containerd --version
# 对 containerd 1.x:
sudo sed -ri 's/^(\s*)SystemdCgroup = false/\1SystemdCgroup = true/' \
/etc/containerd/config.toml
# (如果你装的是 containerd 2.x,相关段落路径略有不同,同样把 SystemdCgroup 设为 true,见官方表格)
sudo systemctl restart containerd
sudo systemctl enable containerd
# 5) 确认默认 CRI 套接字存在
test -S /run/containerd/containerd.sock && echo "containerd OK"
kubelet 与运行时的 cgroup 驱动要一致;在 systemd 系统中推荐使用 systemd 驱动。如何在 containerd 1.x/2.x 配置 SystemdCgroup = true
见官方「Container Runtimes」文档。
安装 kubelet / kubeadm / kubectl(官方 pkgs.k8s.io)
以 Kubernetes v1.34 为例(需要其他小版本就把 URL 中的 v1.34
换掉):
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' \
| sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
官方已弃用 apt.kubernetes.io
,请用新仓库 pkgs.k8s.io
。官方连接
初始化单机控制面
选择与 Calico 兼容的 Pod 网段(Calico 默认示例是 192.168.0.0/16
),并把 --apiserver-advertise-address
指定为本机 IP:
# 可以通过 ip route 获取
# 例:本机 IP 假设为 10.0.108.2
sudo kubeadm init \
--apiserver-advertise-address=10.0.108.2 \
--pod-network-cidr=192.168.0.0/16
配置当前用户的 kubeconfig:
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm 单控制面初始化后,需要安装 Pod 网络插件(否则 CoreDNS 不会起)。若将来要做多控制面再加入 LB,可用 --control-plane-endpoint
,这里只是单机可忽略。
安装 Calico(官方 Operator 方式)
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/operator-crds.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/tigera-operator.yaml
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/custom-resources.yaml
# 如需自定义 PodCIDR,可按需编辑 custom-resources.yaml(kubeadm 场景通常无需改)
kubectl create -f custom-resources.yaml
# 观察 Pod 拉起 (确认没问题后,需要用户自己退出视图)
watch kubectl get pods -n calico-system
让控制平面节点可调度(单机部署必做)
kubectl taint nodes --all node-role.kubernetes.io/control-plane- || true
kubectl taint nodes --all node-role.kubernetes.io/master- || true # 兼容旧污点名
验证
# 核心组件就绪情况(CoreDNS 需要 CNI 安装完才会 Running)
kubectl get nodes -o wide
kubectl get pods -A
# 发一个简单应用确认调度正常
kubectl create deployment hello --image=nginx
kubectl expose deployment hello --port=80 --type=NodePort
kubectl get svc hello
修复源
一件粘贴切换回官方源 apt docker
#!/usr/bin/env bash
set -Eeuo pipefail
log() { printf "\033[1;32m[INFO]\033[0m %s\n" "$*"; }
warn() { printf "\033[1;33m[WARN]\033[0m %s\n" "$*"; }
err() { printf "\033[1;31m[ERR ]\033[0m %s\n" "$*" >&2; }
#--- 前置检查 ---
if [[ $EUID -ne 0 ]]; then
err "请以 root 身份运行(sudo -i 或在命令前加 sudo)。"
exit 1
fi
if ! command -v lsb_release >/dev/null 2>&1 && [[ -r /etc/os-release ]]; then
. /etc/os-release || true
CODENAME="${VERSION_CODENAME:-}"
else
CODENAME="$(lsb_release -sc 2>/dev/null || true)"
fi
if [[ -z "${CODENAME:-}" ]]; then
err "无法识别系统代号。此脚本仅支持 Ubuntu 22.04(jammy)。"
exit 1
fi
if [[ "$CODENAME" != "jammy" ]]; then
err "检测到发行版代号为 '$CODENAME',此脚本仅针对 Ubuntu 22.04 (jammy)。已中止。"
exit 1
fi
ARCH="$(dpkg --print-architecture)"
TS="$(date +%Y%m%d-%H%M%S)"
log "系统代号: $CODENAME, 架构: $ARCH"
#--- 选择官方默认主站 ---
# amd64/i386 用 archive.ubuntu.com + security.ubuntu.com
# 其他移植架构用 ports.ubuntu.com(含安全更新)
case "$ARCH" in
amd64|i386)
UBUNTU_BASE="http://archive.ubuntu.com/ubuntu"
UBUNTU_SEC="http://security.ubuntu.com/ubuntu"
;;
*)
UBUNTU_BASE="http://ports.ubuntu.com/ubuntu-ports"
UBUNTU_SEC="$UBUNTU_BASE"
;;
esac
#--- 备份并恢复 APT 官方源 ---
log "备份并恢复 /etc/apt/sources.list 到 Ubuntu 官方默认源..."
if [[ -f /etc/apt/sources.list ]]; then
cp -a /etc/apt/sources.list "/etc/apt/sources.list.bak.$TS"
fi
cat > /etc/apt/sources.list <<EOF
# Ubuntu 22.04 (jammy) 官方默认源
# 生成时间: $TS
deb $UBUNTU_BASE jammy main restricted universe multiverse
# deb-src $UBUNTU_BASE jammy main restricted universe multiverse
deb $UBUNTU_BASE jammy-updates main restricted universe multiverse
# deb-src $UBUNTU_BASE jammy-updates main restricted universe multiverse
deb $UBUNTU_BASE jammy-backports main restricted universe multiverse
# deb-src $UBUNTU_BASE jammy-backports main restricted universe multiverse
deb $UBUNTU_SEC jammy-security main restricted universe multiverse
# deb-src $UBUNTU_SEC jammy-security main restricted universe multiverse
EOF
# 部分系统可能存在 deb822 的 ubuntu.sources,备份避免冲突
if [[ -f /etc/apt/sources.list.d/ubuntu.sources ]]; then
log "检测到 deb822 源文件,已备份并停用:/etc/apt/sources.list.d/ubuntu.sources"
mv /etc/apt/sources.list.d/ubuntu.sources "/etc/apt/sources.list.d/ubuntu.sources.bak.$TS"
fi
#--- (可选)清理显然替换基础源的自定义文件:不删除第三方源 ---
# 如有你自己添加的第三方仓库(例如 VSCode/Node/Google),它们会保留。
# 如果你之前在 *.list 里替换了 Ubuntu 主仓库,这里仅做提示,不做强制清理。
for f in /etc/apt/sources.list.d/*.list; do
[[ -e "$f" ]] || continue
if grep -Eq 'ubuntu|mirror|aliyun|tencent|tuna|tsinghua|ustc|163' "$f"; then
warn "发现可能影响基础源的列表文件:$f(已保留不动,如需请手动检查或改名为 .disabled)"
fi
done
#--- 重新安装关键证书和密钥(有助于修复因源异常导致的签名错误) ---
log "更新索引前,确保关键证书/密钥工具存在(可能需要几秒)..."
apt-get update -o Acquire::Retries=3 || true
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates gnupg ubuntu-keyring curl >/dev/null 2>&1 || true
update-ca-certificates >/dev/null 2>&1 || true
#--- 恢复 Docker 官方 APT 源 ---
log "恢复 Docker 官方 APT 源(download.docker.com)..."
mkdir -p /etc/apt/keyrings /etc/apt/sources.list.d
# 备份可能存在的旧 docker 源列表
for f in /etc/apt/sources.list.d/docker*.list; do
[[ -e "$f" ]] || continue
mv "$f" "${f}.bak.$TS"
done
# 获取并写入 Docker GPG key(dearmor 到 keyring)
if [[ ! -s /etc/apt/keyrings/docker.gpg ]]; then
log "获取 Docker GPG key..."
if command -v curl >/dev/null 2>&1; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
elif command -v wget >/dev/null 2>&1; then
wget -qO- https://download.docker.com/linux/ubuntu/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
else
warn "系统缺少 curl/wget,尝试安装 curl..."
apt-get update -o Acquire::Retries=3
DEBIAN_FRONTEND=noninteractive apt-get install -y curl
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
fi
chmod a+r /etc/apt/keyrings/docker.gpg
fi
# 写入官方 docker 源列表(按当前架构与 jammy)
cat > /etc/apt/sources.list.d/docker.list <<EOF
deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable
EOF
#--- 刷新索引并做一次基本自检 ---
log "刷新 APT 索引..."
apt-get clean
apt-get update -o Acquire::Retries=3
log "尝试验证:读取 Ubuntu 与 Docker 仓库元数据..."
set +e
apt-cache policy | sed -n '1,120p' | sed -n '1,40p'
echo
apt-cache policy docker-ce | sed -n '1,60p'
set -e
log "完成 ✅"
echo
warn "如你曾在 /etc/docker/daemon.json 设置过 registry-mirrors(镜像加速),该设置不会被此脚本修改。若需恢复 Docker Hub 默认拉取行为,请手动删除该键并重启 Docker:sudo systemctl restart docker"