1. 主流安装方式
a. kubeadm
K8s 官方提供的最小化集群部署工具,通过 kubeadm init/join 快速拉起集群,自动处理依赖、证书、组件启动
- 优点
- 简单,几条命令即可完成单节点 / 多节点集群搭建,大幅降低部署门槛
- 高可用&可维护,自带升级、证书轮换、节点重置等运维能力
- 官方标准、生态兼容最好,与 CNI/CRI/CSI 生态完美兼容
- 社区支持完善,文档全、排错资料多,遇到问题容易解决。
- 缺点
- 定制化程度有限,部署流程、组件启动参数、目录结构被固定,无法深度自定义底层流程
b. 二进制安装
不依赖任何安装工具,手动下载每个组件的二进制文件,手动编写 systemd 单元、配置证书、网络策略、组件依赖关系
- 优点
- 完全自定义:组件启动参数、证书策略、目录结构、启动顺序、依赖关系,完全由自己控制
- 部署过程能彻底搞懂 K8s 各组件通信、证书机制、网络模型、依赖关系
- 缺点
- 复杂度极高、极易出错
- 维护成本极高
- 生产风险大
- 部署、调试周期长,不适合快速交付和规模化节点
2. 部署架构
a. 企业高可用架构
- 在 Master 的 3 个节点(Master 节点个数可以根据集群规模进行扩展)之前,通过一个负载均衡器提供对客户端的唯一访问入口地址。
- 负载均衡器以 HAProxy 搭配 Keepalived 进行配置。
- 3 台主机的 IP 地址分别为 192.168.1.101、192.168.1.102、192.168.1.103,负载均衡器使用的 VIP 为 192.168.1.100。
- 为了保证 Master 的高可用,同时也需要确保 etcd 是高可用的。
- 当然如果业务规模真的很大,可以按照业务模块部署多套 k8s 的集群。(etcd 减压)

