一 构建部署Kubernetes所需要的主机
| 主机名 | IP | 配置 | 角色 |
|---|---|---|---|
| www.onepiece.com | 192.168.136.100 | cpu1、mem 1G | harbor本地仓库 |
| K8s | 192.168.136.10 | cpu4、mem>4G | master,k8s集群控制节点 |
| K8s1 | 192.168.136.20 | cpu2、mem 2G | worker,k8s集群工作节点 |
| K8s2 | 192.168.136.30 | cpu2、mem 2G | worker,k8s集群工作节点 |

!IMPORTANT
以下所有的操作在所有主机中都需要配置
关闭swap
bash
# 禁用并立即停止 swap.target
[root@K8s ~]# systemctl disable --now swap.target
# 屏蔽 swap.target
[root@K8s ~]# systemctl mask swap.target
# 注释 /etc/fstab 中的 swap 配置
sed '/swap/s/^/#/g' -i /etc/fstab
安装docker
bash
[root@K8s ~]# cd /etc/yum.repos.d/
[root@K8s yum.repos.d]# vim dokcer.repo
[docker]
name = docker
baseurl = https://mirrors.aliyun.com/docker-ce/linux/rhel/9.8/x86_64/stable/
gpgcheck = 0
[root@K8s yum.repos.d]# dnf install docker-ce -y
[root@K8s yum.repos.d]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true
[root@K8s yum.repos.d]# echo br_netfilter > /etc/modules-load.d/docker_mod.conf
[root@K8s yum.repos.d]# modprobe -a br_netfilter
[root@K8s yum.repos.d]# cat > /etc/sysctl.d/docker.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
[root@K8s yum.repos.d]# sysctl --system
[root@K8s yum.repos.d]# systemctl enable --now docker
配置证书可以使用harbor仓库
bash
[root@K8s yum.repos.d]# mkdir /etc/docker/certs.d/www.onepiece.com/ -p
[root@Harbor ~]# for i in 10 20 30; do scp /data/certs/onepiece.com.crt root@192.168.136.$i:/etc/docker/certs.d/www.onepiece.com/ca.crt; done
[root@K8s yum.repos.d]# systemctl restart docker
配置docker加速器
bash
# 让Docker拉取镜像时使用指定的镜像仓库镜像源
[root@K8s ~]# cat >/etc/docker/daemon.json <<EOF
{
"registry-mirrors":["https://www.onepiece.com"]
}
EOF
[root@K8s ~]# systemctl restart docker
[root@K8s ~]# docker info
Registry Mirrors:
https://www.onepiece.com/
彼此建立解析
bash
[root@K8s ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.136.10 K8s
192.168.136.20 K8s1
192.168.136.30 K8s2
192.168.136.100 www.onepiece.com
配置kubernetes安装源
bash
[root@K8s ~]# dnf list kubelet
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。
上次元数据过期检查:0:11:27 前,执行于 2026年08月22日 星期六 11时26分34秒。
可安装的软件包
kubelet.aarch64 1.35.8-150500.1.1 kubernetes
kubelet.ppc64le 1.35.8-150500.1.1 kubernetes
kubelet.s390x 1.35.8-150500.1.1 kubernetes
kubelet.src 1.35.8-150500.1.1 kubernetes
kubelet.x86_64 1.35.8-150500.1.1 kubernetes
[root@K8s ~]#
[root@K8s ~]# vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name = kubernetes
baseurl = https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/
gpgcheck = 0
[root@K8s ~]# dnf list kubelet
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。
上次元数据过期检查:0:11:27 前,执行于 2026年08月22日 星期六 11时26分34秒。
可安装的软件包
kubelet.aarch64 1.35.8-150500.1.1 kubernetes
kubelet.ppc64le 1.35.8-150500.1.1 kubernetes
kubelet.s390x 1.35.8-150500.1.1 kubernetes
kubelet.src 1.35.8-150500.1.1 kubernetes
kubelet.x86_64 1.35.8-150500.1.1 kubernetes
以上操作完成后重启主机检测swap分区
bash
# 没有任何输出表示ok
swapon -s
二 kubernetes的部署
1 安装cri-dockerd
bash
# 所有主机中安装
# 可以用rpm包部署cri-dockerd,但是rpm包版本相对较老 推荐二进制方式部署
# 下载二进制包
[root@K8s ~]# wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.4.4/cri-dockerd-0.4.4.amd64.tgz
# 解压二进制压缩包
[root@K8s ~]# tar zxf cri-dockerd-0.4.4.amd64.tgz
[root@K8s ~]# cd cri-dockerd/
[root@K8s cri-dockerd]# ls
cri-dockerd cri-docker.service cri-docker.socket
# 安装cri-docker命令到系统
[root@K8s cri-dockerd]# install -o root -g root -m 0755 cri-dockerd /usr/local/bin/cri-dockerd
[root@K8s cri-dockerd]# ls -l /usr/local/bin/cri-dockerd
-rwxr-xr-x 1 root root 51638434 8月 22 11:45 /usr/local/bin/cri-dockerd
# 生成启动文件
[root@K8s cri-dockerd]# cp cri-docker.s* /lib/systemd/system
[root@K8s cri-dockerd]# chmod +x /lib/systemd/system/cri-docker.s*
[root@K8s cri-dockerd]# vim /lib/systemd/system/cri-docker.service
ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint fd://
[root@K8s cri-dockerd]# systemctl daemon-reload
# 启动服务
[root@K8s cri-dockerd]# systemctl enable --now cri-docker
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template
units). This means they are not meant to be enabled or disabled using systemctl.
Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's
.wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some
instance name specified.
[root@K8s ~]# systemctl status cri-docker.service
● cri-docker.service - CRI Interface for Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/cri-docker.service; static)
Active: active (running) since Sat 2026-08-22 12:34:29 CST; 2min 33s ago
TriggeredBy: ● cri-docker.socket
Docs: https://docs.mirantis.com
Main PID: 12842 (cri-dockerd)
Tasks: 11 (limit: 22916)
Memory: 63.9M
CPU: 53ms
CGroup: /system.slice/cri-docker.service
└─12842 /usr/local/bin/cri-dockerd --container-runtime-endpoint fd://
2 安装构建kubernetes 集群所需软件
Master(K8s主机)节点
bash
[root@K8s ~]# dnf install kubelet kubeadm kubectl -y
[root@K8s ~]# systemctl enable --now kubelet.service
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /usr/lib/systemd/system/kubelet.service.
node(K8s1&2)节点
bash
[root@K8s1 cri-dockerd]# dnf install kubelet kubeadm -y
[root@K8s2 ~]# systemctl enable --now kubelet.service
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /usr/lib/systemd/system/kubelet.service.
master(K8s)节点中 kubectl 和kubeadm 补齐
bash
[root@K8s ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@K8s ~]# echo "source <(kubeadm completion bash)" >> ~/.bashrc
[root@K8s ~]# source ~/.bashrc
3 下载kubernetes集群所需镜像
查看镜像
bash
[root@K8s ~]# kubeadm config images list
I0822 12:44:47.114606 13403 version.go:260] remote version is much newer: v1.36.4; falling back to: stable-1.35
registry.k8s.io/kube-apiserver:v1.35.8
registry.k8s.io/kube-controller-manager:v1.35.8
registry.k8s.io/kube-scheduler:v1.35.8
registry.k8s.io/kube-proxy:v1.35.8
registry.k8s.io/coredns/coredns:v1.13.1
registry.k8s.io/pause:3.10.1
registry.k8s.io/etcd:3.6.6-0
下载镜像
bash
[root@K8s ~]# kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.35.7 \
--cri-socket=unix:///var/run/cri-dockerd.sock
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.35.7
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.35.7
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.35.7
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.35.7
[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:v1.13.1
[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.10.1
[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.6.6-0
上传镜像到本地harbor仓库
bash
[root@K8s ~]# docker login www.onepiece.com -uadmin
Password:
Login Succeeded
[root@K8s ~]# docker images --format "{{.Repository}}:{{.Tag}}" | awk -F "/" '/google/{system("docker tag "$0" www.onepiece.com/k8s/"$3)}'
[root@K8s ~]# docker images --format "{{.Repository}}:{{.Tag}}" | awk -F "/" '/onepiece/{system("docker push "$0)}'
4 在master中初始化kubernetes集群
在master中完成集群初始化
bash
[root@K8s ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 --image-repository www.onepiece.com/k8s --kubernetes-version v1.35.7 --cri-socket=unix:///var/run/cri-dockerd.sock
# 每个人不一样,其他主机加入本集群的凭证
kubeadm join 192.168.136.10:6443 --token zfcu29.dnb6aj9b8iboqncz \
--discovery-token-ca-cert-hash sha256:cbeda5aa208463a315bb564bf264cbaff2d466ae615cf84696a31e654af6af22
# 如果忘记
[root@K8s ~]# kubeadm token create --print-join-command
kubeadm join 192.168.136.10:6443 --token 4zm4uy.pg76rmyg9dm87f5j --discovery-token-ca-cert-hash sha256:cbeda5aa208463a315bb564bf264cbaff2d466ae615cf84696a31e654af6af22
# 如果初始化出问题
# 直接重置
[root@K8s ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
添加kubernets环境变量到本机
bash
[root@K8s ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" > ~/.bash_profile
[root@K8s ~]# source ~/.bash_profile
[root@K8s ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s NotReady control-plane 2m57s v1.35.8
添加node节点到本集群
bash
[root@K8s1 ~]# kubeadm join 192.168.136.10:6443 --token lw0ynt.ej1kryw9519vf31u --discovery-token-ca-cert-hash sha256:cbeda5aa208463a315bb564bf264cbaff2d466ae615cf84696a31e654af6af22 --cri-socket=unix:///var/run/cri-dockerd.sock
[root@K8s ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s NotReady control-plane 7m6s v1.35.8
k8s1 NotReady <none> 65s v1.35.8
k8s2 NotReady <none> 3s v1.35.8
5 安装网络插件
bash
[root@K8s ~]# tar zxf kube-flannel-v0.28.9.tar.gz
[root@K8s ~]# cd flannel/
[root@K8s flannel]# docker load -i kube-flannel-v0.28.9.tar
Loaded image: ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel3
Loaded image: ghcr.io/flannel-io/flannel:v0.28.9
[root@K8s flannel]# docker tag ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel3 www.onepiece.com/flannel-io/flannel-cni-plugin:v1.9.1-flannel3
[root@K8s flannel]# docker push www.onepiece.com/flannel-io/flannel-cni-plugin:v1.9.1-flannel3
[root@K8s flannel]# docker tag ghcr.io/flannel-io/flannel:v0.28.9 www.onepiece.com/flannel-io/flannel:v0.28.9
[root@K8s flannel]# docker push www.onepiece.com/flannel-io/flannel:v0.28.9
The push refers to repository [www.onepiece.com/flannel-io/flannel]
f923fe4d6cdf: Pushed
55afa1ecc21d: Mounted from flannel-io/flannel-cni-plugin
552426a46922: Pushed
464e53b89363: Pushed
779e1d234370: Pushed
74f5049831bd: Pushed
7e7d4790580f: Pushed
dde022ac8ed4: Pushed
fef9ba352c99: Pushed
4f4fb700ef54: Pushed
v0.28.9: digest: sha256:d666a036197fe6c8928f82b670d89f38f5830d25e70bfcc35641da06f03cfcad size: 2197
i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:708a2c9c1cfbfe529d1dbb249cb7113af117f3ed26b5e3e4c8ee015e10555204 -> sha256:d666a036197fe6c8928f82b670d89f38f5830d25e70bfcc35641da06f03cfcad
[root@K8s flannel]# vim kube-flannel.yml
image: flann[root@K8s flannel]# kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
serviceaccount/flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
el-io/flannel:v0.28.1
image: flannel-io/flannel-cni-plugin:v1.9.0-flannel1
image: flannel-io/flannel:v0.28.1
[root@K8s flannel]# kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
serviceaccount/flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
# 测试
[root@K8s flannel]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s Ready control-plane 50m v1.35.8
k8s1 Ready <none> 44m v1.35.8
k8s2 Ready <none> 43m v1.35.8