Appearance
Ubuntu 环境离线安装 Kubernetes v1.33.0 三节点集群详细指南
本文档适用于 Ubuntu 20.04/22.04 + containerd 环境。网络插件以 Flannel 为例,其他插件如 Calico 可类似操作。
一、准备工作
1. 三台服务器
- 主机名建议:master、node1、node2
点击查看更多相关说明
使用 hostnamectl 工具配置主机名,例如,将主节点设置为 master
shell
hostnamectl set-hostname master⚠️ 注意:重启后生效,请依次修改三台服务器的主机名!
- 配置静态 IP
点击查看更多相关说明
通过编辑 /etc/netplan/00-installer-config.yaml 网卡配置文件进行修改,例如:
shell
# This is the network config written by 'subiquity'
network:
ethernets:
ens160:
addresses:
- 192.168.0.160/24
gateway4: 192.168.0.1
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
version: 2修改之后执行 netplan apply 即可生效!
⚠️ 如果通过 ssh 连接,执行 netplan apply 之后连接将会断开连接,会产生卡死的现象,关闭终端另开启一个即可!
- 配置静态 IP、主机名、互相
/etc/hosts - 关闭防火墙
点击查看更多相关说明
shell
sudo systemctl disable --now ufw这将关闭防火墙并禁用开机自动引导启动
- 永久关闭交换分区
点击查看更多相关说明
shell
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab重启之后通过以下命令检查输出是否为空
shell
swapon --show- 如果 没有输出,说明当前没有启用的 Swap。
- 如果有输出,说明仍有 Swap 设备或文件在运行。
- 修改内核参数,允许桥接防火墙及IP转发
点击查看更多相关说明
编辑系统配置文件
编写 /etc/sysctl.conf 配置文件,取消 net.ipv4.ip_forward=1 前面的注释保存即可
txt
net.ipv4.ip_forward=1重新加载配置(无需重启)
shell
sudo sysctl -p- 启用 cgroups 到 v2 版本
点击查看更多相关说明
步骤 1:启用 cgroups v2 并禁用 v1
修改 /etc/default/grub 文件,修改 GRUB_CMDLINE_LINUX 行,添加以下参数
toml
GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all"更新 GRUB 并重启
shell
sudo update-grub && sudo reboot步骤 2:验证切换结果
重启之后进行启用 cgroups v2版本验证
shell
mount | grep cgroup预期输出应仅剩 cgroup2 挂载点:
txt
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)2. SSH 免密登录
- 写入 dns 记录
点击查看更多相关说明
在 Kubernetes 待安装服务器写入 dns 记录,注意是有几台写入几台!
shell
echo '192.168.0.160 master' >> /etc/hosts
echo '192.168.0.161 node1' >> /etc/hosts
echo '192.168.0.162 node2' >> /etc/hosts提醒
待安装的 Kubernetes 集群有几台服务器,就在这些服务器上依次操作!
- 配置免密传输
点击查看更多相关说明
生成 ssh 公私对
shell
ssh-keygen #一路回车,不输入密码在 Kubernetes 待安装服务器写入 dns 记录,有几台服务器就拷贝到几台!
shell
ssh-copy-id master
ssh-copy-id node1
ssh-copy-id node2ssh-copy-id
ssh-copy-id 是一个用于将本地用户的公钥(默认是 ~/.ssh/id_rsa.pub)复制到远程目录主机的 ~/.ssh/authorized_keys 文件中的命令。
从而实现无需密码的 SSH 登录,后续通过 ssh node1 登录时,系统会直接使用密钥认证,无需手动输入密码。
提醒
待安装的 Kubernetes 集群有几台服务器,就在这些服务器上依次操作!理论上当前主机无需拷贝当前主机哦!
3. 修改内核参数
允许桥接防火墙及IP转发,否则 Kubernetes 集群可能会遇到网络问题。
点击查看更多相关说明
- 手动加载 br_netfilter 模块
shell
sudo modprobe br_netfilter验证是否加载成功:
shell
lsmod | grep br_netfilter # 应返回 br_netfilter 相关行- 修改 /etc/sysctl.conf
shell
sudo tee /etc/sysctl.d/99-kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF- 应用配置
shell
sudo sysctl --system # 加载所有 sysctl 配置(包括 /etc/sysctl.d/)验证是否生效:
shell
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward输出应均为 1
4. 配置时间同步
点击查看更多相关说明
如果使用 VMWare ESXi 虚拟化,可以通过 Web 管理界面进行配置时间同步,主机 -> 管理 -> 系统 -> 时间和日期,点击 编辑设置 在弹出的对话框中选择 使用网络时间协议(启用 NTP 客户端) 在 NTP 服务器 输入 pool.ntp.org 点击保存即可!
登录到服务器,输出 timedatectl 命令,查看当前服务器本地时间是否正确
shell
timedatectl将输出类似如下的时间信息
text
Local time: Mon 2025-06-23 13:38:18 UTC
Universal time: Mon 2025-06-23 13:38:18 UTC
RTC time: Mon 2025-06-23 13:38:18
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no可以看到本地时间并不正确,需要修改时区
shell
timedatectl set-timezone Asia/Shanghai再输入 timedatectl 验证即可
txt
Local time: Mon 2025-06-23 21:42:25 CST
Universal time: Mon 2025-06-23 13:42:25 UTC
RTC time: Mon 2025-06-23 13:42:26
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no现在本地时间也就对上了!
5. 安装 IPVS
点击查看更多相关说明
安装 IPVS 内核模块
shell
apt install -y ipset ipvsadm加载内核模块
shell
sudo modprobe ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh查看内核加载 ip_vs
shell
lsmod | grep ip_vs检查 IPVS 规则
shell
sudo ipvsadm -L提醒
kubernetes 安装完全后,可以使用 kube-proxy 使用 IPVS
shell
kubectl edit cm -n kube-system kube-proxy修改 proxy-mode 为 ipvs:
yaml
mode: "ipvs"第一阶段:在有网络的环境中准备离线安装包
1. 设置下载环境
切换到普通用户
shell
su testify提醒
Ubuntu 系统安装时都有一个默认用户,也就是切换到安装系统时创建的用户,其它用户也可以,只要是非 root 用户即可!如果使用 root 下载软件包会存在权限警告问题!W: Download is performed unsandboxed as root as file
创建工作目录
shell
mkdir -p ~/k8s-offline/v1.33.0提醒
可以一直保持在家目录($HOME)完成准备离线安装包的相关操作!
安装必要工具
shell
sudo apt-get update && sudo apt-get install -y apt-transport-https curl gnupg2. 添加 Kubernetes apt 源
1. 创建 keyrings 目录(如果不存在)
shell
sudo mkdir -p /etc/apt/keyrings2. 下载并添加 GPG 密钥
shell
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg3. 添加 Kubernetes apt 源
shell
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list4. 更新 apt 缓存
shell
sudo apt-get update3. 下载 Kubernetes 组件
创建下载目录
shell
DOWNLOAD_DIR="$HOME/k8s-offline/v1.33.0/deb-packages/kubernetes"
mkdir -p $DOWNLOAD_DIR下载指定版本的 kubeadm, kubelet 和 kubectl
shell
apt-get download \
kubelet=1.33.0-1.1 \
kubeadm=1.33.0-1.1 \
kubectl=1.33.0-1.1下载依赖包
shell
apt-get download \
conntrack \
ebtables \
socat \
ethtool \
ipset \
nfs-common \
libseccomp2 \
libltdl7 \
libnfsidmap2 \
libipset13 \
libtirpc3 \
libtirpc-common \
rpcbind \
keyutils \
cri-tools \
kubernetes-cni移动所有 .deb 文件到下载目录
shell
mv *.deb $DOWNLOAD_DIR4. 下载容器运行时组件
创建下载目录
shell
DOWNLOAD_DIR="$HOME/k8s-offline/v1.33.0/deb-packages/cri"
mkdir -p $DOWNLOAD_DIR下载指定版本的 docker.io
shell
apt-get download docker.io=26.1.3-0ubuntu1~20.04.1提醒
Kubernetes v1.33.0 默认使用 containerd 作为容器运行时并不需要安装 docker.io 即可。
下载指定版本的 containerd
shell
apt-get download containerd=1.7.24-0ubuntu1~20.04.2下载依赖包
shell
apt-get download runc移动所有 .deb 文件到下载目录
shell
mv *.deb $DOWNLOAD_DIR5. 下载网络插件(Calico)配置文件
指定下载目录
shell
DOWNLOAD_DIR="$HOME/k8s-offline/v1.33.0/manifests"
mkdir -p $DOWNLOAD_DIRshell
wget -c https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/calico.yaml \
-O $DOWNLOAD_DIR/calico.yaml6. 下载容器镜像
先安装 kubeadm(在线环境)
shell
sudo apt-get install -y kubelet=1.33.0-1.1 kubeadm=1.33.0-1.1 kubectl=1.33.0-1.1
sudo apt-mark hold kubelet kubeadm kubectl # 锁定版本安装 Docker
shell
sudo apt-get install -y docker.io
sudo systemctl start docker配置 Docker 国内镜像源
点击查看更多相关说明
创建或修改 Docker 配置文件 如果不存在
/etc/docker/daemon.json,vim 自动创建它;如果已存在,直接编辑:bashsudo vim /etc/docker/daemon.json添加镜像源配置 将以下内容写入文件(以阿里云镜像为例,其他源见附录):
json{ "registry-mirrors": ["https://<your-mirror-url>.mirror.aliyuncs.com"] }重启 Docker 服务
bashsudo systemctl daemon-reload sudo systemctl restart docker验证配置
bashsudo docker info | grep "Registry Mirrors" -A 1如果看到配置的镜像地址,说明成功。
可尝试是否可用的镜像源
配置 Docker 使用代理
点击查看更多相关说明
如果配置了上面的国内镜像源还是行的话直接配置代理
创建或编辑 Docker 服务配置
创建配置目录
shell
sudo mkdir -p /etc/systemd/system/docker.service.d添加配置文件
shell
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://192.168.0.23:7890"
Environment="HTTPS_PROXY=http://192.168.0.23:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.docker.io,.aliyuncs.com"
EOF重新加载并重启 Docker
shell
sudo systemctl daemon-reload && sudo systemctl restart docker测试下载镜像
shell
sudo docker pull nginx:latest列出 Kubernetes v1.33.0 所需镜像
shell
sudo kubeadm config images list --kubernetes-version=v1.33.0这将输出 Kubernetes v1.33.0 所需的所有镜像版本
txt
registry.k8s.io/kube-apiserver:v1.33.0
registry.k8s.io/kube-controller-manager:v1.33.0
registry.k8s.io/kube-scheduler:v1.33.0
registry.k8s.io/kube-proxy:v1.33.0
registry.k8s.io/coredns/coredns:v1.12.0
registry.k8s.io/pause:3.10
registry.k8s.io/etcd:3.5.21-0拉取 Kubernetes v1.33.0 镜像
shell
images=(
registry.k8s.io/kube-apiserver:v1.33.0
registry.k8s.io/kube-controller-manager:v1.33.0
registry.k8s.io/kube-scheduler:v1.33.0
registry.k8s.io/kube-proxy:v1.33.0
registry.k8s.io/coredns/coredns:v1.12.0
registry.k8s.io/pause:3.10
registry.k8s.io/etcd:3.5.21-0
)
for image in "${images[@]}"; do
sudo docker pull $image
done保存 Kubernetes v1.33.0 镜像为 tar 文件
创建镜像存储目录
shell
mkdir -p $HOME/k8s-offline/v1.33.0/images导出镜像到归档文件
shell
sudo docker save -o $HOME/k8s-offline/v1.33.0/images/k8s-images.tar \
registry.k8s.io/kube-apiserver:v1.33.0 \
registry.k8s.io/kube-controller-manager:v1.33.0 \
registry.k8s.io/kube-scheduler:v1.33.0 \
registry.k8s.io/kube-proxy:v1.33.0 \
registry.k8s.io/coredns/coredns:v1.12.0 \
registry.k8s.io/pause:3.10 \
registry.k8s.io/etcd:3.5.21-0下载网络插件 Calico 镜像
shell
images=(
calico/node:v3.26.0
calico/cni:v3.26.0
calico/kube-controllers:v3.26.0
)
for image in "${images[@]}"; do
sudo docker pull $image
done导出网络插件 Calico 镜像为归档文档
shell
sudo docker save -o $HOME/k8s-offline/v1.33.0/images/calico-images.tar \
calico/node:v3.26.0 \
calico/cni:v3.26.0 \
calico/kube-controllers:v3.26.07. 准备安装脚本
创建安装脚本
shell
cat > $HOME/k8s-offline/v1.33.0/install.sh << 'EOF'
#!/bin/bash
# 安装 Kubernetes 组件
sudo dpkg -i ./deb-packages/kubernetes/*.deb
# 安装容器运行时CRI组件
sudo dpkg -i ./deb-packages/cri/*.deb
systemctl start containerd
# sudo systemctl start docker
# 加载 Kubernetes 镜像到 Docker
# docker load -i ./images/k8s-images.tar
# 加载 Kubernetes 镜像到 Contained
sudo ctr -n=k8s.io images import ./images/k8s-images.tar
# 加载 Calico 镜像 Docker
# docker load -i ./images/calico-images.tar
# 加载 Calico 镜像 Contained
sudo ctr -n=k8s.io images import ./images/calico-images.tar
# 锁定 Kubernetes 版本
sudo apt-mark hold kubelet kubeadm kubectl
# 拷贝网络插件配置文件到 Kubernetes 默认的 /etc/kubernetes/manifests/
cp ./manifests/calico.yaml /etc/kubernetes/manifests/
EOF添加可执行权限
shell
chmod +x $HOME/k8s-offline/v1.33.0/install.sh8. 打包所有文件
shell
sudo tar -czvf k8s-offline-v1.33.0.tar.gz -C $HOME/k8s-offline/v1.33.0 .第二阶段:在离线环境中安装集群
1. 传输文件到所有节点
将 k8s-offline-v1.33.0.tar.gz 传输到所有三台节点服务器。
提示
可以通过 scp 命令进行方便、快捷的传输文件。
2. 在所有节点上执行基础安装
解压离线安装包资源归档文件
创建解压目标目录
shell
mkdir -p /opt/k8s-install解压到解压目标目录
shell
tar -xzvf k8s-offline-v1.33.0.tar.gz -C /opt/k8s-install进入到解压目标目录
shell
cd /opt/k8s-install运行安装脚本
shell
sudo ./install.sh验证安装
查看 kubeadm 版本信息
shell
kubeadm version查看 kubectl 客户端版本信息
shell
kubectl version --client查看 kubelet 版本信息
shell
kubelet --version查看容器镜像
shell
# 查看 contained 查看容器镜像
# sudo docker images
# 查看 contained 查看容器镜像
sudo ctr -n=k8s.io images ls -q查看 rpcbind 服务状态
shell
systemctl status rpcbind.service查看 containerd 服务状态
shell
systemctl status containerd.service查看 kubelet 服务状态
shell
systemctl status kubelet警告
当前 kubelet 应该是未启动状态,即使使用 systemctl restart kubelet 也不会启动成功,只有 初始化控制平面 之后才会拉起 kubelet 服务!
当然,如果初始化控制平台之后 kubelet 应该正常启动,并且可以通过 http://127.0.0.1:10248/healthz 这个端点查看服务状态。
3. 在主节点上初始化集群
3.1. 初始化 containerd 配置
通过 file 命令检测 /etc/containerd/config.toml 文件是否存在
shell
file /etc/containerd/config.toml如果未初始化过 containerd 配置文件,正常情况下应该输出
txt
/etc/containerd/config.toml: cannot open `/etc/containerd/config.toml' (No such file or directory)初始化 containerd 默认配置文件
shell
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml提醒
该操作会将 containerd 默认配置信息写入到 /etc/containerd/config.toml 文件!
🍔 确认 cri 沙箱镜像版本是否与 containerd 镜像版本一致
查看 cri 沙箱镜像版本信息
toml
// other config ......
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"]
device_ownership_from_security_context = false
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
drain_exec_sync_io_timeout = "0s"
enable_cdi = false
enable_selinux = false
enable_tls_streaming = false
enable_unprivileged_icmp = false
enable_unprivileged_ports = false
ignore_deprecation_warnings = []
ignore_image_defined_volumes = false
image_pull_progress_timeout = "5m0s"
image_pull_with_sync_fs = false
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
sandbox_image = "registry.k8s.io/pause:3.8"
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
// other config ......执行以下命令,列出 containerd 镜像列表
shell
ctr -n=k8s.io images ls -q将输出类似如下的 containerd 镜像列表数据
txt
docker.io/calico/cni:v3.26.0
docker.io/calico/kube-controllers:v3.26.0
docker.io/calico/node:v3.26.0
registry.k8s.io/coredns/coredns:v1.12.0
registry.k8s.io/etcd:3.5.21-0
registry.k8s.io/kube-apiserver:v1.33.0
registry.k8s.io/kube-controller-manager:v1.33.0
registry.k8s.io/kube-proxy:v1.33.0
registry.k8s.io/kube-scheduler:v1.33.0
registry.k8s.io/pause:3.10
sha256:1cf5f116067c67da67f97bff78c4bbc76913f59057c18627b96facaced73ea0b
sha256:1d579cb6d696709ea7c8613023cbc1204ac2af295477fe577c8fa741a76efa02
sha256:44f52c09dececf0d842450cfbdcf6f1ce1e6eaf2d7183d643b9fbf77dde03a38
sha256:45ae357729e3a6db7de47d4efb04453ac384d5cfec2f062a86523f3482cb1cdb
sha256:499038711c0816eda03a1ad96a8eb0440c005baa6949698223c6176b7f5077e1
sha256:5d6f5c26c655486ee59f7c517dbd383336f4ce2c0db77f7d5ffd015395deee6f
sha256:6ba9545b2183ef722d7e8a7f9e9c2abfaf483cd980bc378480631699413d9cf4
sha256:873ed75102791e5b0b8a7fcd41606c92fcec98d56d05ead4ac5131650004c136
sha256:8d72586a76469984dc4c5c7c36b24fbe4baed63056998c682f07b591d5e0aba4
sha256:f1184a0bd7fe53a4c7098147f250b1f8b287a0e4f8a4e1509ef1d06893267c68可以看到沙箱镜像指定的镜像版本与 containerd 镜像列表中的 pause 版本匹配不上!
需要将 containerd 配置文件 /etc/containerd/config.toml 中的沙箱镜像校正为 registry.k8s.io/pause:3.10,也就是说该值必须与 containerd 镜像列表中的 pause 版本保持一致!
⚠️修改之后记得重启 containerd
shell
systemctl restart containerd警告
这个应该是 Kubernetes v1.33.0 版本的一个 BUG,在下载离线资源的过程中通过执行 sudo kubeadm config images list --kubernetes-version=v1.33.0 命令得到的 pause 版本确实是 3.10,而现在 containerd 默认配置为 3.8 这明显是有问题的,如果不进行沙箱镜像版本确认,在初始化控制平面操作过程中就会出现问题!
3.2. 创建 crictl.yaml 配置文件
shell
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: false
EOF如果未创建该配置文件,初始化控制平面之后通过,通过执行 crictl ps -a 命令时将到一个警告信息
txt
WARN[0000] Config "/etc/crictl.yaml" does not exist, trying next: "/usr/bin/crictl.yaml"
WARN[0000] runtime connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
WARN[0000] Image connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD NAMESPACE
be6c9ad389276 f1184a0bd7fe5 38 seconds ago Running kube-proxy 1 165cdc961d1bf kube-proxy-4hg8c kube-system
5fc516e787ee8 f1184a0bd7fe5 39 seconds ago Exited kube-proxy 0 08c97bca72201 kube-proxy-4hg8c kube-system
c988838d71433 1d579cb6d6967 About a minute ago Running kube-controller-manager 1 324e2bf77651d kube-controller-manager-testify kube-system
975a48e4e3ef2 499038711c081 About a minute ago Running etcd 1 c9c4da99fc922 etcd-testify kube-system
143f7444e674c 6ba9545b2183e About a minute ago Running kube-apiserver 1 d001ac7718052 kube-apiserver-testify kube-system
88dafa6cc3b63 8d72586a76469 About a minute ago Running kube-scheduler 1 d16427a51cb45 kube-scheduler-testify kube-system
8d4b1eb629996 6ba9545b2183e About a minute ago Exited kube-apiserver 0 4ae4675ab1514 kube-apiserver-testify kube-system
687077efcc7bc 8d72586a76469 About a minute ago Exited kube-scheduler 0 da34d839bc256 kube-scheduler-testify kube-system
cf06d312b77dc 1d579cb6d6967 About a minute ago Exited kube-controller-manager 0 67ccddd02f0a9 kube-controller-manager-testify kube-system
ae9f3da58d14d 499038711c081 About a minute ago Exited etcd 0 c7afacdc52760 etcd-testify kube-system3.3. 初始化控制平面
设置临时节点IP变量,方便下面的初始化参数指定
shell
node_address=<master节点IP>使用 kubeadm 初始化控制平面
shell
sudo kubeadm init \
--kubernetes-version v1.33.0 \
--pod-network-cidr=192.168.0.0/16 \
--apiserver-advertise-address=$node_address \
--control-plane-endpoint=$node_address点击查看更多相关说明
例如,您的控制平面主节点 IP 为 192.168.0.160,那么上面命令替换后应该为
shell
node_address=192.168.0.160kubeadm 初始化控制平面命令为
shell
sudo kubeadm init \
--kubernetes-version v1.33.0 \
--pod-network-cidr=192.168.0.0/16 \
--apiserver-advertise-address=$node_address \
--control-plane-endpoint=$node_address可能会出现容器运行时的沙盒镜像与kubeadm使用的沙盒镜像不一致问题,具体表现如下
txt
[preflight] You can also perform this action beforehand using 'kubeadm config images pull'
W0617 16:13:21.203208 47633 checks.go:846] detected that the sandbox image "registry.k8s.io/pause:3.8" of the container runtime is inconsistent with that used by kubeadm.It is recommended to use "registry.k8s.io/pause:3.10" as the CRI sandbox image.如果遇到该问题可以参考 解决容器运行时的沙盒镜像与kubeadm使用的沙盒镜像不一致问题 相关文档中的具体说明,解决该问题后再次执行上面的初始化命令进行操作验证即可!
可能还会遇到 cgroups v1 support is in maintenance mode, please migrate to cgroups v2 问题,可以参考 解决 kubeadm 初始化时提示 cgroups v1 support is in maintenance mode, please migrate to cgroups v2 问题 相关文档中的具体说明!
可能还会遇到 A control plane component may have crashed or exited when started by the container runtime. To troubleshoot, list all containers using your preferred container runtimes CLI. 的问题
以下是使用 crictl 列出所有正在运行的 Kubernetes 容器的一个示例:
shell
crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps -a | grep kube | grep -v pause根据日志进行问题分析排查,以下是一个可以会存在的问题输出
txt
WARN[0000] Config "/etc/crictl.yaml" does not exist, trying next: "/usr/bin/crictl.yaml"设置 kubectl 配置
shell
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config在主节点上安装网络插件(Calico)
Kubernetes V1.33.0 离线安装资源包已提供离线 Calico 配置文件
shell
kubectl apply -f /opt/k8s-install/calico.yaml --validate=false提醒
只有 kube-apiserver Pod 启动之后上面的操作才能操作成功!可以通过 crictl ps 查看 kube-apiserver 状态是否是 Running,为 Running 时执行上面的命令!
如果节点可以连接到外网的情况下可以使用互联网线上资源
shell
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/calico.yaml查看节点状态
shell
kubectl get nodes将输出类似如下的节点状态数据信息
txt
NAME STATUS ROLES AGE VERSION
testify NotReady control-plane 5m10s v1.33.0完全重置集群点击查看更多相关说明
重置集群
shell
sudo kubeadm reset -f
sudo rm -rf /etc/kubernetes/ /var/lib/etcd/ /etc/cni/net.d/ ~/.kube/重新初始化 再次执行 在主节点上初始化集群 相关操作以修复问题
好的,为您补充 加入工作节点 和 验证集群状态 两个章节的完整内容:
markdown
### 4. 加入工作节点
在主节点初始化控制平面成功后,kubeadm 会输出类似如下的 join 命令:
```txt
You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:
kubeadm join 192.168.0.160:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:7e5a3f9c2b8d1a6e4f7c3b9a2d5e8f1c4a7b2d9e6f3c8a1b5e7d9f2c4a6b8e0f \
--control-plane
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.160:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:7e5a3f9c2b8d1a6e4f7c3b9a2d5e8f1c4a7b2d9e6f3c8a1b5e7d9f2c4a6b8e0f4.1. 在工作节点上执行 join 命令
登录到每个工作节点(node1、node2),执行 worker 节点的 join 命令:
bash
sudo kubeadm join 192.168.0.160:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:7e5a3f9c2b8d1a6e4f7c3b9a2d5e8f1c4a7b2d9e6f3c8a1b5e7d9f2c4a6b8e0f提示
如果您忘记或丢失了初始化时输出的 join 命令,可以在主节点上重新生成:
bash
# 查看现有 token 列表
sudo kubeadm token list
# 如果 token 已过期或不存在,创建新 token
sudo kubeadm token create
# 获取 CA 证书的哈希值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
# 完整的 join 命令(可组合使用)
kubeadm token create --print-join-command4.2. 验证工作节点 join 成功
在工作节点上执行 join 命令后,预期输出如下:
txt
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[preflight] Activating the kubelet service
[post-start] The kubelet is now running4.3. 在主节点确认节点加入
bash
kubectl get nodes预期输出:
txt
NAME STATUS ROLES AGE VERSION
master NotReady control-plane 10m v1.33.0
node1 NotReady <none> 30s v1.33.0
node2 NotReady <none> 30s v1.33.0注意
此时节点的 STATUS 仍然是 NotReady,这是正常的,因为网络插件(Calico)正在配置 Pod 网络。等待 1-2 分钟后再查看,STATUS 应变为 Ready。
5. 验证集群状态
5.1. 查看所有节点状态
bash
kubectl get nodes -o wide预期输出(所有节点均为 Ready 状态):
txt
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE KERNEL-VERSION
master Ready control-plane 15m v1.33.0 192.168.0.160 Ubuntu 22.04.3 LTS 5.15.0-91-generic
node1 Ready <none> 5m v1.33.0 192.168.0.161 Ubuntu 22.04.3 LTS 5.15.0-91-generic
node2 Ready <none> 5m v1.33.0 192.168.0.162 Ubuntu 22.04.3 LTS 5.15.0-91-generic5.2. 查看所有 Pods 状态(特别是 kube-system 命名空间)
bash
kubectl get pods -n kube-system预期输出(所有 Pod 状态应为 Running):
txt
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-7d9b5b5b5f-xyz12 1/1 Running 0 12m
calico-node-abc12 1/1 Running 0 12m
calico-node-def34 1/1 Running 0 10m
calico-node-ghi56 1/1 Running 0 10m
coredns-5d4d8b9c9f-abc12 1/1 Running 0 15m
coredns-5d4d8b9c9f-def34 1/1 Running 0 15m
etcd-master 1/1 Running 0 15m
kube-apiserver-master 1/1 Running 0 15m
kube-controller-manager-master 1/1 Running 0 15m
kube-proxy-abc12 1/1 Running 0 15m
kube-proxy-def34 1/1 Running 0 5m
kube-proxy-ghi56 1/1 Running 0 5m
kube-scheduler-master 1/1 Running 0 15m5.3. 查看所有命名空间的 Pods
bash
kubectl get pods --all-namespaces5.4. 检查集群健康状态
bash
kubectl get cs预期输出:
txt
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy ok提示
较新版本的 Kubernetes 中 kubectl get cs 可能返回 unhealthy,这是已知问题,不影响集群正常运行。建议使用 kubectl get componentstatuses 或直接检查核心 Pod 状态。
5.5. 检查 kubelet 服务状态(在所有节点上)
bash
systemctl status kubelet预期输出应包含 active (running)。
5.6. 验证 DNS 解析是否正常
创建一个临时 Pod 用于测试 DNS:
bash
kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup kubernetes.default预期输出:
txt
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default
Address 1: 10.96.0.15.7. 验证 Pod 网络通信
创建一个测试 Nginx Pod:
bash
kubectl create deployment nginx --image=nginx:alpine
kubectl expose deployment nginx --port=80 --type=ClusterIP
kubectl get svc nginx预期输出:
txt
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.96.123.45 <none> 80/TCP 10s5.8. 查看集群资源使用情况(如果已安装 metrics-server)
bash
kubectl top nodes
kubectl top pods --all-namespaces说明
如果未安装 metrics-server,kubectl top 命令会报错。这是正常的,metrics-server 需要单独安装。
6. 安装验证清单
| 检查项 | 验证命令 | 预期结果 |
|---|---|---|
| 节点状态 | kubectl get nodes | 所有节点 Ready |
| 核心 Pods | kubectl get pods -n kube-system | 所有 Pod Running |
| DNS 解析 | nslookup kubernetes.default | 返回正确的 ClusterIP |
| Pod 网络 | 创建测试 Nginx Pod | Pod 能正常启动并访问 |
| kubelet 服务 | systemctl status kubelet | active (running) |
7. 常见问题排查
如果节点状态一直为 NotReady,按以下顺序排查:
检查网络插件是否正常安装
bashkubectl get pods -n kube-system | grep calico查看节点详细信息
bashkubectl describe node <node-name>查看 kubelet 日志
bashjournalctl -u kubelet -f --lines=50检查 CNI 配置
bashls /etc/cni/net.d/检查容器运行时状态
bashsystemctl status containerd ctr -n=k8s.io containers ls
至此,Kubernetes v1.33.0 离线三节点集群已安装完成!🎉