b. 测试模式
一主两从的模式,一个 master,两个 node,用于测试,下面按照这个模式部署
- master: 192.168.1.101
- node: 192.168.1.102
- node: 192.168.1.103
3. 安装流程
a. 软件准备(离线安装)
i. k8s 包
- 可以到 https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/x86_64/?spm=a2c6h.25603864.0.0.412b1b64kyV9rm 进行下载
- 包含以下 rpm 包
- cri-tools-1.35.0-150500.1.1.x86_64.rpm
- kubeadm-1.35.0-150500.1.1.x86_64.rpm
- kubectl-1.35.0-150500.1.1.x86_64.rpm
- kubelet-1.35.0-150500.1.1.x86_64.rpm
- kubernetes-cni-1.8.0-150500.1.1.x86_64.rpm
ii. docker-ce 包
- 可以到 https://mirrors.aliyun.com/docker-ce/linux/centos/9.3/x86_64/stable/Packages/?spm=a2c6h.25603864.0.0.289436d5qP7mT9 进行下载
- 包含以下包
- docker-ce-29.3.0-1.el9.x86_64.rpm
- docker-ce-cli-29.3.0-1.el9.x86_64.rpm
- docker-ce-rootless-extras-29.3.0-1.el9.x86_64.rpm
- docker-compose-plugin-5.1.0-1.el9.x86_64.rpm
- docker-buildx-plugin-0.31.1-1.el9.x86_64.rpm
- containerd.io-2.2.2-1.el9.x86_64.rpm
iii. cri-docker 包
- 可以到 https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.24/cri-dockerd-0.3.24.amd64.tgz 进行下载
iii. k8s 核心镜像包(kubeadm init 的时候需要用到)
- 先在有外网的服务器上拉取以下镜像
- docker pull registry.aliyuncs.com/google_containers/coredns:v1.13.1
- docker pull registry.aliyuncs.com/google_containers/etcd:3.6.6-0
- docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.35.0
- docker pull registry.aliyuncs.com/google_containers/kube-controller-manager:v1.35.0
- docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.35.0
- docker pull registry.aliyuncs.com/google_containers/kube-scheduler:v1.35.0
- docker pull registry.aliyuncs.com/google_containers/pause:3.10.1
- docker pull registry.aliyuncs.com/google_containers/pause:3.8
- 然后导出镜像
- docker save -o k8s-1.35.0-images.tar registry.aliyuncs.com/google_containers/coredns:v1.13.1 registry.aliyuncs.com/google_containers/etcd:3.6.6-0 registry.aliyuncs.com/google_containers/kube-apiserver:v1.35.0 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.35.0 registry.aliyuncs.com/google_containers/kube-proxy:v1.35.0 registry.aliyuncs.com/google_containers/kube-scheduler:v1.35.0 registry.aliyuncs.com/google_containers/pause:3.10.1 registry.aliyuncs.com/google_containers/pause:3.8
iiii. calico 插件
- 可以通过以下命令先下载
iiiii. calico 镜像包
- 先在有外网的服务器上拉取以下镜像
- docker pull quay.io/calico/cni:v3.29.7
- docker pull quay.io/calico/kube-controllers:v3.29.7
- docker pull quay.io/calico/node:v3.29.7
- docker pull quay.io/calico/typha:v3.29.7
- 然后导出镜像
- docker save -o calico-3.29.7-images.tar quay.io/calico/cni:v3.29.7 quay.io/calico/kube-controllers:v3.29.7 quay.io/calico/node:v3.29.7 quay.io/calico/typha:v3.29.7
b. 安装步骤
i. 网卡配置(可选)
只保留一个网卡,其余的网卡将自启动关闭,如果保留多个网卡可能导致 calico 绑定网卡出错,也可以通过固定网卡解决
bash
# 仅主机模式的网卡
[root@rocky-server-1: ~]#cat /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
uuid=55ff12b9-d0ae-33ef-9d0d-63e65df2e750
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1761792426
[ethernet]
[ipv4]
address1=192.168.1.101/24
method=manual
dns=114.114.114.114;8.8.8.8
[ipv6]
addr-gen-mode=eui64
method=auto
[proxy]
bash
# NAT 网卡
[root@rocky-server-1: ~]#cat /etc/NetworkManager/system-connections/ens192.nmconnection
[connection]
id=ens192
uuid=e8834466-539f-3848-9f06-46c41d5c66b7
type=ethernet
autoconnect-priority=-999
interface-name=ens192
timestamp=1761811392
autoconnect=false # 关闭自启动
[ethernet]
[ipv4]
address1=192.168.73.101/24,192.168.73.2
method=manual
dns=114.114.114.114;8.8.8.8
[ipv6]
addr-gen-mode=eui64
method=auto
[proxy]
bash
# 调用 nmcli 重启设备和连接配置
nmcli d d ens192
nmcli d r ens160
nmcli c r ens160
ii. 更换 yum 源
bash
# 替换为国内阿里云源
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/[Rr]ocky*.repo
iii. 禁用 selinux
bash
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
grubby --update-kernel ALL --args selinux=0
# 查看是否禁用,grubby --info DEFAULT
# 回滚内核层禁用操作,grubby --update-kernel ALL --remove-args selinux
iiii. 设置时区
bash
timedatectl set-timezone Asia/Shanghai
iiiii. 关闭 swap 分区
bash
# swap 分区是在内存不够的时候把磁盘空间变成虚拟内存,但是性能较低,如果服务器专门用于做 k8s 就建议关闭 swap 分区
swapoff -a # 临时关闭
sed -i 's:/dev/mapper/rl-swap:#/dev/mapper/rl-swap:g' /etc/fstab # 永久关闭
iiiiii. 修改主机名
bash
# k8s 会读取主机名标识
hostnamectl set-hostname k8s-master01 # 192.168.1.101
hostnamectl set-hostname k8s-node01 # 192.168.1.102
hostnamectl set-hostname k8s-node02 # 192.168.1.103
# /etc/hosts 中写入
192.168.1.101 k8s-master01 m1
192.168.1.102 k8s-node01 n1
192.168.1.103 k8s-node02 n2
iiiiiii. 安装 ipvs
bash
# 生产环境 K8s 都用 kube-proxy 的 IPVS 四层负载均衡模式,而 IPVS 必须依赖这个工具
yum install -y ipvsadm
iiiiiiii. 开启路由转发
bash
# 让节点变成「网络路由器」,允许节点转发不同网段的网络数据包------ 这是 K8s 集群中 Pod 跨节点通信、Service 流量转发、Pod 访问外网的核心前提,不开启的话 K8s 网络直接瘫痪。
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
iiiiiiiii. 加载 bridge
bash
# 加载 bridge
yum install -y epel-release
yum install -y bridge-utils
# 加载 br_netfilter 模块
modprobe br_netfilter
# modprobe overlay # 如果是 containerd 容器需要加载 overlay
# 开机自动加载模块
echo 'br_netfilter' >> /etc/modules-load.d/bridge.conf
# 配置网桥 iptables 调用参数
echo 'net.bridge.bridge-nf-call-iptables=1' >> /etc/sysctl.conf
echo 'net.bridge.bridge-nf-call-ip6tables=1' >> /etc/sysctl.conf
# 让配置立即生效
sysctl -p
iiiiiiiiii. 安装 docker
bash
# 添加 docker-ce yum 源
# 中科大(ustc)
sudo dnf config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
cd /etc/yum.repos.d
# 切换中科大源
sed -e 's|download.docker.com|mirrors.ustc.edu.cn/docker-ce|g' docker-ce.repo > docker-ce-ustc.repo
mv docker-ce.repo docker-ce.repo.bak
# 安装 docker-ce
yum -y install docker-ce
# 配置 daemon
cat > /etc/docker/daemon.json <<EOF
{
"data-root": "/data/docker",
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": { "max-size": "100m", "max-file": "100" },
"insecure-registries": ["harbor.bsoft.com"],
"registry-mirrors": ["https://kfp63jaj.mirror.aliyuncs.com"]
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# 重启docker服务
systemctl daemon-reload && systemctl restart docker && systemctl enable docker
# 重启服务器
reboot
iiiiiiiiiii. 安装 cri-docker
bash
# 安装 cri-docker
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.24/cri-dockerd-0.3.24.amd64.tgz
tar -zvxf cri-dockerd-0.3.24.amd64.tgz
cp cri-dockerd/cri-dockerd /usr/bin/
chmod a+x /usr/bin/cri-dockerd
# 配置 cri-docker 服务
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.8
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
# 添加 cri-docker 套接字
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.socket
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF
# 启动 cri-docker 对应服务
systemctl daemon-reload
systemctl enable cri-docker
systemctl start cri-docker
systemctl is-active cri-docker
iiiiiiiiiiiii. 开放所需端口
bash
# 1. 放行 K8s 控制面端口
firewall-cmd --permanent --add-port=6443/tcp # kube-apiserver
firewall-cmd --permanent --add-port=2379-2380/tcp # etcd
firewall-cmd --permanent --add-port=10250/tcp # kubelet
firewall-cmd --permanent --add-port=10251/tcp # kube-scheduler
firewall-cmd --permanent --add-port=10252/tcp # kube-controller-manager
firewall-cmd --permanent --add-port=10255/tcp # kubelet 只读端口
# 2. 放行 CNI 网络插件端口(Calico/Flannel)
firewall-cmd --permanent --add-port=8472/udp # Flannel VXLAN
firewall-cmd --permanent --add-port=5473/udp # Calico VXLAN
firewall-cmd --permanent --add-port=4789/udp # VXLAN 通用端口
# 3. 放行 IPVS 相关端口(kube-proxy IPVS 模式)
firewall-cmd --permanent --add-port=10249/tcp # kube-proxy metrics
firewall-cmd --permanent --add-port=10256/tcp # kube-proxy healthz
# 4. 重新加载 firewalld 规则(生效配置)
firewall-cmd --reload
# 验证放行的端口
firewall-cmd --list-ports
iiiiiiiiiiiiii. 安装 kubeadm 1.35.0 版本
bash
# 安装 kubeadm 1.35.0 版本(所有节点执行)
cd /usr/upload/kubernetes-1.35.0-150500.1.1
yum -y install *.rpm
# 固定ip(所有节点执行)
vim /etc/sysconfig/kubelet
# 输入以下内容
KUBELET_EXTRA_ARGS=--node-ip=192.168.1.101 --cgroup-driver=systemd
# 开机自启(所有节点执行)
systemctl enable kubelet.service
# 初始化主节点(master 节点执行,这里如果有外网可以直接执行,如果没有外网先把 k8s-1.35.0-images.tar 镜像导入到 master 节点的 docker 中,然后再执行)
kubeadm init --apiserver-advertise-address=192.168.1.101 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version 1.35.0 --service-cidr=10.10.0.0/12 --pod-network-cidr=10.244.0.0/16 --cri-socket unix:///var/run/cri-dockerd.sock
# 也可以通过配置文件进行初始化
kubeadm init --config=kubeadm-config.yaml --upload-certs
# 从初始化输出内容中复制以下命令执行(master 节点执行)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# work 加入(work 节点执行)
kubeadm join 192.168.1.101:6443 --token yynve7.my0fozh4kfgrd39v --discovery-token-ca-cert-hash sha256:56aa0ebaf54104e1bdec475d78698c42a1c93e8acc20b615ef7179d171d1a404 --cri-socket unix:///var/run/cri-dockerd.sock
# master 加入(可选,如果是多 master 的情况)
# token 通过执行 kubeadm token create 生成新的 token
# discovery-token-ca-cert-hash 通过执行 openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' 得到
# certificate-key 通过执行 kubeadm certs certificate-key 得到,如果过期需要通过 kubeadm init phase upload-certs --upload-certs 重新生成
kubeadm join 192.168.1.101:6443 --token yynve7.my0fozh4kfgrd39v --discovery-token-ca-cert-hash sha256:56aa0ebaf54104e1bdec475d78698c42a1c93e8acc20b615ef7179d171d1a404 --control-plane --certificate-key 6b5ae96e16cf35bc8d6d665458f014a8add06e8e9277fcbb880a2a7a3df0740a --cri-socket unix:///var/run/cri-dockerd.sock
# 验证节点
kubectl get node
kubectl get pod -A
iiiiiiiiiiiiiii. 部署网络插件 calico
bash
# 下载 3.29.7 版本 YAML
curl https://raw.githubusercontent.com/projectcalico/calico/v3.29.7/manifests/calico-typha.yaml -o calico.yaml
# 替换 YAML 中的镜像源(避免离线部署时镜像拉取失败)
sed -i 's#docker.io/calico#quay.io/calico#g' calico.yaml
# 修改 calico.yaml 的 CALICO_IPV4POOL_CIDR 地址
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
# 修改 calico.yaml 开启 bgp 模式
# Enable IPIP
- name: CALICO_IPV4POOL_IPIP
value: "Always" #改成 Off
# 导入 calico 镜像(如果是离线环境,所有节点先把 calico-3.29.7-images.tar 镜像导入)
docker load -i calico-3.29.7-images.tar
# 先确定只有一个网卡,然后执行以下命令把 calico 应用到 kubernetes 集群
cd /usr/upload
kubectl apply -f calico.yaml # 启动 calico
c. 清理重置集群
i. master node 都要清理
bash
# 重置集群
kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock -f
# 停止 kubelet cri-docker
systemctl stop kubelet
systemctl stop cri-docker
systemctl disable kubelet
# 手动清理残留目录(关键步骤)
rm -rf $HOME/.kube/config
rm -rf /etc/kubernetes/*
rm -rf /var/lib/kubelet/*
rm -rf /var/lib/etcd/*
rm -rf /etc/cni/*
rm -rf /opt/cni/*
rm -rf /var/lib/cni/*
rm -rf /var/lib/dockershim/*
rm -rf /var/lib/calico/*
rm -rf /var/run/kubernetes/*
docker system prune -a
# 清理网络残留(可选)
ip link delete cni0 2>/dev/null
ip link delete flannel.1 2>/dev/null
# 重启核心服务
systemctl start cri-docker
systemctl daemon-reload
ii. 清理 kubernetes 的 rpm 包
bash
yum remove -y cri-tools kubeadm kubectl kubelet kubernetes-cni