Kubernetes 基础集群部署完整操作记录
集群信息
- Master 节点:k8s-master01(192.168.92.11)
- Node 节点:k8s-node01(192.168.92.12)、k8s-node02(192.168.92.13)
- 操作系统:Rocky Linux / Red Hat Enterprise Linux 9.5
- Kubernetes 版本:v1.36.3
- 容器运行时:Docker + cri-dockerd(v0.4.4)
- 网络插件:Calico v3.32.1(BGP 模式)
- Service CIDR:10.10.0.0/12
- Pod CIDR:10.244.0.0/16
目录
- [1. 基础环境配置(所有节点)](#1. 基础环境配置(所有节点))
- [2. Master 节点初始化](#2. Master 节点初始化)
- [3. Node 节点加入集群](#3. Node 节点加入集群)
- [4. 安装 Calico 网络插件](#4. 安装 Calico 网络插件)
- [5. 最终验证](#5. 最终验证)
- [6. 部署过程中的关键问题处理](#6. 部署过程中的关键问题处理)
- 附录:常用命令速查
1. 基础环境配置(所有节点)
说明:以下操作在三个节点上均需执行,包括 YUM 源配置、系统优化、Docker 安装、cri-dockerd 和 Kubernetes 组件安装。
1.1 配置 YUM 源
Rocky Linux:
bash
# 进入 YUM 仓库目录
cd /etc/yum.repos.d/
# 备份并替换为阿里云 Rocky Linux 源
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
-i.bak /etc/yum.repos.d/rocky-*.repo
# 更新缓存
yum makecache -y
Red Hat Enterprise Linux:
bash
# 配置本地仓库(挂载 ISO 镜像)
cat > /etc/yum.repos.d/yum.repo <<EOF
[BaseOS]
name=BaseOS
baseurl=/mnt/BaseOS
gpgcheck=0
[AppStream]
name=AppStream
baseurl=/mnt/AppStream
gpgcheck=0
EOF
# 配置自动挂载
echo "/dev/sr0 /mnt iso9660 defaults 0 0" >> /etc/fstab
mount -a
# 安装基本工具后,再添加 Kubernetes 源
1.2 关闭防火墙和 SELinux
bash
# 关闭防火墙
systemctl disable --now firewalld
# 临时关闭 SELinux
setenforce 0
# 永久关闭 SELinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
# 验证 SELinux 状态
getenforce
1.3 关闭 Swap
bash
# 临时关闭
swapoff -a
# 永久关闭(注释 /etc/fstab 中的 swap 挂载行)
sed -i 's/.*swap.*/#&/' /etc/fstab
# 验证 swap 是否已关闭
free -m
预期输出:Swap 行显示 total: 0。
1.4 安装基础工具
bash
dnf install -y \
net-tools \
nfs-utils \
vim \
wget \
curl \
bash-completion \
device-mapper-persistent-data \
psmisc \
tree \
openssh \
openssh-server \
ipvsadm \
chrony \
yum-utils
1.5 配置内核参数
bash
# 开启 IP 转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
# 使内核参数生效
sysctl -p
# 验证 IP 转发是否开启
cat /proc/sys/net/ipv4/ip_forward
# 预期输出:1
1.6 配置主机名和网络
| 节点 | 主机名设置 | IP 配置 |
|---|---|---|
| Master | hostnamectl set-hostname k8s-master01 && bash |
nmcli c modify ens160 ipv4.addresses 192.168.92.11/24 ipv4.gateway 192.168.92.2 ipv4.method manual autoconnect yes ipv4.dns 223.5.5.5 |
| Node01 | hostnamectl set-hostname k8s-node01 && bash |
nmcli c modify ens160 ipv4.addresses 192.168.92.12/24 ipv4.gateway 192.168.92.2 ipv4.method manual autoconnect yes ipv4.dns 223.5.5.5 |
| Node02 | hostnamectl set-hostname k8s-node02 && bash |
nmcli c modify ens160 ipv4.addresses 192.168.92.13/24 ipv4.gateway 192.168.92.2 ipv4.method manual autoconnect yes ipv4.dns 223.5.5.5 |
bash
# 应用网络配置(各节点执行)
nmcli c up ens160
ip a
1.7 配置 hosts 文件
Master 节点操作:
bash
cat > /etc/hosts <<EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.92.11 k8s-master01 m1
192.168.92.12 k8s-node01 n1
192.168.92.13 k8s-node02 n2
192.168.92.20 hb.com harbor
EOF
bash
# 生成 SSH 密钥并复制到节点
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
ssh-copy-id root@192.168.92.12
ssh-copy-id root@192.168.92.13
# 同步 hosts 文件到节点
scp /etc/hosts root@192.168.92.12:/etc/
scp /etc/hosts root@192.168.92.13:/etc/
1.8 配置时间同步
Master 节点作为 NTP 服务器:
bash
dnf install -y chrony
cat > /etc/chrony.conf << 'EOF'
# 使用国内 NTP 服务器
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server cn.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
# 允许 192.168.92.0/24 网段的客户端访问
allow 192.168.92.0/24
local stratum 10
logdir /var/log/chrony
EOF
systemctl enable chronyd --now
chronyc sources -v
Node 节点同步到 Master:
bash
dnf install -y chrony
cat > /etc/chrony.conf << 'EOF'
server 192.168.92.11 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
EOF
systemctl enable chronyd --now
chronyc sources -v
1.9 安装 Docker
bash
# 添加阿里云 Docker CE 源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/rhel/docker-ce.repo
# 安装 Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 创建 Docker 配置文件
cat > /etc/docker/daemon.json <<EOF
{
"default-ipc-mode": "shareable",
"data-root": "/data/docker",
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "50"
},
"insecure-registries": ["http://hb.com"],
"registry-mirrors": [
"https://docker.1ms.run",
"https://func.ink",
"https://proxy.1panel.live",
"https://docker-0.unsee.tech",
"https://docker.zhai.cm",
"https://a.ussh.net",
"https://docker.melikeme.cn",
"https://docker.hlmirror.com",
"https://docker.xiaogenban1993.com",
"https://docker.1panel.top",
"https://docker.kejilion.pro",
"https://dockerpull.cn",
"https://docker.xuanyuan.me",
"https://docker.anye.in",
"https://hub.fast360.xyz",
"https://docker.m.daocloud.io",
"https://docker.ims.run",
"https://dockerproxy.net",
"https://proxy.vvvv.ee",
"https://dockerproxy.link",
"https://7kjolzcz.mirror.aliyuncs.com"
]
}
EOF
# 启动 Docker
systemctl daemon-reload
systemctl enable --now docker
# 验证 Docker 安装
docker version
1.10 安装 cri-dockerd
说明:由于 Kubernetes v1.24+ 已移除对 Docker 的 direct 支持,需通过 cri-dockerd 作为适配器。
Master 节点操作:
bash
# 下载 cri-dockerd v0.4.4
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.4.4/cri-dockerd-0.4.4.amd64.tgz
# 解压并安装
tar -zxf cri-dockerd-0.4.4.amd64.tgz
cp cri-dockerd/cri-dockerd /usr/bin/
chmod +x /usr/bin/cri-dockerd
# 查看 cri-dockerd 服务文件所在目录
ls cri-dockerd/packaging/systemd/
# 复制服务文件
cp cri-dockerd/packaging/systemd/cri-docker.service /usr/lib/systemd/system/
cp cri-dockerd/packaging/systemd/cri-docker.socket /usr/lib/systemd/system/
# 修改 cri-docker.service 文件,添加必要的参数
sed -i 's|ExecStart=/usr/bin/cri-dockerd|ExecStart=/usr/bin/cri-dockerd --network-plugin=nci --pod-infra-container-image=registry.k8s.io/pause:3.10|' /usr/lib/systemd/system/cri-docker.service
# 重新加载并启动
systemctl daemon-reload
systemctl enable --now cri-docker
systemctl status cri-docker
同步 cri-dockerd 到 Node 节点:
bash
# 同步二进制文件
scp /usr/bin/cri-dockerd root@192.168.92.12:/usr/bin/
scp /usr/bin/cri-dockerd root@192.168.92.13:/usr/bin/
# 同步服务文件
scp /usr/lib/systemd/system/cri-docker.service root@192.168.92.12:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/cri-docker.service root@192.168.92.13:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/cri-docker.socket root@192.168.92.12:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/cri-docker.socket root@192.168.92.13:/usr/lib/systemd/system/
Node 节点操作:
bash
systemctl daemon-reload
systemctl enable --now cri-docker
systemctl status cri-docker
1.11 安装 Kubernetes 组件
bash
# 添加阿里云 Kubernetes YUM 源
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.36/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.36/rpm/repodata/repomd.xml.key
EOF
# 安装 kubeadm、kubelet、kubectl
yum install -y kubelet kubeadm kubectl
# 启动 kubelet(此时会报错,属于正常现象,等待集群初始化完成后自动恢复正常)
systemctl enable kubelet --now
# 验证安装
kubeadm version
kubectl version --client
2. Master 节点初始化
说明 :以下操作仅在 k8s-master01 上执行。
2.1 查看所需镜像并手动加载
bash
# 查看初始化所需镜像列表
kubeadm config images list
预期输出(v1.36.3):
registry.k8s.io/kube-apiserver:v1.36.3
registry.k8s.io/kube-controller-manager:v1.36.3
registry.k8s.io/kube-scheduler:v1.36.3
registry.k8s.io/kube-proxy:v1.36.3
registry.k8s.io/coredns/coredns:v1.14.2
registry.k8s.io/pause:3.10.2
registry.k8s.io/etcd:3.6.8-0
说明:由于直接拉取镜像较慢,可提前将镜像包导入 Docker。
bash
# 手动加载镜像
docker load -i pause_3.10.2.tar.gz
docker load -i k8s-images_v1.36.3.tar.gz
docker load -i etcd_3.6.8.tar.gz
# 查看已加载的镜像
docker images
2.2 初始化集群
bash
kubeadm init \
--apiserver-advertise-address=192.168.92.11 \
--kubernetes-version=v1.36.3 \
--service-cidr=10.10.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket=unix:///var/run/cri-dockerd.sock
⚠️ 重要提示:
- 初始化成功后,最后一行会显示
kubeadm join命令,请复制保存该命令,用于 Node 节点加入集群。- 默认生成的
join命令不包含--cri-socket参数,需要在 Node 节点执行时手动添加该参数。- 完整的 Node 加入命令格式请参考 [3.2 加入集群](#3.2 加入集群) 章节。
执行过程说明:
[init] Using Kubernetes version: v1.36.3
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[certs] Generating certificate and key
[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
[wait-control-plane] Waiting for the kubelet to boot up the control plane
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config"
[mark-control-plane] Marking the node k8s-master01 as control-plane
[bootstrap-token] Using token: xxxxxx
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
2.3 配置 kubectl
bash
# 配置 kubectl 访问集群
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 验证集群状态
kubectl get nodes
# 预期输出:k8s-master01 NotReady ... (等待网络插件部署后变为 Ready)
kubectl get pods -n kube-system
3. Node 节点加入集群
说明 :以下操作分别在 k8s-node01 和 k8s-node02 上执行。
3.1 加载 Kubernetes 镜像
bash
# 加载 pause 镜像
docker load -i pause_3.10.2.tar.gz
# 加载 Kubernetes 核心组件镜像
docker load -i k8s-images_v1.36.3.tar.gz
# 加载 etcd 镜像
docker load -i etcd_3.6.8.tar.gz
# 注意:如果存在旧版本 etcd 镜像冲突,先删除再加载
docker rmi registry.k8s.io/etcd:3.6.11-0 2>/dev/null
docker load -i etcd_3.6.8.tar.gz
# 查看已加载的镜像
docker images
3.2 加入集群
⚠️ 重要说明:
- 以下命令中的
token和--discovery-token-ca-cert-hash来自 Master 节点kubeadm init成功后的输出。--cri-socket=unix:///var/run/cri-dockerd.sock是手动添加的参数,用于指定容器运行时接口(CRI)的 Socket 路径。- 如果 Token 过期,请在 Master 节点执行
kubeadm token create --print-join-command重新生成,并手动添加--cri-socket参数。
k8s-node01:
bash
kubeadm join 192.168.92.11:6443 \
--token <你的token> \
--discovery-token-ca-cert-hash sha256:<你的hash值> \
--cri-socket=unix:///var/run/cri-dockerd.sock
k8s-node02:
bash
kubeadm join 192.168.92.11:6443 \
--token <你的token> \
--discovery-token-ca-cert-hash sha256:<你的hash值> \
--cri-socket=unix:///var/run/cri-dockerd.sock
4. 安装 Calico 网络插件
说明 :Calico 提供 Pod 之间的网络连通性,安装后节点才会变为
Ready状态。
4.1 下载并配置 Calico
bash
# 下载 Calico 部署文件
curl https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico-typha.yaml -o calico.yaml
# 查看需要的镜像
grep image calico.yaml
预期镜像列表:
quay.io/calico/cni:v3.32.1
quay.io/calico/node:v3.32.1
quay.io/calico/kube-controllers:v3.32.1
quay.io/calico/typha:v3.32.1
4.2 修改 Calico 配置(BGP 模式)
bash
vim calico.yaml
找到并修改以下配置:
yaml
# 关闭 IPIP 模式(使用 BGP)
- name: CALICO_IPV4POOL_IPIP
value: "off"
# 关闭 VXLAN 模式(使用 BGP)
- name: CALICO_IPV4POOL_VXLAN
value: "Never"
# 修改 Pod 网络 CIDR(与 kubeadm init 时的 --pod-network-cidr 保持一致)
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
4.3 加载 Calico 镜像
bash
# 三个节点都需要加载
docker load -i calico-images_v3.32.1.tar.gz
# 查看已加载的 Calico 镜像
docker images | grep calico
4.4 部署 Calico
bash
# 在 Master 节点执行
kubectl apply -f calico.yaml
4.5 验证 Calico 部署
bash
# 查看 Calico Pod 状态
kubectl get pods -n kube-system | grep calico
# 预期输出:
# calico-kube-controllers-xxxxx 1/1 Running 0 2m
# calico-node-xxxxx 1/1 Running 0 2m
# calico-node-yyyyy 1/1 Running 0 2m
# calico-node-zzzzz 1/1 Running 0 2m
# calico-typha-xxxxx 1/1 Running 0 2m
5. 最终验证
在 Master 节点上执行:
bash
# 查看所有节点状态
kubectl get nodes
# 预期输出:
# NAME STATUS ROLES AGE VERSION
# k8s-master01 Ready control-plane 10m v1.36.3
# k8s-node01 Ready <none> 5m v1.36.3
# k8s-node02 Ready <none> 5m v1.36.3
# 查看节点详细信息
kubectl get nodes -o wide
# 查看所有命名空间的 Pod 状态
kubectl get pods --all-namespaces
# 查看系统组件状态
kubectl get cs
6. 部署过程中的关键问题处理
| 问题 | 解决方案 |
|---|---|
| etcd 镜像版本不匹配 | 初始化需要 etcd:3.6.8-0,如存在 3.6.11-0 需先删除: docker rmi registry.k8s.io/etcd:3.6.11-0 docker load -i etcd_3.6.8.tar.gz |
| kubelet 启动失败 | 集群初始化前 kubelet 启动失败属正常现象,等待 kubeadm init 完成即可恢复正常 |
| Token 过期 | Token 默认有效期 24 小时,过期后重新生成: kubeadm token create --print-join-command 注意 :重新生成的命令不包含 --cri-socket,需手动添加 |
| cri-dockerd 服务异常 | 检查服务状态并重启: systemctl status cri-docker systemctl restart cri-docker |
| 节点 NotReady | 等待 Calico 网络插件部署完成,约需 1-3 分钟 检查 Calico Pod 状态:`kubectl get pods -n kube-system |
| Docker 镜像拉取慢 | 已配置国内镜像加速器,或提前下载镜像包通过 docker load 导入 |
| SELinux 未完全关闭 | 执行 setenforce 0 并修改 /etc/selinux/config 中 SELINUX=disabled,重启节点后验证 |
| 防火墙干扰 | 确保 firewalld 已完全禁用:systemctl disable --now firewalld |
| kubectl exec 报错 HTTP vs HTTPS | API Server 配置添加 --kubelet-https=true,或检查 kubelet 的 --port=10250 是否正常 |
附录:常用命令速查
重新生成 Join 命令
bash
kubeadm token create --print-join-command
注意 :重新生成的命令不包含
--cri-socket参数,需要手动添加:
bashkubeadm join 192.168.92.11:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx --cri-socket=unix:///var/run/cri-dockerd.sock
查看集群状态
bash
# 查看节点
kubectl get nodes
kubectl get nodes -o wide
# 查看所有命名空间的 Pod
kubectl get pods --all-namespaces
kubectl get pods -n kube-system
# 查看系统组件状态
kubectl get cs
重启服务
bash
# 重启 Docker
systemctl restart docker
# 重启 cri-dockerd
systemctl restart cri-docker
# 重启 kubelet
systemctl restart kubelet
查看日志
bash
# 查看 kubelet 日志
journalctl -u kubelet -f
# 查看 cri-dockerd 日志
journalctl -u cri-docker -f
# 查看 Docker 日志
journalctl -u docker -f
# 查看 kubelet 日志(最近 50 行)
journalctl -u kubelet -n 50 --no-pager
清理集群(如需重装)
bash
# Master 节点执行
kubeadm reset
# 清理残留文件
rm -rf /etc/kubernetes/
rm -rf ~/.kube/
rm -rf /etc/cni/
rm -rf /opt/cni/
rm -rf /var/lib/etcd/
rm -rf /var/lib/kubelet/
rm -rf /var/lib/cni/
rm -rf /var/run/calico/
# Node 节点执行
kubeadm reset
rm -rf /etc/kubernetes/
rm -rf /var/lib/kubelet/
rm -rf /var/lib/cni/
rm -rf /var/run/calico/
# 重启节点(推荐)
reboot
⚠️ 重要提示 :以上命令中涉及的 Token 和 CA 证书哈希值仅对本次部署有效。如需重新生成加入命令,请在 Master 节点上执行
kubeadm token create --print-join-command,并记得手动添加--cri-socket=unix:///var/run/cri-dockerd.sock参数。