Kubernetes 集群安装指南(2 节点架构)
本文档详细介绍如何在 2 个节点(1 master + 1 node)上安装 Kubernetes 集群。
文档内容详尽,适合新手从零开始部署。
⚠️ 版本说明(2026年6月更新)
Kubernetes 版本会持续更新,本文档以 v1.33.12 为示例版本。
当前可用版本:v1.36.1、v1.35.5、v1.34.8、v1.33.12
请根据实际需求选择版本,建议使用稳定版本。安装时将文档中的
v1.33.12替换为您选择的版本号即可。
目录
1. 架构概述
1.1 集群架构图
┌─────────────────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────┐ ┌────────────────────────┐ │
│ │ master1 │ │ node1 │ │
│ │ (控制面节点) │ │ (工作节点) │ │
│ ├────────────────────────┤ ├────────────────────────┤ │
│ │ │ │ │ │
│ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │
│ │ │ kube-apiserver │ │ │ │ kubelet │ │ │
│ │ │ (API 服务) │ │ │ │ (节点代理) │ │ │
│ │ └──────────────────┘ │ │ └──────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │
│ │ │ kube-scheduler │ │ │ │ kube-proxy │ │ │
│ │ │ (调度器) │ │ │ │ (网络代理) │ │ │
│ │ └──────────────────┘ │ │ └──────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │
│ │ │ kube-controller │ │ │ │ containerd │ │ │
│ │ │ (控制器) │ │ │ │ (容器运行时) │ │ │
│ │ └──────────────────┘ │ │ └──────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │
│ │ │ etcd │ │ │ │ Pods │ │ │
│ │ │ (数据存储) │ │ │ │ (工作负载) │ │ │
│ │ └──────────────────┘ │ │ └──────────────────┘ │ │
│ │ │ │ │ │
│ └────────────────────────┘ └────────────────────────┘ │
│ │
│ IP: 192.168.x.x IP: 192.168.x.y │
│ │
└─────────────────────────────────────────────────────────────────┘
1.2 组件说明
| 组件 | 所在节点 | 说明 |
|---|---|---|
| kube-apiserver | master | Kubernetes API 入口,所有操作都通过它 |
| kube-scheduler | master | 负责调度 Pod 到合适的节点 |
| kube-controller-manager | master | 运行控制器,维护集群状态 |
| etcd | master | 分布式键值存储,保存集群所有数据 |
| kubelet | master + node | 节点代理,管理本节点上的 Pod |
| kube-proxy | master + node | 网络代理,实现 Service 功能 |
| containerd | master + node | 容器运行时,负责运行容器 |
1.3 节点角色
| 节点 | 角色 | 职责 |
|---|---|---|
| master1 | 控制面 (Control Plane) | 管理集群状态、调度、API 服务 |
| node1 | 工作节点 (Worker Node) | 运行应用 Pod |
2. 系统要求
2.1 硬件要求
| 节点 | CPU | 内存 | 磁盘 |
|---|---|---|---|
| master1 | ≥ 2 核 | ≥ 4 GB | ≥ 50 GB |
| node1 | ≥ 2 核 | ≥ 4 GB | ≥ 100 GB |
2.2 软件要求
| 项目 | 要求 |
|---|---|
| 操作系统 | Ubuntu 20.04/22.04、CentOS 7/8、Debian 10+ |
| 内核版本 | ≥ 4.18(推荐 5.x) |
| 架构 | amd64 或 arm64 |
2.3 网络要求
| 项目 | 要求 |
|---|---|
| 节点互通 | 所有节点之间网络互通 |
| 端口开放 | 见下方端口表 |
| 唯一 IP | 每个节点有唯一 IP 地址 |
| 主机名 | 每个节点有唯一主机名 |
2.4 端口要求
Master 节点端口:
| 端口 | 协议 | 组件 | 说明 |
|---|---|---|---|
| 6443 | TCP | kube-apiserver | API Server(必须开放) |
| 2379-2380 | TCP | etcd | etcd 服务端口 |
| 10250 | TCP | kubelet | Kubelet API |
| 10251 | TCP | kube-scheduler | Scheduler |
| 10252 | TCP | kube-controller | Controller Manager |
| 10257 | TCP | kube-controller | Controller Manager (v1.22+) |
| 10259 | TCP | kube-scheduler | Scheduler (v1.22+) |
Worker 节点端口:
| 端口 | 协议 | 组件 | 说明 |
|---|---|---|---|
| 10250 | TCP | kubelet | Kubelet API |
| 10256 | TCP | kube-proxy | Kube Proxy |
| 30000-32767 | TCP | NodePort | NodePort Service 端口范围 |
3. 环境准备
⚠️ 重要:以下步骤需要在 所有节点(master1 和 node1)上执行!
3.1 登录节点
# 登录 master 节点
ssh root@master1_ip
# 登录 worker 节点
ssh root@node1_ip
3.2 设置主机名
在 master1 上执行:
hostnamectl set-hostname master1
# 验证
hostname
# 输出: master1
在 node1 上执行:
hostnamectl set-hostname node1
# 验证
hostname
# 输出: node1
3.3 配置 hosts 文件
在所有节点上执行:
# 编辑 hosts 文件
cat >> /etc/hosts << EOF
192.168.x.x master1
192.168.y.y node1
EOF
⚠️ 注意:将
192.168.x.x和192.168.y.y替换为实际的 IP 地址。
验证:
# 测试解析
ping master1
ping node1
3.4 关闭 Swap
为什么要关闭 Swap?
| 原因 | 说明 |
|---|---|
| 性能 | Swap 会导致内存交换,影响 Kubernetes 性能 |
| 调度 | Kubernetes 调度器假设节点有固定内存 |
| 官方要求 | Kubernetes 官方文档明确要求 |
执行关闭:
# 1. 立即关闭所有 swap
swapoff -a
# 2. 永久关闭(修改 fstab)
sed -i 's|^/swap.img|# /swap.img|' /etc/fstab
# 或者注释所有 swap 行
sed -i '/swap/s/^/#/' /etc/fstab
# 3. 验证(Swap 应该为 0)
free -h | grep Swap
# 期望输出: Swap: 0B 0B 0B
3.5 关闭防火墙
Ubuntu/Debian:
# 检查防火墙状态
ufw status
# 关闭防火墙
ufw disable
# 验证
ufw status
# 输出: Status: inactive
CentOS/RHEL:
# 停止并禁用防火墙
systemctl stop firewalld
systemctl disable firewalld
# 验证
systemctl status firewalld
💡 提示:如果生产环境需要防火墙,请配置规则开放所需端口,而不是直接关闭。
3.6 关闭 SELinux(CentOS/RHEL)
# 临时关闭
setenforce 0
# 永久关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 验证
getenforce
# 输出: Disabled 或 Permissive
3.7 时间同步
为什么需要时间同步?
核心目的:保证所有节点时间一致。
| 场景 | 如果时间不同步会发生什么 |
|---|---|
| TLS 证书验证 | 证书有效期验证失败,导致节点无法加入集群 |
| 日志分析 | 不同节点日志时间戳对不上,排查问题困难 |
| 调度决策 | 调度器可能做出错误判断 |
| etcd 数据 | 分布式数据一致性出问题 |
时间同步示意图
时间同步的作用:
──────────────────────────────────────────────
master1 时间: 2026-06-17 10:00:00
node1 时间: 2026-06-17 10:00:00 ← 必须一致
──────────────────────────────────────────────
如果不一致:
──────────────────────────────────────────────
master1 时间: 2026-06-17 10:00:00
node1 时间: 2026-06-17 09:50:00 ← 相差 10 分钟
──────────────────────────────────────────────
→ TLS 证书验证失败
→ 节点无法加入集群
→ 日志时间戳错乱
安装并配置 NTP:
# Ubuntu/Debian
apt update
apt install -y chrony
# CentOS/RHEL
yum install -y chrony
配置时间同步服务器:
# 编辑配置文件
cat > /etc/chrony/chrony.conf << EOF
server ntp.aliyun.com iburst
server ntp.tencent.com iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
EOF
# 重启服务
systemctl restart chronyd
systemctl enable chronyd
# 验证时间同步
chronyc sources -v
手动同步时间(可选):
# 安装 ntpdate
apt install -y ntpdate # Ubuntu/Debian
yum install -y ntpdate # CentOS/RHEL
# 同步时间
ntpdate ntp.aliyun.com
# 查看时间
date
简化验证
# 在 master1 上查看时间
date
# 在 node1 上查看时间
date
# 两者时间应该基本一致(误差最好在 1 秒内)
结论
| 场景 | 建议 |
|---|---|
| 生产环境 | 使用 chrony 自动同步,长期保持一致 |
| 测试环境 | 手动同步一次即可,或简单验证时间一致 |
| 时间误差要求 | 最好在 1 秒内,最多不超过几分钟 |
💡 一句话理解:时间同步的核心目的就是保证所有节点时间一致,防止 TLS 证书验证失败和日志时间戳错乱。
3.8 配置内核参数
为什么要配置?
Kubernetes 需要特定的内核参数来支持:
- 网络功能(网桥、IP 转发)
- 容器网络通信
执行配置:
# 加载必要的内核模块
cat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# 立即加载模块
modprobe overlay
modprobe br_netfilter
# 验证模块加载
lsmod | grep -E "overlay|br_netfilter"
配置内核网络参数:
# 设置 sysctl 参数
cat << EOF | tee /etc/sysctl.d/k8s.conf
# 网桥网络调用 iptables
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# IPv4 转发
net.ipv4.ip_forward = 1
# 禁用 IPv6(可选)
net.ipv6.conf.all.disable_ipv6 = 1
EOF
# 应用配置
sysctl --system
# 验证关键参数
sysctl net.bridge.bridge-nf-call-iptables
sysctl net.bridge.bridge-nf-call-ip6tables
sysctl net.ipv4.ip_forward
# 以上三个参数都应该输出 1
3.9 环境准备验证脚本
一键验证脚本:
#!/bin/bash
echo "========== 环境检查 =========="
# 检查 Swap
echo -e "\n[1] Swap 状态:"
swap_total=$(free -m | awk '/Swap/{print $2}')
if [ "$swap_total" -eq 0 ]; then
echo "✅ Swap 已关闭"
else
echo "❌ Swap 未关闭,当前: ${swap_total}MB"
fi
# 检查防火墙
echo -e "\n[2] 防火墙状态:"
if command -v ufw &> /dev/null; then
ufw_status=$(ufw status | grep -o "inactive\|active")
[ "$ufw_status" == "inactive" ] && echo "✅ UFW 已关闭" || echo "❌ UFW 未关闭"
elif command -v firewall-cmd &> /dev/null; then
fw_status=$(systemctl is-active firewalld)
[ "$fw_status" == "inactive" ] && echo "✅ Firewalld 已关闭" || echo "❌ Firewalld 未关闭"
else
echo "✅ 未检测到防火墙"
fi
# 检查内核模块
echo -e "\n[3] 内核模块:"
lsmod | grep -q overlay && echo "✅ overlay 已加载" || echo "❌ overlay 未加载"
lsmod | grep -q br_netfilter && echo "✅ br_netfilter 已加载" || echo "❌ br_netfilter 未加载"
# 检查内核参数
echo -e "\n[4] 内核参数:"
[ "$(sysctl -n net.bridge.bridge-nf-call-iptables)" -eq 1 ] && echo "✅ bridge-nf-call-iptables = 1" || echo "❌ bridge-nf-call-iptables 未设置"
[ "$(sysctl -n net.ipv4.ip_forward)" -eq 1 ] && echo "✅ ip_forward = 1" || echo "❌ ip_forward 未设置"
# 检查时间同步
echo -e "\n[5] 时间同步:"
systemctl is-active chronyd &> /dev/null && echo "✅ chrony 运行中" || echo "⚠️ chrony 未运行"
echo -e "\n========== 检查完成 =========="
保存并执行:
# 保存脚本
cat > /root/check_env.sh << 'EOF'
# ... 上面的脚本内容 ...
EOF
# 添加执行权限
chmod +x /root/check_env.sh
# 执行检查
/root/check_env.sh
4. 安装 Containerd
⚠️ 重要:以下步骤需要在 所有节点 上执行!
4.1 Containerd 简介
什么是 Containerd?
Containerd 是一个工业级的容器运行时,它是 Kubernetes 运行容器所必需的组件。
┌─────────────────────────────────────────────────────────────┐
│ 容器运行时架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Kubernetes ──────► containerd ──────► runc ──────► 容器 │
│ (编排) (运行时) (执行) (进程) │
│ │
└─────────────────────────────────────────────────────────────┘
为什么选择 Containerd?
| 原因 | 说明 |
|---|---|
| 官方推荐 | Kubernetes 官方推荐的标准运行时 |
| 性能优秀 | 比 Docker 更轻量,性能更好 |
| 稳定可靠 | 由 CNCF 维护,生产级别稳定 |
4.2 安装 Containerd
Ubuntu/Debian:
# 更新软件源
apt update
# 安装依赖
apt install -y ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 添加软件源
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# 更新并安装 containerd
apt update
apt install -y containerd.io
CentOS/RHEL:
# 安装依赖
yum install -y yum-utils
# 添加 Docker 软件源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装 containerd
yum install -y containerd.io
验证安装:
# 查看版本
containerd --version
# 输出示例:
# containerd github.com/containerd/containerd v1.7.2 ...
4.3 配置 Containerd
生成默认配置:
# 创建配置目录
mkdir -p /etc/containerd
# 生成默认配置
containerd config default > /etc/containerd/config.toml
修改配置(重要):
# 编辑配置文件
vi /etc/containerd/config.toml
需要修改的内容:
# 1. 设置 SystemdCgroup = true(使用 systemd cgroup)
[plugins."io.containerd.grpc.v1.cri"]
...
[plugins."io.containerd.grpc.v1.cri".containerd]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true # 改为 true
# 2. 设置 sandbox 镜像(国内网络需要修改)
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9" # 使用阿里云镜像
一键配置脚本:
# 自动配置 containerd
cat > /etc/containerd/config.toml << EOF
version = 2
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry.aliyuncs.com"]
EOF
4.4 启动 Containerd
# 重启 containerd 服务
systemctl daemon-reload
systemctl restart containerd
# 设置开机自启
systemctl enable containerd
# 查看状态
systemctl status containerd
# 验证运行状态
# Active: active (running) 表示正常运行
4.5 安装 nerdctl(可选)
nerdctl 是 containerd 的命令行工具,类似 docker 命令:
# 下载 nerdctl
wget https://github.com/containerd/nerdctl/releases/download/v1.5.0/nerdctl-1.5.0-linux-amd64.tar.gz
# 解压
tar -xzf nerdctl-1.5.0-linux-amd64.tar.gz -C /usr/local/bin/
# 验证
nerdctl --version
5. 安装 Kubernetes 组件
⚠️ 重要:以下步骤需要在 所有节点 上执行!
5.1 Kubernetes 组件说明
| 组件 | 说明 | 安装位置 |
|---|---|---|
| kubeadm | 集群初始化工具 | 所有节点 |
| kubelet | 节点代理,管理 Pod | 所有节点 |
| kubectl | 命令行管理工具 | master(可选 node) |
5.2 添加 Kubernetes 软件源
Ubuntu/Debian:
# 更新软件源并安装依赖
apt update
apt install -y ca-certificates curl
# 添加 Kubernetes GPG 密钥
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | 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.33/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
CentOS/RHEL:
# 添加 Kubernetes 软件源
cat << EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key
EOF
5.3 安装 Kubernetes 组件
Ubuntu/Debian:
# 更新软件源
apt update
# 安装 kubeadm、kubelet、kubectl
apt install -y kubeadm kubelet kubectl
# 设置 kubelet 开机自启
systemctl enable kubelet
CentOS/RHEL:
# 安装组件
yum install -y kubeadm kubelet kubectl
# 设置 kubelet 开机自启
systemctl enable kubelet
5.4 验证安装
# 查看版本
kubeadm version
kubelet --version
kubectl version --client
# 输出示例:
# kubeadm version: &version.Info{Major:"1", Minor:"28", ...}
# Kubernetes v1.33.x
5.5 配置镜像加速(可选但推荐)
由于国内网络原因,建议配置镜像加速:
# 查看需要的镜像
kubeadm config images list
# 输出示例:
# registry.k8s.io/kube-apiserver:v1.33.12
# registry.k8s.io/kube-controller-manager:v1.33.12
# ...
使用阿里云镜像:
# 拉取镜像(使用阿里云镜像源)
kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
6. 初始化 Master 节点
⚠️ 重要:以下步骤 只在 master1 上执行!
6.1 初始化前检查
# 检查 kubelet 状态
systemctl status kubelet
# 检查 containerd 状态
systemctl status containerd
# 检查网络
ping node1
6.2 初始化集群
基础初始化命令:
# 初始化集群(替换为实际 IP)
kubeadm init \
--apiserver-advertise-address=192.168.x.x \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.33.12 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
参数说明:
| 参数 | 说明 |
|---|---|
--apiserver-advertise-address | API Server 监听地址(master 的 IP) |
--image-repository | 镜像仓库地址(国内使用阿里云) |
--kubernetes-version | Kubernetes 版本 |
--service-cidr | Service 网段 |
--pod-network-cidr | Pod 网段(需与 CNI 插件匹配) |
6.3 初始化过程详解
执行初始化后,你会看到类似输出:
[init] Using Kubernetes version: v1.33.12
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kube-apiserver to be up and running
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[mark-control-plane] Marking the node master1 as control-plane
[mark-control-plane] Marking the node master1 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane]
[bootstraptoken] Using tokens: ["abcdef.0123456789abcdef"]
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to get CSRs
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.x.x:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6.4 配置 kubectl
为 root 用户配置:
# 设置 KUBECONFIG 环境变量
export KUBECONFIG=/etc/kubernetes/admin.conf
# 永久配置(写入 bashrc)
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bashrc
source ~/.bashrc
为普通用户配置:
# 创建 .kube 目录
mkdir -p $HOME/.kube
# 复制配置文件
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 修改所有者
sudo chown $(id -u):$(id -g) $HOME/.kube/config
6.5 验证 Master 节点
# 查看节点状态
kubectl get nodes
# 输出示例:
# NAME STATUS ROLES AGE VERSION
# master1 NotReady control-plane 1m v1.33.12
# 查看集群组件状态
kubectl get cs
# 输出示例:
# NAME STATUS MESSAGE ERROR
# controller-manager Healthy ok
# scheduler Healthy ok
# etcd-0 Healthy {"health":"true"}
# 查看 Pod 状态
kubectl get pods -n kube-system
# 输出示例:
# NAME READY STATUS RESTARTS AGE
# coredns-xxxx-xxxx 0/1 Pending 0 1m
# coredns-xxxx-xxxx 0/1 Pending 0 1m
# etcd-master1 1/1 Running 0 1m
# kube-apiserver-master1 1/1 Running 0 1m
# kube-controller-manager-master1 1/1 Running 0 1m
# kube-proxy-xxxx 1/1 Running 0 1m
# kube-scheduler-master1 1/1 Running 0 1m
⚠️ 注意:此时节点状态为
NotReady,CoreDNS 为Pending,这是正常的,因为还没有安装网络插件。
6.6 保存 join 命令
重要!保存 node 加入集群的命令:
# 获取 join 命令
kubeadm token create --print-join-command
# 输出示例:
# kubeadm join 192.168.x.x:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:xxx
# 保存到文件
kubeadm token create --print-join-command > /root/k8s-join-command.sh
chmod +x /root/k8s-join-command.sh
7. 加入 Worker 节点
⚠️ 重要:以下步骤 只在 node1 上执行!
7.1 获取 join 命令
在 master1 上获取:
kubeadm token create --print-join-command
输出示例:
kubeadm join 192.168.x.x:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
7.2 在 node1 上执行 join
# 执行 join 命令(从 master 获取的完整命令)
kubeadm join 192.168.x.x:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
成功输出:
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config map with 'kubectl -n kube-system get cm kubeadm-config'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to 'apiserver' and a reply was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
7.3 验证节点加入
在 master1 上执行:
# 查看节点
kubectl get nodes
# 输出示例:
# NAME STATUS ROLES AGE VERSION
# master1 NotReady control-plane 10m v1.33.12
# node1 NotReady <none> 1m v1.33.12
⚠️ 注意:节点状态仍为
NotReady,需要安装网络插件后才会变为Ready。
8. 安装网络插件
⚠️ 重要:以下步骤 只在 master1 上执行!
8.1 网络插件选择
| 插件 | 特点 | 适用场景 |
|---|---|---|
| Calico | 性能好,功能全,支持网络策略 | 生产环境推荐 |
| Flannel | 简单易用,资源占用少 | 开发测试推荐 |
| Cilium | 基于 eBPF,功能强大 | 高级网络需求 |
8.2 安装 Calico(推荐)
# 下载 Calico 配置文件
curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml -O
# 应用配置
kubectl apply -f calico.yaml
等待 Calico Pod 启动:
# 查看 Calico Pod 状态
kubectl get pods -n kube-system | grep calico
# 输出示例:
# calico-node-xxxxx 1/1 Running 0 1m
# calico-kube-controllers-xxxxx 1/1 Running 0 1m
8.3 安装 Flannel(备选)
# 下载 Flannel 配置
curl https://raw.githubusercontent.com/flannel-io/flannel/v0.22.3/manifest/kube-flannel.yml -O
# 应用配置
kubectl apply -f kube-flannel.yml
8.4 验证网络插件
# 等待所有 Pod 运行
kubectl get pods -n kube-system
# 查看节点状态(应该变为 Ready)
kubectl get nodes
# 输出示例:
# NAME STATUS ROLES AGE VERSION
# master1 Ready control-plane 15m v1.33.12
# node1 Ready <none> 5m v1.33.12
9. 验证集群
9.1 检查集群状态
# 查看节点
kubectl get nodes -o wide
# 查看所有系统 Pod
kubectl get pods -n kube-system
# 查看组件状态
kubectl get cs
9.2 测试部署应用
创建测试 Deployment:
# 创建 nginx deployment
kubectl create deployment nginx --image=nginx
# 查看 deployment
kubectl get deployments
# 查看 pod
kubectl get pods
暴露服务:
# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看 service
kubectl get svc
# 输出示例:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20m
# nginx NodePort 10.96.xxx.xxx <none> 80:300xx/TCP 1m
访问测试:
# 获取 NodePort 端口
NODE_PORT=$(kubectl get svc nginx -o jsonpath='{.spec.ports[0].nodePort}')
# 访问测试(在任意节点执行)
curl http://node1:$NODE_PORT
# 或者直接访问
curl http://node1:300xx
9.3 查看集群信息
# 集群信息
kubectl cluster-info
# 输出示例:
# Kubernetes control plane is running at https://192.168.x.x:6443
# CoreDNS is running at https://192.168.x.x:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
# 查看资源使用
kubectl top nodes
# 查看所有资源
kubectl get all --all-namespaces
10. 常见问题排查
10.1 节点状态 NotReady
现象:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 NotReady control-plane 10m v1.33.12
排查步骤:
# 1. 检查网络插件是否安装
kubectl get pods -n kube-system | grep -E "calico|flannel"
# 2. 检查 kubelet 日志
journalctl -u kubelet -f
# 3. 检查节点详情
kubectl describe node master1
10.2 Pod 状态 Pending
现象:
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-xxxxx-xxxx 0/1 Pending 0 5m
排查步骤:
# 查看 Pod 详情
kubectl describe pod nginx-xxxxx-xxxx
# 常见原因:
# - 网络插件未安装
# - 资源不足(CPU/内存)
# - PVC 未绑定
10.3 Image Pull Failed
现象:
Failed to pull image "xxx": rpc error: code = Unknown desc = Error response from daemon: pull access denied
解决方案:
# 手动拉取镜像
crictl pull xxx
# 或使用国内镜像源
crictl pull registry.aliyuncs.com/google_containers/xxx
10.4 kubelet 启动失败
排查步骤:
# 查看 kubelet 状态
systemctl status kubelet
# 查看日志
journalctl -u kubelet -n 100
# 常见原因:
# - Swap 未关闭
# - containerd 未运行
# - 配置文件错误
10.5 重置集群
如果初始化失败,可以重置后重新初始化:
# 重置节点(在所有节点执行)
kubeadm reset -f
# 清理文件
rm -rf /etc/kubernetes/
rm -rf /var/lib/etcd/
rm -rf /var/lib/kubelet/
rm -rf $HOME/.kube/config
# 重启 containerd
systemctl restart containerd
附录 A:一键安装脚本
A.1 环境准备脚本
#!/bin/bash
# 文件名: prepare_env.sh
# 用途: 准备 Kubernetes 安装环境
set -e
echo "========== Kubernetes 环境准备 =========="
# 1. 关闭 Swap
echo "[1/7] 关闭 Swap..."
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
# 2. 关闭防火墙
echo "[2/7] 关闭防火墙..."
if command -v ufw &> /dev/null; then
ufw disable
fi
if command -v firewall-cmd &> /dev/null; then
systemctl stop firewalld
systemctl disable firewalld
fi
# 3. 配置内核模块
echo "[3/7] 配置内核模块..."
cat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 4. 配置内核参数
echo "[4/7] 配置内核参数..."
cat << EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# 5. 时间同步
echo "[5/7] 配置时间同步..."
apt install -y chrony || yum install -y chrony
systemctl restart chronyd
systemctl enable chronyd
# 6. 安装 containerd
echo "[6/7] 安装 containerd..."
apt install -y containerd.io || yum install -y containerd.io
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl restart containerd
systemctl enable containerd
# 7. 安装 Kubernetes 组件
echo "[7/7] 安装 Kubernetes 组件..."
apt install -y kubeadm kubelet kubectl || yum install -y kubeadm kubelet kubectl
systemctl enable kubelet
echo "========== 环境准备完成 =========="
echo "请执行 kubeadm init 初始化集群"
A.2 Master 初始化脚本
#!/bin/bash
# 文件名: init_master.sh
# 用途: 初始化 Kubernetes Master 节点
set -e
# 配置变量
MASTER_IP="${1:-$(hostname -I | awk '{print $1}')}"
K8S_VERSION="${2:-v1.33.12}"
POD_CIDR="${3:-10.244.0.0/16}"
echo "========== 初始化 Master 节点 =========="
echo "Master IP: $MASTER_IP"
echo "K8s Version: $K8S_VERSION"
echo "Pod CIDR: $POD_CIDR"
# 初始化集群
kubeadm init \
--apiserver-advertise-address=$MASTER_IP \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version $K8S_VERSION \
--pod-network-cidr=$POD_CIDR
# 配置 kubectl
export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bashrc
# 保存 join 命令
kubeadm token create --print-join-command > /root/k8s-join-command.sh
chmod +x /root/k8s-join-command.sh
echo "========== Master 初始化完成 =========="
echo "Join 命令已保存到: /root/k8s-join-command.sh"
附录 B:常用命令速查
| 命令 | 说明 |
|---|---|
kubectl get nodes | 查看节点 |
kubectl get pods -A | 查看所有 Pod |
kubectl get svc -A | 查看所有 Service |
kubectl describe node <name> | 查看节点详情 |
kubectl describe pod <name> | 查看 Pod 详情 |
kubectl logs <pod> | 查看 Pod 日志 |
kubectl exec -it <pod> -- bash | 进入 Pod |
kubectl apply -f xxx.yaml | 应用配置 |
kubectl delete -f xxx.yaml | 删除资源 |
kubeadm token create --print-join-command | 获取 join 命令 |
kubeadm reset -f | 重置节点 |
附录 C:离线安装指南
本章节详细介绍如何在无网络环境下安装 Kubernetes 集群。
C.1 离线安装概述
适用场景
| 场景 | 说明 |
|---|---|
| 内网环境 | 服务器无法访问外网 |
| 安全要求 | 生产环境不允许连接互联网 |
| 批量部署 | 多套环境统一安装包 |
离线安装流程图
┌─────────────────────────────────────────────────────────────────────────┐
│ 离线安装流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 第一步:准备 │ │ 第二步:传输 │ │ 第三步:安装 │ │
│ │ (有网机器) │ │ (移动介质) │ │ (无网机器) │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ • 下载系统包 │ │ • 打包离线文件 │ │ • 安装 RPM/DEB │ │
│ │ • 下载 K8s 组件 │ ──► │ • 拷贝到 U 盘 │ ──► │ • 导入容器镜像 │ │
│ │ • 下载容器镜像 │ │ 或内网传输 │ │ • 初始化集群 │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
C.2 在 Windows 上下载离线包(推荐)
💡 推荐场景:使用有网络的 Windows 电脑下载,然后传输到无网络的 Linux 服务器安装。
C.2.1 Windows 下载方式概述
┌─────────────────────────────────────────────────────────────────────────┐
│ Windows 下载离线包流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Windows 电脑 │ │ 移动介质 │ │ Linux 服务器 │ │
│ │ (有网络) │ │ (U盘/移动硬盘) │ │ (无网络) │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ • 浏览器下载 │ │ • 复制整个目录 │ │ • 解压安装包 │ │
│ │ • 下载工具下载 │ ──► │ 到移动介质 │ ──► │ • 执行安装脚本 │ │
│ │ • 直链批量下载 │ │ • 或网络传输 │ │ • 导入镜像 │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
C.2.2 创建 Windows 目录结构
在 Windows 上创建以下目录结构:
D:\k8s-offline\
├── packages\
│ ├── ubuntu\ # Ubuntu/Debian 安装包
│ ├── centos\ # CentOS/RHEL 安装包
│ ├── containerd\ # Containerd 安装包
│ └── kubernetes\ # Kubernetes 组件
├── images\ # 容器镜像 tar 包
├── scripts\ # 安装脚本
└── configs\ # 配置文件
创建目录(PowerShell):
# 在 PowerShell 中执行
$basePath = "D:\k8s-offline"
# 创建目录结构
New-Item -ItemType Directory -Path "$basePath\packages\ubuntu" -Force
New-Item -ItemType Directory -Path "$basePath\packages\centos" -Force
New-Item -ItemType Directory -Path "$basePath\packages\containerd" -Force
New-Item -ItemType Directory -Path "$basePath\packages\kubernetes" -Force
New-Item -ItemType Directory -Path "$basePath\images" -Force
New-Item -ItemType Directory -Path "$basePath\scripts" -Force
New-Item -ItemType Directory -Path "$basePath\configs" -Force
# 查看目录结构
Get-ChildItem -Path $basePath -Recurse -Directory
C.2.3 下载 Containerd 安装包
Ubuntu/Debian (amd64 架构):
| 组件 | 下载地址 |
|---|---|
| containerd.io | https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/containerd.io_1.7.2-1_amd64.deb |
| containerd.io (arm64) | https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/arm64/containerd.io_1.7.2-1_arm64.deb |
CentOS/RHEL 8 (x86_64 架构):
| 组件 | 下载地址 |
|---|---|
| containerd.io | https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.7.2-3.1.el8.x86_64.rpm |
| containerd.io (aarch64) | https://download.docker.com/linux/centos/8/aarch64/stable/Packages/containerd.io-1.7.2-3.1.el8.aarch64.rpm |
使用 PowerShell 批量下载:
# 设置下载目录
$downloadPath = "D:\k8s-offline\packages\containerd"
# Ubuntu 22.04 amd64 下载链接
$ubuntuUrls = @(
"https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/containerd.io_1.7.2-1_amd64.deb"
)
# CentOS 8 x86_64 下载链接
$centosUrls = @(
"https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.7.2-3.1.el8.x86_64.rpm"
)
# 下载 Ubuntu 包
foreach ($url in $ubuntuUrls) {
$fileName = Split-Path $url -Leaf
$output = Join-Path $downloadPath $fileName
Write-Host "下载: $fileName"
Invoke-WebRequest -Uri $url -OutFile $output
}
# 下载 CentOS 包
foreach ($url in $centosUrls) {
$fileName = Split-Path $url -Leaf
$output = Join-Path $downloadPath $fileName
Write-Host "下载: $fileName"
Invoke-WebRequest -Uri $url -OutFile $output
}
Write-Host "Containerd 下载完成!"
Get-ChildItem $downloadPath
C.2.4 下载 Kubernetes 安装包
⚠️ 重要提示:Kubernetes 官方 CDN 有访问限制,推荐使用"在有网Linux机器上下载"或"下载二进制文件"方式。
方法1:在有网络的 Linux 机器上下载(推荐)
Ubuntu/Debian:
# 添加 Kubernetes 软件源
mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | 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.33/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
# 更新并下载
apt-get update
mkdir -p /root/k8s-packages
cd /root/k8s-packages
# 下载指定版本
apt-get download kubeadm=1.33.12-1.1
apt-get download kubelet=1.33.12-1.1
apt-get download kubectl=1.33.12-1.1
# 打包
tar -czvf k8s-packages.tar.gz *.deb
CentOS/RHEL:
# 添加 Kubernetes 软件源
cat << EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
enabled=1
gpgcheck=0
EOF
# 下载
mkdir -p /root/k8s-packages
yumdownloader --destdir=/root/k8s-packages kubeadm-1.33.12-1.1
yumdownloader --destdir=/root/k8s-packages kubelet-1.33.12-1.1
yumdownloader --destdir=/root/k8s-packages kubectl-1.33.12-1.1
# 打包
cd /root/k8s-packages
tar -czvf k8s-packages.tar.gz *.rpm
方法2:下载二进制文件(Windows 可直接下载)
Kubernetes 官方提供二进制文件,无需通过包管理器。
官方下载站点:
| 网站 | 说明 |
|---|---|
| https://dl.k8s.io/ | Kubernetes 官方二进制文件下载站,可浏览所有版本 |
| https://github.com/kubernetes/kubernetes/releases | GitHub Release 页面 |
访问 https://dl.k8s.io/ 自行搜索下载步骤:
- 打开浏览器,访问 https://dl.k8s.io/
- 查看当前可用版本(截至 2026年6月):
- v1.36.1(最新)
- v1.35.5
- v1.34.8
- v1.33.12
- 目录结构说明:
dl.k8s.io/ ├── release/ # 正式发布版本 │ ├── v1.33.12/ # 具体版本(示例) │ │ └── bin/ │ │ └── linux/ │ │ ├── amd64/ # x86_64 架构 │ │ │ ├── kubeadm │ │ │ ├── kubelet │ │ │ └── kubectl │ │ └── arm64/ # ARM64 架构 │ │ ├── kubeadm │ │ ├── kubelet │ │ └── kubectl │ └── ... ├── ci/ # CI 构建(开发测试用) └── stable.txt # 当前稳定版本号 - 点击进入对应版本目录,如
release/→v1.33.12/→bin/→linux/→amd64/或arm64/ - 下载需要的文件:
kubeadm、kubelet、kubectl
💡 提示:选择版本时建议使用稳定版本(如 v1.33.12),避免使用最新版本可能存在的不稳定问题。
直接下载地址(以 v1.33.12 为例):
| 组件 | 架构 | 下载地址 |
|---|---|---|
| kubeadm | amd64 | https://dl.k8s.io/release/v1.33.12/bin/linux/amd64/kubeadm |
| kubelet | amd64 | https://dl.k8s.io/release/v1.33.12/bin/linux/amd64/kubelet |
| kubectl | amd64 | https://dl.k8s.io/release/v1.33.12/bin/linux/amd64/kubectl |
| kubeadm | arm64 | https://dl.k8s.io/release/v1.33.12/bin/linux/arm64/kubeadm |
| kubelet | arm64 | https://dl.k8s.io/release/v1.33.12/bin/linux/arm64/kubelet |
| kubectl | arm64 | https://dl.k8s.io/release/v1.33.12/bin/linux/arm64/kubectl |
PowerShell 批量下载二进制文件:
$downloadPath = "D:\k8s-offline\packages\kubernetes"
$version = "v1.33.12" # 根据需要修改版本号,可选:v1.36.1, v1.35.5, v1.34.8, v1.33.12
$arch = "amd64" # 改为 arm64 下载 ARM 版本
# 创建目录
New-Item -ItemType Directory -Path $downloadPath -Force | Out-Null
# 下载链接
$urls = @(
"https://dl.k8s.io/release/$version/bin/linux/$arch/kubeadm",
"https://dl.k8s.io/release/$version/bin/linux/$arch/kubelet",
"https://dl.k8s.io/release/$version/bin/linux/$arch/kubectl"
)
Write-Host "========== 下载 Kubernetes 二进制文件 =========="
foreach ($url in $urls) {
$fileName = Split-Path $url -Leaf
$output = Join-Path $downloadPath $fileName
Write-Host "下载: $fileName"
try {
Invoke-WebRequest -Uri $url -OutFile $output -ErrorAction Stop
Write-Host " ✓ 完成" -ForegroundColor Green
} catch {
Write-Host " ✗ 失败: $_" -ForegroundColor Red
}
}
Write-Host "`n下载完成!文件列表:"
Get-ChildItem $downloadPath
在目标 Linux 上安装二进制文件:
# 复制到系统目录
cp kubeadm kubelet kubectl /usr/local/bin/
# 添加执行权限
chmod +x /usr/local/bin/kubeadm /usr/local/bin/kubelet /usr/local/bin/kubectl
# 创建 kubelet systemd 服务(必须)
cat > /etc/systemd/system/kubelet.service << 'EOF'
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/
After=network.target
[Service]
ExecStart=/usr/local/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# 重载 systemd
systemctl daemon-reload
systemctl enable kubelet
# 验证
kubeadm version
kubelet --version
kubectl version --client
方法3:使用阿里云镜像
# Ubuntu/Debian
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
echo 'deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main' | tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get download kubeadm=1.33.12-00
apt-get download kubelet=1.33.12-00
apt-get download kubectl=1.33.12-00
Get-ChildItem $downloadPath
#### C.2.5 下载 Kubernetes 依赖包(Ubuntu)
> ⚠️ **重要提示**:Ubuntu 依赖包版本会更新,建议使用"在有网Linux机器上下载"的方法最可靠。
**方法1:在有网络的 Linux 机器上下载(最可靠)**
```bash
# 在有网络的 Ubuntu 机器上执行
mkdir -p /root/ubuntu-deps
cd /root/ubuntu-deps
# 更新软件源
apt-get update
# 下载所有依赖
apt-get download conntrack
apt-get download libnetfilter-conntrack3
apt-get download libnfnetlink0
apt-get download socat
apt-get download ipset
apt-get download libipset13
apt-get download ebtables
# 下载依赖的依赖
apt-cache depends conntrack | grep Depends | awk '{print $2}' | xargs apt-get download
apt-cache depends ipset | grep Depends | awk '{print $2}' | xargs apt-get download
# 打包
tar -czvf ubuntu-deps.tar.gz *.deb
# 然后将 ubuntu-deps.tar.gz 拷贝到 Windows,再传输到目标 Linux
方法2:手动搜索下载
- 访问 Ubuntu Packages 网站:https://packages.ubuntu.com/
- 搜索以下包名:
| 依赖包 | 搜索关键词 | 说明 |
|---|---|---|
| conntrack | conntrack | 连接追踪工具 |
| libnetfilter-conntrack3 | libnetfilter-conntrack | conntrack 库依赖 |
| libnfnetlink0 | libnfnetlink | 底层网络库 |
| socat | socat | Socket 工具 |
| ipset | ipset | IP 集合工具 |
| libipset13 | libipset | ipset 库依赖 |
| ebtables | ebtables | 以太网桥防火墙 |
- 选择对应版本(jammy=22.04, focal=20.04)和架构(amd64/arm64)
- 下载
.deb文件
方法3:阿里云镜像浏览下载
访问:https://mirrors.aliyun.com/ubuntu/pool/main/
按目录浏览:
c/conntrack-tools/- conntracks/socat/- socati/ipset/- ipsete/ebtables/- ebtables
C.2.6 下载 Kubernetes 依赖包(CentOS)
⚠️ 重要提示:CentOS 8 已停止维护,建议使用"在有网Linux机器上下载"的方法。
方法1:在有网络的 Linux 机器上下载(最可靠)
# 在有网络的 CentOS/RHEL 机器上执行
mkdir -p /root/centos-deps
cd /root/centos-deps
# 安装下载工具
yum install -y yum-utils
# 下载依赖包(自动解决依赖)
yumdownloader --resolve --destdir=/root/centos-deps conntrack
yumdownloader --resolve --destdir=/root/centos-deps socat
yumdownloader --resolve --destdir=/root/centos-deps ipset
yumdownloader --resolve --destdir=/root/centos-deps ebtables
# 打包
tar -czvf centos-deps.tar.gz *.rpm
# 然后将 centos-deps.tar.gz 拷贝到 Windows,再传输到目标 Linux
方法2:CentOS Vault 镜像(CentOS 8 已归档)
CentOS 8 包已迁移到 vault 仓库:
$downloadPath = "D:\k8s-offline\packages\centos"
# 使用阿里云 vault 镜像
$centosUrls = @(
"https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/conntrack-tools-1.4.4-10.el8.x86_64.rpm",
"https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/libnetfilter_conntrack-1.0.6-5.el8.x86_64.rpm",
"https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/libnfnetlink-1.0.1-7.el8.x86_64.rpm",
"https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/socat-1.7.4.1-1.el8.x86_64.rpm",
"https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/ipset-7.1-1.el8.x86_64.rpm",
"https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/ipset-libs-7.1-1.el8.x86_64.rpm",
"https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/ebtables-2.0.11-5.el8.x86_64.rpm"
)
foreach ($url in $centosUrls) {
$fileName = Split-Path $url -Leaf
$output = Join-Path $downloadPath $fileName
Write-Host "下载: $fileName"
try {
Invoke-WebRequest -Uri $url -OutFile $output -ErrorAction Stop
Write-Host " ✓ 完成" -ForegroundColor Green
} catch {
Write-Host " ✗ 失败,请手动下载" -ForegroundColor Red
Write-Host " 访问: https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/"
}
}
Get-ChildItem $downloadPath
方法3:使用 Rocky Linux 镜像(CentOS 兼容替代)
$downloadPath = "D:\k8s-offline\packages\centos"
# Rocky Linux 8 与 CentOS 8 完全兼容
$rockyUrls = @(
"https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/Packages/c/conntrack-tools-1.4.4-10.el8.x86_64.rpm",
"https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/Packages/l/libnetfilter_conntrack-1.0.6-5.el8.x86_64.rpm",
"https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/Packages/l/libnfnetlink-1.0.1-7.el8.x86_64.rpm",
"https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/Packages/s/socat-1.7.4.1-1.el8.x86_64.rpm"
)
foreach ($url in $rockyUrls) {
$fileName = Split-Path $url -Leaf
$output = Join-Path $downloadPath $fileName
Write-Host "下载: $fileName"
try {
Invoke-WebRequest -Uri $url -OutFile $output -ErrorAction Stop
Write-Host " ✓ 完成" -ForegroundColor Green
} catch {
Write-Host " ✗ 失败: $_" -ForegroundColor Red
}
}
方法4:pkgs.org 网站搜索下载
- 访问:https://pkgs.org/
- 搜索包名(如
conntrack-tools) - 选择 CentOS 8 或 Rocky Linux 8 版本
- 下载 RPM 包
C.2.7 下载容器镜像(使用 Docker Desktop)
前提条件:
- 安装 Docker Desktop for Windows
- Docker Desktop 已启动并运行
步骤1:拉取 Kubernetes 核心镜像
在 PowerShell 或 CMD 中执行:
# 设置版本
$k8sVersion = "v1.33.12"
# 使用阿里云镜像加速
$registry = "registry.aliyuncs.com/google_containers"
# 拉取 Kubernetes 核心镜像
docker pull ${registry}/kube-apiserver:${k8sVersion}
docker pull ${registry}/kube-controller-manager:${k8sVersion}
docker pull ${registry}/kube-scheduler:${k8sVersion}
docker pull ${registry}/kube-proxy:${k8sVersion}
docker pull ${registry}/pause:3.9
docker pull ${registry}/etcd:3.5.9-0
docker pull ${registry}/coredns:v1.10.1
# 查看已拉取镜像
docker images
步骤2:拉取 Calico 网络插件镜像
# Calico 版本
$calicoVersion = "v3.26.1"
# 拉取 Calico 镜像
docker pull docker.io/calico/cni:${calicoVersion}
docker pull docker.io/calico/node:${calicoVersion}
docker pull docker.io/calico/kube-controllers:${calicoVersion}
# 查看镜像
docker images | Select-String "calico"
步骤3:导出镜像为 tar 文件
# 设置导出目录
$exportPath = "D:\k8s-offline\images"
$k8sVersion = "v1.33.12"
$calicoVersion = "v3.26.1"
$registry = "registry.aliyuncs.com/google_containers"
# 导出 Kubernetes 核心镜像
docker save -o "${exportPath}\kube-apiserver.tar" ${registry}/kube-apiserver:${k8sVersion}
docker save -o "${exportPath}\kube-controller-manager.tar" ${registry}/kube-controller-manager:${k8sVersion}
docker save -o "${exportPath}\kube-scheduler.tar" ${registry}/kube-scheduler:${k8sVersion}
docker save -o "${exportPath}\kube-proxy.tar" ${registry}/kube-proxy:${k8sVersion}
docker save -o "${exportPath}\pause.tar" ${registry}/pause:3.9
docker save -o "${exportPath}\etcd.tar" ${registry}/etcd:3.5.9-0
docker save -o "${exportPath}\coredns.tar" ${registry}/coredns:v1.10.1
# 导出 Calico 镜像
docker save -o "${exportPath}\calico-cni.tar" docker.io/calico/cni:${calicoVersion}
docker save -o "${exportPath}\calico-node.tar" docker.io/calico/node:${calicoVersion}
docker save -o "${exportPath}\calico-kube-controllers.tar" docker.io/calico/kube-controllers:${calicoVersion}
Write-Host "镜像导出完成!"
Get-ChildItem $exportPath
一键导出脚本:
# 保存为 export-images.ps1
$exportPath = "D:\k8s-offline\images"
$k8sVersion = "v1.33.12"
$calicoVersion = "v3.26.1"
$registry = "registry.aliyuncs.com/google_containers"
# 定义镜像列表
$images = @(
@{Name="kube-apiserver"; Image="${registry}/kube-apiserver:${k8sVersion}"},
@{Name="kube-controller-manager"; Image="${registry}/kube-controller-manager:${k8sVersion}"},
@{Name="kube-scheduler"; Image="${registry}/kube-scheduler:${k8sVersion}"},
@{Name="kube-proxy"; Image="${registry}/kube-proxy:${k8sVersion}"},
@{Name="pause"; Image="${registry}/pause:3.9"},
@{Name="etcd"; Image="${registry}/etcd:3.5.9-0"},
@{Name="coredns"; Image="${registry}/coredns:v1.10.1"},
@{Name="calico-cni"; Image="docker.io/calico/cni:${calicoVersion}"},
@{Name="calico-node"; Image="docker.io/calico/node:${calicoVersion}"},
@{Name="calico-kube-controllers"; Image="docker.io/calico/kube-controllers:${calicoVersion}"}
)
Write-Host "========== 开始拉取和导出镜像 =========="
foreach ($img in $images) {
Write-Host "`n处理: $($img.Name)" -ForegroundColor Cyan
# 拉取镜像
Write-Host " 拉取镜像..."
docker pull $img.Image
# 导出镜像
$output = Join-Path $exportPath "$($img.Name).tar"
Write-Host " 导出到: $output"
docker save -o $output $img.Image
if ($LASTEXITCODE -eq 0) {
Write-Host " ✓ 完成" -ForegroundColor Green
} else {
Write-Host " ✗ 失败" -ForegroundColor Red
}
}
Write-Host "`n========== 导出完成 =========="
Get-ChildItem $exportPath | Format-Table Name, Length
C.2.8 下载 Calico YAML 配置
直接下载:
在浏览器中访问:
https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
保存到 D:\k8s-offline\configs\calico.yaml
PowerShell 下载:
$downloadPath = "D:\k8s-offline\configs"
$calicoUrl = "https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml"
Write-Host "下载 Calico YAML 配置..."
Invoke-WebRequest -Uri $calicoUrl -OutFile "$downloadPath\calico.yaml"
Write-Host "下载完成!"
Get-Content "$downloadPath\calico.yaml" | Select-Object -First 10
C.2.9 创建安装脚本
在 Windows 上创建安装脚本,保存到 D:\k8s-offline\scripts\ 目录:
install-ubuntu.sh:
# 在 PowerShell 中创建脚本
$scriptPath = "D:\k8s-offline\scripts\install-ubuntu.sh"
$scriptContent = @'
#!/bin/bash
# Ubuntu/Debian 离线安装脚本
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$(dirname "$SCRIPT_DIR")"
echo "========== Ubuntu 离线安装 =========="
# 1. 安装依赖包
echo "[1/4] 安装系统依赖..."
dpkg -i ${BASE_DIR}/packages/ubuntu/*.deb 2>/dev/null || true
apt-get install -f -y
# 2. 安装 containerd
echo "[2/4] 安装 Containerd..."
dpkg -i ${BASE_DIR}/packages/containerd/*.deb 2>/dev/null || true
apt-get install -f -y
# 配置 containerd
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sed -i 's|sandbox_image = "registry.k8s.io/pause:.*"|sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"|' /etc/containerd/config.toml
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
# 3. 安装 Kubernetes
echo "[3/4] 安装 Kubernetes 组件..."
dpkg -i ${BASE_DIR}/packages/kubernetes/kubelet*.deb
dpkg -i ${BASE_DIR}/packages/kubernetes/kubectl*.deb
dpkg -i ${BASE_DIR}/packages/kubernetes/kubeadm*.deb
apt-get install -f -y
systemctl enable kubelet
# 4. 导入镜像
echo "[4/4] 导入容器镜像..."
for tar in ${BASE_DIR}/images/*.tar; do
echo "导入: $(basename $tar)"
ctr -n k8s.io images import $tar 2>/dev/null || \
nerdctl -n k8s.io load -i $tar 2>/dev/null
done
echo "========== 安装完成 =========="
echo "验证: kubeadm version"
echo "下一步: kubeadm init 初始化集群"
'@
Set-Content -Path $scriptPath -Value $scriptContent -Encoding UTF8
Write-Host "脚本已创建: $scriptPath"
install-centos.sh:
$scriptPath = "D:\k8s-offline\scripts\install-centos.sh"
$scriptContent = @'
#!/bin/bash
# CentOS/RHEL 离线安装脚本
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$(dirname "$SCRIPT_DIR")"
echo "========== CentOS 离线安装 =========="
# 1. 安装依赖包
echo "[1/4] 安装系统依赖..."
yum localinstall -y ${BASE_DIR}/packages/centos/*.rpm
# 2. 安装 containerd
echo "[2/4] 安装 Containerd..."
yum localinstall -y ${BASE_DIR}/packages/containerd/*.rpm
# 配置 containerd
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sed -i 's|sandbox_image = "registry.k8s.io/pause:.*"|sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"|' /etc/containerd/config.toml
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
# 3. 安装 Kubernetes
echo "[3/4] 安装 Kubernetes 组件..."
yum localinstall -y ${BASE_DIR}/packages/kubernetes/*.rpm
systemctl enable kubelet
# 4. 导入镜像
echo "[4/4] 导入容器镜像..."
for tar in ${BASE_DIR}/images/*.tar; do
echo "导入: $(basename $tar)"
ctr -n k8s.io images import $tar 2>/dev/null || \
nerdctl -n k8s.io load -i $tar 2>/dev/null
done
echo "========== 安装完成 =========="
echo "验证: kubeadm version"
echo "下一步: kubeadm init 初始化集群"
'@
Set-Content -Path $scriptPath -Value $scriptContent -Encoding UTF8
Write-Host "脚本已创建: $scriptPath"
prepare-env.sh(环境准备):
$scriptPath = "D:\k8s-offline\scripts\prepare-env.sh"
$scriptContent = @'
#!/bin/bash
# 环境准备脚本
echo "========== 环境准备 =========="
# 1. 关闭 Swap
echo "[1/4] 关闭 Swap..."
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
# 2. 关闭防火墙
echo "[2/4] 关闭防火墙..."
if command -v ufw &> /dev/null; then
ufw disable
fi
if command -v firewall-cmd &> /dev/null; then
systemctl stop firewalld
systemctl disable firewalld
fi
# 3. 配置内核模块
echo "[3/4] 配置内核模块..."
cat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 4. 配置内核参数
echo "[4/4] 配置内核参数..."
cat << EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
echo "========== 环境准备完成 =========="
'@
Set-Content -Path $scriptPath -Value $scriptContent -Encoding UTF8
Write-Host "脚本已创建: $scriptPath"
C.2.10 打包并传输到 Linux
打包离线安装包:
# 使用 PowerShell 压缩
$sourcePath = "D:\k8s-offline"
$destinationPath = "D:\k8s-offline-$(Get-Date -Format 'yyyyMMdd').zip"
Write-Host "打包离线安装包..."
# 压缩目录
Compress-Archive -Path "$sourcePath\*" -DestinationPath $destinationPath -Force
Write-Host "打包完成!"
Write-Host "文件: $destinationPath"
Write-Host "大小: $([math]::Round((Get-Item $destinationPath).Length / 1GB, 2)) GB"
传输方式:
| 方式 | 操作步骤 |
|---|---|
| U盘/移动硬盘 | 1. 将 zip 文件复制到移动介质 2. 在 Linux 上挂载并复制 |
| SCP 传输 | scp D:\k8s-offline.zip root@linux-server:/root/ |
| FTP/SFTP 工具 | 使用 WinSCP、FileZilla 等工具上传 |
| HTTP 服务 | 在 Windows 上启动临时 HTTP 服务 |
Windows 启动临时 HTTP 服务:
# 在离线包目录启动 HTTP 服务(Python 需要安装)
cd D:\
python -m http.server 8080
# 或者使用 PowerShell(需要管理员权限)
# 在 Linux 上使用 wget 下载:
# wget http://windows-ip:8080/k8s-offline.zip
C.3 在 Linux 上安装离线包
⚠️ 重要:将离线包传输到 Linux 后,按以下步骤安装。
C.3.1 解压离线包
# 进入目录
cd /root
# 解压 zip 文件(需要安装 unzip)
unzip k8s-offline.zip
# 或者解压 tar.gz 文件
tar -xzvf k8s-offline.tar.gz
# 查看文件结构
ls -la k8s-offline/
C.3.2 执行环境准备
cd k8s-offline
# 添加执行权限
chmod +x scripts/*.sh
# 执行环境准备
./scripts/prepare-env.sh
C.3.3 执行离线安装
Ubuntu/Debian:
./scripts/install-ubuntu.sh
CentOS/RHEL:
./scripts/install-centos.sh
C.3.4 验证安装
# 验证版本
kubeadm version
kubelet --version
kubectl version --client
# 验证镜像
crictl images
# 验证 containerd
systemctl status containerd
C.3.5 初始化集群
# 初始化 Master
kubeadm init \
--apiserver-advertise-address=192.168.x.x \
--kubernetes-version=v1.33.12 \
--pod-network-cidr=10.244.0.0/16
# 配置 kubectl
export KUBECONFIG=/etc/kubernetes/admin.conf
# 安装网络插件
kubectl apply -f /root/k8s-offline/configs/calico.yaml
C.4 准备离线安装包(在有网 Linux 机器上执行)
C.2.1 创建工作目录
# 创建离线包目录
mkdir -p /root/k8s-offline/{packages,images,scripts}
# 进入工作目录
cd /root/k8s-offline
C.2.2 下载系统依赖包
Ubuntu/Debian 系统:
# 安装下载工具
apt update
apt install -y apt-utils
# 创建依赖包下载脚本
cat > download_ubuntu_packages.sh << 'EOF'
#!/bin/bash
# 下载 Ubuntu/Debian 系统依赖包
PACKAGES_DIR="./packages/ubuntu"
mkdir -p $PACKAGES_DIR
# 系统基础依赖
BASE_PACKAGES=(
"ca-certificates"
"curl"
"wget"
"gnupg"
"lsb-release"
"apt-transport-https"
"software-properties-common"
"conntrack"
"socat"
"git"
"ntpdate"
"chrony"
)
echo "下载基础依赖包..."
for pkg in "${BASE_PACKAGES[@]}"; do
echo "下载: $pkg"
apt-get download $pkg 2>/dev/null || echo "跳过: $pkg"
done
# 下载依赖
apt-get install --print-uris ${BASE_PACKAGES[@]} | awk -F "'" '/http/ {print $2}' | xargs -r wget -P $PACKAGES_DIR
echo "基础依赖包下载完成!"
ls -lh $PACKAGES_DIR
EOF
chmod +x download_ubuntu_packages.sh
./download_ubuntu_packages.sh
CentOS/RHEL 系统:
# 安装下载工具
yum install -y yum-utils
# 创建依赖包下载脚本
cat > download_centos_packages.sh << 'EOF'
#!/bin/bash
# 下载 CentOS/RHEL 系统依赖包
PACKAGES_DIR="./packages/centos"
mkdir -p $PACKAGES_DIR
# 系统基础依赖
BASE_PACKAGES=(
"ca-certificates"
"curl"
"wget"
"gnupg2"
"yum-utils"
"conntrack"
"socat"
"git"
"ntpdate"
"chrony"
)
echo "下载基础依赖包..."
for pkg in "${BASE_PACKAGES[@]}"; do
echo "下载: $pkg"
yumdownloader --resolve --destdir=$PACKAGES_DIR $pkg
done
echo "基础依赖包下载完成!"
ls -lh $PACKAGES_DIR
EOF
chmod +x download_centos_packages.sh
./download_centos_packages.sh
C.2.3 下载 Containerd 安装包
Ubuntu/Debian:
# 添加 Docker 软件源
apt update
apt install -y ca-certificates curl gnupg
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list
apt update
# 下载 containerd 及依赖
mkdir -p ./packages/containerd
cd ./packages/containerd
# 下载 containerd
apt-get download containerd.io
# 下载依赖
apt-cache depends containerd.io | grep Depends | awk '{print $2}' | xargs apt-get download
cd ../..
echo "Containerd 包下载完成!"
ls -lh ./packages/containerd/
CentOS/RHEL:
# 添加 Docker 软件源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 下载 containerd 及依赖
mkdir -p ./packages/containerd
yumdownloader --resolve --destdir=./packages/containerd containerd.io
echo "Containerd 包下载完成!"
ls -lh ./packages/containerd/
C.2.4 下载 Kubernetes 安装包
Ubuntu/Debian:
# 添加 Kubernetes 软件源
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | 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.33/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
apt update
# 下载 Kubernetes 组件
mkdir -p ./packages/kubernetes
cd ./packages/kubernetes
# 指定版本下载(可根据需要修改版本号)
K8S_VERSION="1.33.12-1.1"
# 下载 kubeadm、kubelet、kubectl
apt-get download kubeadm=$K8S_VERSION
apt-get download kubelet=$K8S_VERSION
apt-get download kubectl=$K8S_VERSION
# 下载依赖
apt-cache depends kubeadm | grep Depends | awk '{print $2}' | xargs apt-get download 2>/dev/null
apt-cache depends kubelet | grep Depends | awk '{print $2}' | xargs apt-get download 2>/dev/null
apt-cache depends kubectl | grep Depends | awk '{print $2}' | xargs apt-get download 2>/dev/null
cd ../..
echo "Kubernetes 包下载完成!"
ls -lh ./packages/kubernetes/
CentOS/RHEL:
# 添加 Kubernetes 软件源
cat << EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
enabled=1
gpgcheck=0
EOF
# 下载 Kubernetes 组件
mkdir -p ./packages/kubernetes
# 指定版本下载
K8S_VERSION="1.33.12"
yumdownloader --resolve --destdir=./packages/kubernetes kubeadm-$K8S_VERSION
yumdownloader --resolve --destdir=./packages/kubernetes kubelet-$K8S_VERSION
yumdownloader --resolve --destdir=./packages/kubernetes kubectl-$K8S_VERSION
echo "Kubernetes 包下载完成!"
ls -lh ./packages/kubernetes/
C.2.5 下载 Kubernetes 镜像
创建镜像下载脚本:
cat > download_k8s_images.sh << 'EOF'
#!/bin/bash
# 下载 Kubernetes 所需镜像
IMAGES_DIR="./images"
mkdir -p $IMAGES_DIR
# Kubernetes 版本
K8S_VERSION="v1.33.12"
# 镜像仓库(使用阿里云镜像加速)
REGISTRY="registry.aliyuncs.com/google_containers"
# Kubernetes 核心镜像列表
K8S_IMAGES=(
"kube-apiserver:${K8S_VERSION}"
"kube-controller-manager:${K8S_VERSION}"
"kube-scheduler:${K8S_VERSION}"
"kube-proxy:${K8S_VERSION}"
"pause:3.9"
"etcd:3.5.9-0"
"coredns:v1.10.1"
)
echo "========== 下载 Kubernetes 核心镜像 =========="
for image in "${K8S_IMAGES[@]}"; do
echo "下载: ${REGISTRY}/${image}"
crictl pull "${REGISTRY}/${image}"
done
echo "========== 导出镜像为 tar 包 =========="
for image in "${K8S_IMAGES[@]}"; do
# 获取镜像 ID
image_id=$(crictl images | grep "${image}" | awk '{print $3}' | head -1)
if [ -n "$image_id" ]; then
# 生成文件名(替换特殊字符)
filename=$(echo "${image}" | sed 's/[:/]/-/g')
output_file="${IMAGES_DIR}/k8s-${filename}.tar"
echo "导出: ${image} -> ${output_file}"
ctr -n k8s.io image export "${output_file}" "${REGISTRY}/${image}"
fi
done
echo "========== Kubernetes 镜像下载完成 =========="
ls -lh $IMAGES_DIR
EOF
chmod +x download_k8s_images.sh
./download_k8s_images.sh
使用 Docker 下载镜像(备选):
cat > download_k8s_images_docker.sh << 'EOF'
#!/bin/bash
# 使用 Docker 下载并导出镜像
IMAGES_DIR="./images"
mkdir -p $IMAGES_DIR
K8S_VERSION="v1.33.12"
REGISTRY="registry.aliyuncs.com/google_containers"
K8S_IMAGES=(
"kube-apiserver:${K8S_VERSION}"
"kube-controller-manager:${K8S_VERSION}"
"kube-scheduler:${K8S_VERSION}"
"kube-proxy:${K8S_VERSION}"
"pause:3.9"
"etcd:3.5.9-0"
"coredns:v1.10.1"
)
for image in "${K8S_IMAGES[@]}"; do
echo "拉取: ${REGISTRY}/${image}"
docker pull "${REGISTRY}/${image}"
filename=$(echo "${image}" | sed 's/[:/]/-/g')
output_file="${IMAGES_DIR}/k8s-${filename}.tar"
echo "导出: ${output_file}"
docker save -o "${output_file}" "${REGISTRY}/${image}"
done
echo "镜像下载完成!"
ls -lh $IMAGES_DIR
EOF
chmod +x download_k8s_images_docker.sh
./download_k8s_images_docker.sh
C.2.6 下载网络插件镜像(Calico)
cat > download_calico_images.sh << 'EOF'
#!/bin/bash
# 下载 Calico 网络插件镜像
IMAGES_DIR="./images"
# Calico 版本
CALICO_VERSION="v3.26.1"
# Calico 镜像列表
CALICO_IMAGES=(
"docker.io/calico/cni:${CALICO_VERSION}"
"docker.io/calico/node:${CALICO_VERSION}"
"docker.io/calico/kube-controllers:${CALICO_VERSION}"
)
echo "========== 下载 Calico 镜像 =========="
for image in "${CALICO_IMAGES[@]}"; do
echo "拉取: ${image}"
crictl pull "${image}" || docker pull "${image}"
filename=$(echo "${image}" | sed 's/[:/]/-/g' | sed 's/docker.io-//')
output_file="${IMAGES_DIR}/calico-${filename}.tar"
echo "导出: ${output_file}"
if command -v ctr &> /dev/null; then
ctr -n k8s.io image export "${output_file}" "${image}"
else
docker save -o "${output_file}" "${image}"
fi
done
echo "========== Calico 镜像下载完成 =========="
ls -lh $IMAGES_DIR
EOF
chmod +x download_calico_images.sh
./download_calico_images.sh
C.2.7 下载 Calico YAML 配置
# 下载 Calico 配置文件
cd ./images
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
cd ..
C.2.8 创建离线安装脚本
创建离线安装主脚本:
cat > scripts/install_offline.sh << 'EOF'
#!/bin/bash
# Kubernetes 离线安装脚本
# 用途: 在无网络环境下安装 Kubernetes
set -e
echo "=========================================="
echo " Kubernetes 离线安装脚本"
echo "=========================================="
# 当前脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$(dirname "$SCRIPT_DIR")"
PACKAGES_DIR="${BASE_DIR}/packages"
IMAGES_DIR="${BASE_DIR}/images"
echo "安装包目录: $PACKAGES_DIR"
echo "镜像目录: $IMAGES_DIR"
# 检测系统类型
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
else
echo "无法检测系统类型"
exit 1
fi
echo "系统类型: $OS"
# 函数:安装 Ubuntu/Debian 包
install_ubuntu_packages() {
echo "========== 安装系统依赖 =========="
# 安装基础依赖
if [ -d "${PACKAGES_DIR}/ubuntu" ]; then
dpkg -i ${PACKAGES_DIR}/ubuntu/*.deb 2>/dev/null || true
apt-get install -f -y
fi
# 安装 containerd
echo "安装 Containerd..."
if [ -d "${PACKAGES_DIR}/containerd" ]; then
dpkg -i ${PACKAGES_DIR}/containerd/*.deb 2>/dev/null || true
apt-get install -f -y
fi
# 安装 Kubernetes 组件
echo "安装 Kubernetes 组件..."
if [ -d "${PACKAGES_DIR}/kubernetes" ]; then
# 先安装依赖
for pkg in conntrack socat; do
if ls ${PACKAGES_DIR}/kubernetes/${pkg}*.deb 1> /dev/null 2>&1; then
dpkg -i ${PACKAGES_DIR}/kubernetes/${pkg}*.deb 2>/dev/null || true
fi
done
# 安装 kubeadm、kubelet、kubectl
dpkg -i ${PACKAGES_DIR}/kubernetes/kubelet*.deb 2>/dev/null || true
dpkg -i ${PACKAGES_DIR}/kubernetes/kubectl*.deb 2>/dev/null || true
dpkg -i ${PACKAGES_DIR}/kubernetes/kubeadm*.deb 2>/dev/null || true
# 修复依赖
apt-get install -f -y
fi
}
# 函数:安装 CentOS/RHEL 包
install_centos_packages() {
echo "========== 安装系统依赖 =========="
# 安装基础依赖
if [ -d "${PACKAGES_DIR}/centos" ]; then
yum localinstall -y ${PACKAGES_DIR}/centos/*.rpm
fi
# 安装 containerd
echo "安装 Containerd..."
if [ -d "${PACKAGES_DIR}/containerd" ]; then
yum localinstall -y ${PACKAGES_DIR}/containerd/*.rpm
fi
# 安装 Kubernetes 组件
echo "安装 Kubernetes 组件..."
if [ -d "${PACKAGES_DIR}/kubernetes" ]; then
yum localinstall -y ${PACKAGES_DIR}/kubernetes/*.rpm
fi
}
# 函数:配置 Containerd
configure_containerd() {
echo "========== 配置 Containerd =========="
mkdir -p /etc/containerd
# 生成默认配置
containerd config default > /etc/containerd/config.toml
# 修改配置
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 修改 sandbox 镜像
sed -i 's|sandbox_image = "registry.k8s.io/pause:.*"|sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"|' /etc/containerd/config.toml
# 启动服务
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
echo "Containerd 配置完成!"
}
# 函数:导入镜像
import_images() {
echo "========== 导入容器镜像 =========="
if [ -d "${IMAGES_DIR}" ]; then
for tar_file in ${IMAGES_DIR}/*.tar; do
if [ -f "$tar_file" ]; then
echo "导入镜像: $(basename $tar_file)"
ctr -n k8s.io images import "$tar_file" 2>/dev/null || \
nerdctl -n k8s.io load -i "$tar_file" 2>/dev/null || \
docker load -i "$tar_file" 2>/dev/null || \
echo "警告: 导入失败 $tar_file"
fi
done
fi
echo "镜像导入完成!"
# 查看已导入镜像
echo "已导入镜像列表:"
ctr -n k8s.io images ls 2>/dev/null || crictl images
}
# 主安装流程
main() {
case $OS in
ubuntu|debian)
install_ubuntu_packages
;;
centos|rhel|rocky|almalinux)
install_centos_packages
;;
*)
echo "不支持的系统: $OS"
exit 1
;;
esac
configure_containerd
import_images
# 启用 kubelet
systemctl enable kubelet
echo ""
echo "=========================================="
echo " 离线安装完成!"
echo "=========================================="
echo ""
echo "验证安装:"
echo " kubeadm version"
echo " kubelet --version"
echo " kubectl version --client"
echo " crictl images"
echo ""
echo "下一步:执行 kubeadm init 初始化集群"
}
main
EOF
chmod +x scripts/install_offline.sh
C.2.9 创建环境准备脚本
cat > scripts/prepare_env.sh << 'EOF'
#!/bin/bash
# 环境准备脚本(无需网络)
set -e
echo "========== 环境准备 =========="
# 1. 关闭 Swap
echo "[1/5] 关闭 Swap..."
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
echo "✅ Swap 已关闭"
# 2. 关闭防火墙
echo "[2/5] 关闭防火墙..."
if command -v ufw &> /dev/null; then
ufw disable
echo "✅ UFW 已关闭"
fi
if command -v firewall-cmd &> /dev/null; then
systemctl stop firewalld
systemctl disable firewalld
echo "✅ Firewalld 已关闭"
fi
# 3. 关闭 SELinux (CentOS/RHEL)
echo "[3/5] 配置 SELinux..."
if command -v setenforce &> /dev/null; then
setenforce 0 2>/dev/null || true
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config 2>/dev/null || true
echo "✅ SELinux 已配置"
fi
# 4. 配置内核模块
echo "[4/5] 配置内核模块..."
cat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay 2>/dev/null || true
modprobe br_netfilter 2>/dev/null || true
# 5. 配置内核参数
echo "[5/5] 配置内核参数..."
cat << EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
echo "========== 环境准备完成 =========="
EOF
chmod +x scripts/prepare_env.sh
C.2.10 打包离线安装包
# 创建打包脚本
cat > pack_offline.sh << 'EOF'
#!/bin/bash
# 打包离线安装包
PACKAGE_NAME="k8s-offline-$(date +%Y%m%d).tar.gz"
echo "打包离线安装包..."
# 确保目录存在
mkdir -p packages images scripts
# 打包
tar -czvf ${PACKAGE_NAME} \
packages/ \
images/ \
scripts/ \
README.md 2>/dev/null || \
tar -czvf ${PACKAGE_NAME} \
packages/ \
images/ \
scripts/
echo "========== 打包完成 =========="
echo "文件: ${PACKAGE_NAME}"
echo "大小: $(ls -lh ${PACKAGE_NAME} | awk '{print $5}')"
# 计算校验和
sha256sum ${PACKAGE_NAME} > ${PACKAGE_NAME}.sha256
echo "校验文件: ${PACKAGE_NAME}.sha256"
EOF
chmod +x pack_offline.sh
./pack_offline.sh
C.3 传输离线安装包
C.3.1 传输方式
| 方式 | 适用场景 | 操作 |
|---|---|---|
| U 盘/移动硬盘 | 物理隔离环境 | 复制文件到移动介质 |
| SCP 传输 | 内网可通 | scp k8s-offline.tar.gz root@node1:/root/ |
| HTTP 服务 | 批量传输 | 搭建临时 HTTP 服务 |
| NFS 共享 | 内网共享 | 挂载 NFS 目录 |
C.3.2 SCP 传输示例
# 传输到 master 节点
scp k8s-offline-*.tar.gz root@master1:/root/
# 传输到 worker 节点
scp k8s-offline-*.tar.gz root@node1:/root/
C.3.3 解压安装包
在所有节点执行:
# 进入目录
cd /root
# 解压
tar -xzvf k8s-offline-*.tar.gz
# 查看文件结构
ls -la
# 输出:
# drwxr-xr-x packages/
# drwxr-xr-x images/
# drwxr-xr-x scripts/
C.4 离线安装步骤(在无网机器上执行)
C.4.1 安装流程图
┌─────────────────────────────────────────────────────────────┐
│ 离线安装流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 步骤 1: 解压安装包 │
│ tar -xzvf k8s-offline.tar.gz │
│ ↓ │
│ 步骤 2: 执行环境准备脚本 │
│ ./scripts/prepare_env.sh │
│ ↓ │
│ 步骤 3: 执行离线安装脚本 │
│ ./scripts/install_offline.sh │
│ ↓ │
│ 步骤 4: 验证安装 │
│ kubeadm version │
│ crictl images │
│ ↓ │
│ 步骤 5: 初始化集群(仅 master) │
│ kubeadm init ... │
│ │
└─────────────────────────────────────────────────────────────┘
C.4.2 在所有节点执行
# 1. 解压安装包
cd /root
tar -xzvf k8s-offline-*.tar.gz
# 2. 执行环境准备
cd k8s-offline
./scripts/prepare_env.sh
# 3. 执行离线安装
./scripts/install_offline.sh
# 4. 验证安装
kubeadm version
kubelet --version
kubectl version --client
crictl images
C.4.3 初始化集群(仅 Master 节点)
# 在 master1 上执行
# 初始化集群
kubeadm init \
--apiserver-advertise-address=192.168.x.x \
--kubernetes-version=v1.33.12 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository=registry.aliyuncs.com/google_containers \
--skip-phases=preflight # 跳过预检(镜像已导入)
# 配置 kubectl
export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bashrc
# 获取 join 命令
kubeadm token create --print-join-command > /root/k8s-join-command.sh
chmod +x /root/k8s-join-command.sh
C.4.4 Worker 节点加入集群
# 在 node1 上执行
# 从 master 获取 join 命令后执行
kubeadm join 192.168.x.x:6443 --token xxxx --discovery-token-ca-cert-hash sha256:xxxx
C.4.5 安装网络插件
# 在 master1 上执行
# 应用 Calico 配置(需要提前下载好 YAML 文件)
kubectl apply -f /root/k8s-offline/images/calico.yaml
# 等待 Pod 启动
kubectl get pods -n kube-system -w
C.5 离线安装验证
C.5.1 验证检查清单
#!/bin/bash
# 离线安装验证脚本
echo "========== 验证检查 =========="
echo "[1] 检查 Swap"
swap_total=$(free -m | awk '/Swap/{print $2}')
[ "$swap_total" -eq 0 ] && echo "✅ Swap 已关闭" || echo "❌ Swap 未关闭"
echo "[2] 检查 Containerd"
systemctl is-active containerd &>/dev/null && echo "✅ Containerd 运行中" || echo "❌ Containerd 未运行"
echo "[3] 检查 Kubelet"
systemctl is-enabled kubelet &>/dev/null && echo "✅ Kubelet 已启用" || echo "❌ Kubelet 未启用"
echo "[4] 检查 Kubeadm"
command -v kubeadm &>/dev/null && echo "✅ Kubeadm 已安装: $(kubeadm version -o short)" || echo "❌ Kubeadm 未安装"
echo "[5] 检查 Kubectl"
command -v kubectl &>/dev/null && echo "✅ Kubectl 已安装" || echo "❌ Kubectl 未安装"
echo "[6] 检查镜像数量"
image_count=$(crictl images 2>/dev/null | wc -l)
echo "✅ 已导入镜像: $((image_count - 1)) 个"
echo "[7] 检查内核模块"
lsmod | grep -q overlay && echo "✅ overlay 已加载" || echo "❌ overlay 未加载"
lsmod | grep -q br_netfilter && echo "✅ br_netfilter 已加载" || echo "❌ br_netfilter 未加载"
echo "[8] 检查内核参数"
[ "$(sysctl -n net.ipv4.ip_forward)" -eq 1 ] && echo "✅ ip_forward = 1" || echo "❌ ip_forward 未设置"
echo "========== 验证完成 =========="
C.5.2 集群状态验证
# 查看节点状态
kubectl get nodes -o wide
# 查看所有 Pod
kubectl get pods -A
# 查看组件状态
kubectl get cs
# 测试部署
kubectl create deployment test-nginx --image=nginx
kubectl get pods
C.6 离线安装目录结构
k8s-offline/
├── packages/
│ ├── ubuntu/ # Ubuntu 系统依赖包
│ │ ├── ca-certificates_*.deb
│ │ ├── curl_*.deb
│ │ └── ...
│ ├── centos/ # CentOS 系统依赖包
│ │ ├── ca-certificates-*.rpm
│ │ ├── curl-*.rpm
│ │ └── ...
│ ├── containerd/ # Containerd 安装包
│ │ ├── containerd.io_*.deb # Ubuntu
│ │ └── containerd.io-*.rpm # CentOS
│ └── kubernetes/ # Kubernetes 组件
│ ├── kubeadm_*.deb
│ ├── kubelet_*.deb
│ ├── kubectl_*.deb
│ ├── kubeadm-*.rpm
│ ├── kubelet-*.rpm
│ └── kubectl-*.rpm
├── images/
│ ├── k8s-kube-apiserver-v1.33.12.tar
│ ├── k8s-kube-controller-manager-v1.33.12.tar
│ ├── k8s-kube-scheduler-v1.33.12.tar
│ ├── k8s-kube-proxy-v1.33.12.tar
│ ├── k8s-pause-3.9.tar
│ ├── k8s-etcd-3.5.9-0.tar
│ ├── k8s-coredns-v1.10.1.tar
│ ├── calico-cni-v3.26.1.tar
│ ├── calico-node-v3.26.1.tar
│ ├── calico-kube-controllers-v3.26.1.tar
│ └── calico.yaml # Calico 配置文件
├── scripts/
│ ├── prepare_env.sh # 环境准备脚本
│ ├── install_offline.sh # 离线安装脚本
│ └── verify_install.sh # 验证脚本
└── README.md # 说明文档
C.7 常见问题
C.7.1 依赖包缺失
问题: 安装时报依赖缺失
解决:
# Ubuntu/Debian
dpkg -i --force-depends package.deb
apt-get install -f
# CentOS/RHEL
yum localinstall --nogpgcheck package.rpm
C.7.2 镜像导入失败
问题: 镜像导入失败
解决:
# 方法1: 使用 ctr
ctr -n k8s.io images import image.tar
# 方法2: 使用 nerdctl
nerdctl -n k8s.io load -i image.tar
# 方法3: 使用 docker
docker load -i image.tar
# 方法4: 使用 crictl(需要先导入到 containerd)
ctr -n k8s.io images import image.tar
crictl images
C.7.3 版本不匹配
问题: kubeadm init 时版本不匹配
解决:
# 检查已安装版本
kubeadm version
kubelet --version
# 指定正确版本初始化
kubeadm init --kubernetes-version=v1.33.12
&spm=1001.2101.3001.5002&articleId=162062063&d=1&t=3&u=6561bae19d6e40c3a8f688f8aa922894)
1571

被折叠的 条评论
为什么被折叠?



