基于 cri-dockerd 搭建 Kubernetes 1.36 集群完整指南

基于 cri-dockerd 搭建 Kubernetes 1.36 集群完整指南

本文是一份面向实践的 Kubernetes 1.36 集群搭建指南,采用 Docker + cri-dockerd 方案作为容器运行时。文章从零开始,依次涵盖 Harbor 私有镜像仓库的搭建、Rocky Linux 节点的环境准备、kubeadm 集群初始化和工作节点接入,以及 Calico 网络插件的部署。所有步骤均配有完整的命令行操作与输出日志,适合在生产或实验环境中对照执行。
Rocky虚拟机安装可以参考:https://blog.lonelybear.cn/rocky-install/
虚拟机克隆可以参考:https://blog.lonelybear.cn/cloning/

目录


环境概览

主机 IP地址 角色
Red hat 01 192.168.142.129 harbor镜像仓库
Rocky-master 192.168.142.150 Master
Rocky-node1 192.168.142.151 Worker
Rocky-node2 192.168.142.152 Worker

软件版本

组件 版本 说明
操作系统 Rocky Linux 10.2 RHEL 10 兼容发行版
Docker Engine 29.7.1 CE 版本
Docker Compose v5.3.1 插件内置
Harbor v2.14.2 离线安装包
Kubernetes v1.36.3 阿里云镜像源
cri-dockerd v0.3.17 Mirantis 维护
Calico v3.32.1 Tigera 官方
CoreDNS v1.14.2 K8s 内置
etcd 3.6.8-0 K8s 内置
CNI 插件 kubernetes-cni 1.9.1 基础网络二进制

网络规划

网络类型 CIDR 用途
物理网络 192.168.142.0/24 节点间通信
Pod 网络 10.244.0.0/16 Calico 管理
Service 网络 10.10.0.0/12 ClusterIP 分配

0-6-虚拟机列表.jpg


一、Harbor 镜像仓库搭建

1. 修改主机名

[root@localhost ~]# hostnamectl hostname harbor && bash

2. 配置静态IP

[root@harbor ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:fc:a1:e3 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname enx000c29fca1e3
    inet 192.168.142.129/24 brd 192.168.142.255 scope global dynamic noprefixroute ens160
       valid_lft 1256sec preferred_lft 1256sec
    inet6 fe80::20c:29ff:fefc:a1e3/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

#网卡要结合实际情况修改我的是ens160
[root@harbor ~]# nmcli c m ens160 ipv4.method manual ipv4.addresses 192.168.142.129/24 ipv4.gateway 192.168.142.2 ipv4.dns "223.5.5.5 8.8.8.8" connection.autoconnect yes

[root@harbor ~]# nmcli connection up ens160 
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3)
[root@harbor ~]# 

#注意:网段要和子网保持一致,其次如果修改的静态IP地址和原先的不一样会导致ssh远程连接断开。

1-1-子网一致.jpg

3. 开启路由转发

[root@harbor ~]# echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
[root@harbor ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@harbor ~]# 

4. 配置主机映射

cat >> /etc/hosts <<EOF
192.168.142.129 hb.reg.com harbor
192.168.142.150 k8s-master01 m1
192.168.142.151 k8s-node01 n1
192.168.142.152 k8s-node02 n2
EOF

[root@harbor ~]# tail -4 /etc/hosts 
192.168.142.129 hb.reg.com harbor
192.168.142.150 k8s-master01 m1
192.168.142.151 k8s-node01 n1
192.168.142.152 k8s-node02 n2

5. 配置本地仓库

vi /etc/yum.repos.d/rpm.repo

[BaseOS]
name=BaseOS
baseurl=/mnt/BaseOS
gpgcheck=0
[AppStream]
name=AppStream
baseurl=/mnt/AppStream
gpgcheck=0

6. 挂载

#临时
mount /dev/sr0 /mnt

#自动挂载
vi /etc/fstab

/dev/sr0     /mnt      iso9660 defaults        0 0

mount -a
#如果遇到下面报错可以在虚拟机设置里将"已连接"勾选上
[root@harbor ~]# mount /dev/sr0 /mnt
mount: /mnt: fsconfig system call failed: /dev/sr0: Can't open blockdev.
       dmesg(1) may have more information after failed mount system call.
       
#再试一下应该就可以了
[root@harbor ~]# mount /dev/sr0 /mnt
mount: /mnt: WARNING: source write-protected, mounted read-only.
[root@harbor ~]# df -h
Filesystem             Size  Used Avail Use% Mounted on
……
/dev/sr0               7.9G  7.9G     0 100% /mnt

1-0-设备状态.jpg

7. 常用工具安装

dnf install net-tools bash-completion wget curl vim tree -y

8. 安装 Docker

Step 1 — 安装必要的系统工具

yum install -y yum-utils

Step 2 — 添加软件源信息

yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/rhel/docker-ce.repo

Step 3 — 安装 Docker

yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Step 4 — 镜像加速器

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": ["https://hb.reg.com"],
  "registry-mirrors": [
    "https://mirror.ccs.tencentyun.com",
    "https://hub-mirror.c.163.com",
    "https://docker.xuanyuan.me",
    "https://docker.m.daocloud.io"
  ]
}
EOF

Step 5 — 开启 Docker 服务

systemctl daemon-reload 
systemctl enable --now docker
systemctl status docker

docker compose version

也可以传统二进制安装 docker-compose:

mv docker-compose-linux-x86_64 docker-compose
chmod +x docker-compose 
mv docker-compose /usr/bin
docker-compose -v

9. 准备 Harbor

官网地址:https://goharbor.io/docs/2.14.0/install-config

软件 版本 作用
Docker Engine Version > 20.10 用于运行Harbor环境
Docker Compose Docker compose > 2.3 用于管理Harbor服务
OpenSSL Latest (optional) 用于生成Harbor访问的私钥和证书
[root@harbor harbor]# docker --version
Docker version 29.7.1, build e9452d6
[root@harbor harbor]# docker compose version
Docker Compose version v5.3.1
[root@harbor harbor]# openssl -v
OpenSSL 3.2.2 4 Jun 2024 (Library: OpenSSL 3.2.2 4 Jun 2024)
[root@harbor harbor]# 

Step 1 — 安装 Harbor

#下载二进制包
wget https://github.com/goharbor/harbor/releases/download/v2.14.2/harbor-offline-installer-v2.14.2.tgz
[root@harbor ~]# ls
harbor-offline-installer-v2.14.2.tgz
[root@harbor ~]# tar -xzf harbor-offline-installer-v2.14.2.tgz -C /usr/local/
[root@harbor ~]# cd /usr/local/harbor/
[root@harbor harbor]# ls
common.sh  harbor.v2.14.2.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@harbor harbor]# 

Step 2 — 关闭防火墙和 SELinux(实验环境可临时关闭)

[root@harbor harbor]# systemctl disable --now firewalld.service 
Removed '/etc/systemd/system/multi-user.target.wants/firewalld.service'.
Removed '/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service'.
[root@harbor harbor]# systemctl is-active firewalld.service 
inactive
[root@harbor harbor]# setenforce 0
[root@harbor harbor]# getenforce 
Permissive
[root@harbor harbor]# 

Step 3 — 配置证书

官方文档:https://goharbor.io/docs/2.14.0/install-config/configure-https/

#生成CA证书
[root@harbor harbor]# mkdir certs
[root@harbor harbor]# cd certs
[root@harbor certs]# openssl genrsa -out ca.key 4096
[root@harbor certs]# openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Chongqing/L=Chongqing/O=Banan/OU=Chengke/CN=hb.reg.com" \
-key ca.key \
-out ca.crt
[root@harbor certs]# ls
ca.crt  ca.key
[root@harbor certs]#

Step 4 — 生成服务器证书

# 生成服务私钥
[root@harbor certs]# openssl genrsa -out hb.reg.com.key 4096        

#根据私钥生成服务证书请求(CSR)
[root@harbor certs]# openssl req -sha512 -new \
-subj "/C=CN/ST=Chongqing/L=Chongqing/O=Banan/OU=Chengke/CN=hb.reg.com" \
-key hb.reg.com.key \
-out hb.reg.com.csr
[root@harbor certs]# ls
ca.crt  ca.key  hb.reg.com.csr  hb.reg.com.key

#生成一个x509 v3扩展文件
[root@harbor certs]# cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=hb.reg.com
DNS.2=hb.reg
DNS.3=harbor
EOF
[root@harbor certs]# ls
ca.crt  ca.key  hb.reg.com.csr  hb.reg.com.key  v3.ext

#使用该v3.ext文件为Harbor主机生成证书
[root@harbor certs]# openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in hb.reg.com.csr \
-out hb.reg.com.crt
Certificate request self-signature ok
subject=C=CN, ST=Chongqing, L=Chongqing, O=Banan, OU=Chengke, CN=hb.reg.com
[root@harbor certs]# ls
ca.crt  ca.key  ca.srl  hb.reg.com.crt  hb.reg.com.csr  hb.reg.com.key  v3.ext

Step 5 — 向 Harbor 和 Docker 提供证书

#将服务器证书和密钥复制到 Harbor 主机上的 certificates 文件夹中
[root@harbor certs]# pwd
/usr/local/harbor/certs
[root@harbor certs]# ls
ca.crt  ca.key  ca.srl  hb.reg.com.crt  hb.reg.com.csr  hb.reg.com.key  v3.ext
[root@harbor certs]# mkdir -p /data/certs
[root@harbor certs]# cp hb.reg.com.crt /data/certs/
[root@harbor certs]# cp hb.reg.com.key /data/certs/
[root@harbor certs]# ls /data/certs/
hb.reg.com.crt  hb.reg.com.key

#转换 hb.reg.com.crt 为 hb.reg.com.cert,供 Docker 使用
[root@harbor certs]# openssl x509 -inform PEM -in hb.reg.com.crt -out hb.reg.com.cert
[root@harbor certs]# ls
ca.crt  ca.key  ca.srl  hb.reg.com.cert  hb.reg.com.crt  hb.reg.com.csr  hb.reg.com.key  v3.ext


#将服务器证书,私钥文件和 CA 文件复制到 Harbor 主机上的 Docker 证书文件夹中
[root@harbor certs]# cp hb.reg.com.cert hb.reg.com.key ca.crt /etc/docker/certs.d/hb.reg.com/

[root@harbor certs]# tree /etc/docker/certs.d/
/etc/docker/certs.d/
└── hb.reg.com
    ├── ca.crt
    ├── hb.reg.com.cert
    └── hb.reg.com.key

2 directories, 3 files

Step 6 — 重新启动 Docker Engine

[root@harbor certs]# systemctl restart docker

10. 配置 Harbor

#step1:修改配置文件
[root@harbor ~]# cd /usr/local/harbor
[root@harbor harbor]# ls
certs  common.sh  harbor.v2.14.2.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@harbor harbor]# cp harbor.yml.tmpl harbor.yml
[root@harbor harbor]# ls
certs  common.sh  harbor.v2.14.2.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@harbor harbor]# vim harbor.yml
#修改项如下:
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by
external clients.
hostname: hb.reg.com
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to
https port
port: 80
# https related config
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
certificate: /data/certs/hb.reg.com.crt
private_key: /data/certs/hb.reg.com.key
.....
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: hb123
......
# The default data volume
data_volume: /data/harbor
.......


#step2:创建数据卷目录
[root@harbor harbor]# mkdir -p /data/harbor
[root@harbor harbor]# mkdir -p /data/docker
[root@harbor harbor]# ls /data/
certs  docker  harbor

11. 加载 Harbor 镜像

[root@harbor harbor]# ls
certs  common.sh  harbor.v2.14.2.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@harbor harbor]# docker load -i harbor.v2.14.2.tar.gz
Loaded image: goharbor/prepare:v2.14.2
Loaded image: goharbor/trivy-adapter-photon:v2.14.2
Loaded image: goharbor/harbor-core:v2.14.2
Loaded image: goharbor/harbor-db:v2.14.2
Loaded image: goharbor/harbor-jobservice:v2.14.2
Loaded image: goharbor/harbor-registryctl:v2.14.2
Loaded image: goharbor/nginx-photon:v2.14.2
Loaded image: goharbor/harbor-portal:v2.14.2
Loaded image: goharbor/redis-photon:v2.14.2
Loaded image: goharbor/registry-photon:v2.14.2
Loaded image: goharbor/harbor-log:v2.14.2
Loaded image: goharbor/harbor-exporter:v2.14.2




[root@harbor harbor]# docker images 

IMAGE                                   ID             DISK USAGE   CONTENT SIZE   EXTRA
goharbor/harbor-core:v2.14.2            def2f48ebb3a        413MB          205MB        
goharbor/harbor-db:v2.14.2              3417b2d261fe        593MB          293MB        
goharbor/harbor-exporter:v2.14.2        ae87109e4c79        269MB          133MB        
goharbor/harbor-jobservice:v2.14.2      2ad0c5a5810c        362MB          180MB        
goharbor/harbor-log:v2.14.2             32448bb26446        379MB          188MB        
goharbor/harbor-portal:v2.14.2          32fb3a3f57cd        370MB          183MB        
goharbor/harbor-registryctl:v2.14.2     cfa0b205c9fd        334MB          167MB        
goharbor/nginx-photon:v2.14.2           09aadc2e99b0        353MB          175MB        
goharbor/prepare:v2.14.2                a4380f5d2bab        413MB          203MB        
goharbor/redis-photon:v2.14.2           ac49d496e188        383MB          190MB        
goharbor/registry-photon:v2.14.2        a4cf93bc522b        177MB         88.4MB        
goharbor/trivy-adapter-photon:v2.14.2   4201757303dd        807MB          403MB        

12. 启动 Harbor

踩坑提示:必须先运行 ./prepare --with-trivy 生成配置文件,跳过这一步容易出问题。

cd /usr/local/harbor

# 先跑 prepare 生成配置文件(跳过这步,容易踩坑)
./prepare --with-trivy

# 正式安装启动
./install.sh --with-trivy
展开查看完整输出
[root@harbor harbor]# cd /usr/local/harbor
[root@harbor harbor]# ./prepare --with-trivy
prepare base dir is set to /usr/local/harbor
Generated configuration file: /config/portal/nginx.conf
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/registryctl/config.yml
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
……
Generated and saved secret to file: /data/secret/keys/secretkey
Successfully called func: create_root_cert
Generated configuration file: /config/trivy-adapter/env
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir

[root@harbor harbor]# ./install.sh --with-trivy

[Step 0]: checking if docker is installed ...

Note: docker version: 29.7.1

[Step 1]: checking docker-compose is installed ...

Note: Docker Compose version v5.3.1

[Step 2]: loading Harbor images ...
Loaded image: goharbor/prepare:v2.14.2
Loaded image: goharbor/trivy-adapter-photon:v2.14.2
Loaded image: goharbor/harbor-core:v2.14.2
Loaded image: goharbor/harbor-db:v2.14.2
Loaded image: goharbor/harbor-jobservice:v2.14.2
Loaded image: goharbor/harbor-registryctl:v2.14.2
Loaded image: goharbor/nginx-photon:v2.14.2
Loaded image: goharbor/harbor-portal:v2.14.2
Loaded image: goharbor/redis-photon:v2.14.2
Loaded image: goharbor/registry-photon:v2.14.2
Loaded image: goharbor/harbor-log:v2.14.2
Loaded image: goharbor/harbor-exporter:v2.14.2


[Step 3]: preparing environment ...

[Step 4]: preparing harbor configs ...
prepare base dir is set to /usr/local/harbor
Clearing the configuration file: /config/portal/nginx.conf
Clearing the configuration file: /config/log/logrotate.conf
Clearing the configuration file: /config/log/rsyslog_docker.conf
Clearing the configuration file: /config/nginx/nginx.conf
Clearing the configuration file: /config/core/env
Clearing the configuration file: /config/core/app.conf
Clearing the configuration file: /config/registry/passwd
Clearing the configuration file: /config/registry/config.yml
Clearing the configuration file: /config/registryctl/env
Clearing the configuration file: /config/registryctl/config.yml
Clearing the configuration file: /config/db/env
Clearing the configuration file: /config/jobservice/env
Clearing the configuration file: /config/jobservice/config.yml
Clearing the configuration file: /config/trivy-adapter/env
Generated configuration file: /config/portal/nginx.conf
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/registryctl/config.yml
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
……
loaded secret from file: /data/secret/keys/secretkey
Generated configuration file: /config/trivy-adapter/env
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir


Note: stopping existing Harbor instance ...


[Step 5]: starting Harbor ...
[+] up 11/11
 ✔ Network harbor_harbor       Created                                                                     0.0s
 ✔ Container harbor-log        Started                                                                     0.3s
 ✔ Container registry          Started                                                                     0.6s
 ✔ Container harbor-db         Started                                                                     0.6s
 ✔ Container registryctl       Started                                                                     0.6s
 ✔ Container redis             Started                                                                     0.5s
 ✔ Container harbor-portal     Started                                                                     0.6s
 ✔ Container trivy-adapter     Started                                                                     0.7s
 ✔ Container harbor-core       Started                                                                     0.8s
 ✔ Container harbor-jobservice Started                                                                     0.9s
 ✔ Container nginx             Started                                                                     1.0s
✔ ----Harbor has been installed and started successfully.----

#目录中会生成 docker-compose.yml 文件和 common 目录
[root@harbor harbor]# ls
certs   common.sh           harbor.v2.14.2.tar.gz  harbor.yml.tmpl  LICENSE
common  docker-compose.yml  harbor.yml             install.sh       prepare
[root@harbor harbor]# 

[root@harbor harbor]# docker compose ps
NAME                IMAGE                                   COMMAND                  SERVICE         CREATED              STATUS                        PORTS
harbor-core         goharbor/harbor-core:v2.14.2            "/harbor/entrypoint.…"   core            About a minute ago   Up About a minute (healthy)   
harbor-db           goharbor/harbor-db:v2.14.2              "/docker-entrypoint.…"   postgresql      About a minute ago   Up About a minute (healthy)   
harbor-jobservice   goharbor/harbor-jobservice:v2.14.2      "/harbor/entrypoint.…"   jobservice      About a minute ago   Up About a minute (healthy)   
harbor-log          goharbor/harbor-log:v2.14.2             "/bin/sh -c /usr/loc…"   log             About a minute ago   Up About a minute (healthy)   127.0.0.1:1514->10514/tcp
harbor-portal       goharbor/harbor-portal:v2.14.2          "nginx -g 'daemon of…"   portal          About a minute ago   Up About a minute (healthy)   
nginx               goharbor/nginx-photon:v2.14.2           "nginx -g 'daemon of…"   proxy           About a minute ago   Up About a minute (healthy)   0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp
redis               goharbor/redis-photon:v2.14.2           "redis-server /etc/r…"   redis           About a minute ago   Up About a minute (healthy)   
registry            goharbor/registry-photon:v2.14.2        "/home/harbor/entryp…"   registry        About a minute ago   Up About a minute (healthy)   
registryctl         goharbor/harbor-registryctl:v2.14.2     "/home/harbor/start.…"   registryctl     About a minute ago   Up About a minute (healthy)   
trivy-adapter       goharbor/trivy-adapter-photon:v2.14.2   "/home/scanner/entry…"   trivy-adapter   About a minute ago   Up About a minute (healthy)   
[root@harbor harbor]# 

13. 配置启动服务

[root@harbor harbor]# docker compose down
[+] down 11/11
 ✔ Container nginx             Removed                                                                     0.2s
 ✔ Container registryctl       Removed                                                                     0.1s
 ✔ Container harbor-jobservice Removed                                                                     0.2s
 ✔ Container trivy-adapter     Removed                                                                     0.2s
 ✔ Container harbor-portal     Removed                                                                     0.1s
 ✔ Container harbor-core       Removed                                                                     3.1s
 ✔ Container registry          Removed                                                                     0.1s
 ✔ Container redis             Removed                                                                     0.1s
 ✔ Container harbor-db         Removed                                                                     0.1s
 ✔ Container harbor-log        Removed                                                                    10.1s
 ✔ Network harbor_harbor       Removed                                                                     0.1s
[root@harbor harbor]# vim /usr/lib/systemd/system/harbor.service
[root@harbor harbor]# cat /usr/lib/systemd/system/harbor.service 
[Unit]
Documentation=https://goharbor.io/docs/
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service

#如果是二进制安装docker-compose则需要改为
#ExecStart=/usr/bin/docker-compose -f /usr/local/harbor/docker-compose.yml up
#ExecStop=/usr/bin/docker-compose -f /usr/local/harbor/docker-compose.yml down
[Service]
Type=simple
ExecStart=/usr/bin/docker compose -f /usr/local/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker compose -f /usr/local/harbor/docker-compose.yml down
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
[root@harbor harbor]# systemctl daemon-reload
[root@harbor harbor]# systemctl stop harbor.service
[root@harbor harbor]# systemctl start harbor
[root@harbor harbor]# systemctl status harbor

Harbor 客户端配置

在 Windows 的 hosts 文件中配置 IP 和主机映射。推荐使用软件 SwitchHosts

"C:\Windows\System32\drivers\etc\hosts"
#文件末尾加上
192.168.142.129 hb.reg.com

1-2-SwitchHosts.jpg

注意:默认 HTTP 私有仓库不能访问,需要设置以下参数才可以。前面已经配置过了。

vim /etc/docker/daemon.json

{
"insecure-registries" : ["https://hb.reg.com"]
}

测试(可选)

#.拉取基础镜像
[root@harbor harbor]# docker pull busybox:1.37
1.37: Pulling from library/busybox
436a1b1fd078: Pull complete 
a4d00a06cf87: Download complete 
Digest: sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0
Status: Downloaded newer image for busybox:1.37
docker.io/library/busybox:1.37
#重新打标签
[root@harbor harbor]# docker tag busybox:1.37 hb.reg.com/library/busybox:1.37
# 登录 Harbor
[root@harbor harbor]# docker login hb.reg.com
Username: admin
Password: # 此处输入hb123
WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/

#推送到自己搭建的镜像仓库
[root@harbor harbor]# docker push hb.reg.com/library/busybox:1.37
The push refers to repository [hb.reg.com/library/busybox]
436a1b1fd078: Pushed 
1.37: digest: sha256:7a3ebe5bfd1a4a19797d20b0c0bb39d44393e9a03fd852c0865b0f540d868df0 size: 610

i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
         sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0 -> sha256:7a3ebe5bfd1a4a19720b0c0bb39d44393e9a03fd852c0865b0f540d868df0

#清理本地镜像
[root@harbor harbor]# docker images | grep busybox
busybox:1.37                            9db7b59979c3        6.7MB         2.22MB   
hb.reg.com/library/busybox:1.37         9db7b59979c3        6.7MB         2.22MB   
[root@harbor harbor]# docker rmi busybox:1.37 hb.reg.com/library/busybox:1.37 
Untagged: busybox:1.37
Untagged: hb.reg.com/library/busybox:1.37
Deleted: sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0

#从私有仓库拉回验证
[root@harbor harbor]# docker pull hb.reg.com/library/busybox:1.37
1.37: Pulling from library/busybox
436a1b1fd078: Pull complete 
Digest: sha256:7a3ebe5bfd1a4a19797d20b0c0bb39d44393e9a03fd852c0865b0f540d868df0
Status: Downloaded newer image for hb.reg.com/library/busybox:1.37
hb.reg.com/library/busybox:1.37
[root@harbor harbor]# docker images | grep busybox
hb.reg.com/library/busybox:1.37         7a3ebe5bfd1a        6.7MB         2.21MB   

1-3-镜像仓库.jpg


二、集群准备

在 Rocky-master、Rocky-node1、Rocky-node2 三台主机上操作。

Rocky Linux 是基于 RHEL 源码重建的发行版,安装完成后 /etc/yum.repos.d/ 里会自动包含官方的软件仓库配置。常见的就是这几个:

  • rocky.repo — 包含 BaseOS、AppStream、Extras 等核心仓库
  • Rocky-AppStream.repoRocky-BaseOS.repoRocky-Extras.repo
  • 关键系统组件仓库:Rocky-PowerTools.repo(8 系列)、Rocky-CR.repoRocky-Debuginfo.repoRocky-Sources.repo
[root@localhost ~]# ls /etc/yum.repos.d/
rocky-addons.repo  rocky-devel.repo  rocky-extras.repo  rocky.repo  rocky-security.repo
[root@localhost ~]# yum repolist
仓库 id                                      仓库名称
appstream                                    Rocky Linux 10 - AppStream
baseos                                       Rocky Linux 10 - BaseOS
extras                                       Rocky Linux 10 - Extras

1. 关闭防火墙和 SELinux

[root@localhost ~]# systemctl disable --now firewalld
Removed '/etc/systemd/system/multi-user.target.wants/firewalld.service'.
Removed '/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service'.
[root@localhost ~]# sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
[root@localhost ~]# setenforce 0

2. 关闭交换分区

[root@localhost ~]# swapoff -a
[root@localhost ~]# sed -i 's/.*swap.*/#&/' /etc/fstab
[root@localhost ~]# free -m
               total        used        free      shared  buff/cache   available
Mem:            3621         496        3058           9         288        3124
Swap:              0           0           0
[root@localhost ~]# 

3. 安装基本软件

dnf install net-tools nfs-utils vim wget curl bash-completion device-mapper-persistent-data psmisc tree openssh openssh-server -y

4. 修改 Linux 最大连接数

[root@localhost ~]# tail -7 /etc/security/limits.conf
# 在文件末尾加上:
# End of file
* soft nofile 655350
* hard nofile 655350
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited

5. 安装 IPVS

dnf install ipvsadm -y

6. 开启路由转发

[root@localhost ~]# echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1

三、节点基础配置

Rocky-master

[root@localhost ~]# hostnamectl hostname k8s-master01
[root@localhost ~]# bash
[root@k8s-master01 ~]# ip a
	……
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    ……
    inet 192.168.142.150/24 brd 192.168.142.255 scope global noprefixroute 
#查看网卡类型:
[root@k8s-master01 ~]# ls /etc/NetworkManager/system-connections/
ens160.nmconnection
#修改为静态IP地址
[root@k8s-master01 ~]# nmcli connection modify ens160 ipv4.method manual ipv4.addresses 192.168.142.150/24 ipv4.dns "223.5.5.5 8.8.8.8" ipv4.gateway 192.168.142.2 connection.autoconnect yes
[root@k8s-master01 ~]# nmcli connection up ens160 
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/3)
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# 
#配置主机映射
cat > /etc/hosts <<EOF
192.168.142.150 k8s-master01 m1
192.168.142.151 k8s-node01 n1
192.168.142.152 k8s-node02 n2
192.168.142.129 hb.reg.com harbor
EOF

Rocky-node1

[root@localhost ~]# hostnamectl hostname k8s-node01 && bash

[root@k8s-node01 ~]# nmcli connection modify ens160 ipv4.method manual ipv4.addresses 192.168.142.151/24 ipv4.dns "223.5.5.5 8.8.8.8" ipv4.gateway 192.168.142.2 connection.autoconnect yes
[root@k8s-node01 ~]# nmcli connection up ens160 
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/3)
[root@k8s-node01 ~]# 

Rocky-node2

[root@localhost ~]# hostnamectl hostname k8s-node02 && bash

[root@k8s-node02 ~]# nmcli connection modify ens160 ipv4.method manual ipv4.addresses 192.168.142.152/24 ipv4.dns "223.5.5.5 8.8.8.8" ipv4.gateway 192.168.142.2 connection.autoconnect yes
[root@k8s-node02 ~]# nmcli connection up ens160 
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/3)
[root@k8s-node02 ~]# 

四、搭建集群

1. 安装 Docker(三台虚拟机)

#安装基础工具
dnf install -y vim wget curl net-tools bash-completion yum-utils
# 添加阿里云 Docker 仓库
yum-config-manager --add-repo \
  https://mirrors.aliyun.com/docker-ce/linux/rhel/docker-ce.repo

# 安装 Docker 及相关组件
dnf install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
  
  
# 配置Docker
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": "50"
  },
  "insecure-registries": ["hb.reg.com"],
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://docker.1ms.run",
    "https://dockerproxy.net",
    "https://proxy.vvvv.ee",
    "https://dockerproxy.link",
    "https://7kjolzcz.mirror.aliyuncs.com"
  ]
}
EOF

systemctl daemon-reload
systemctl enable --now docker
systemctl status docker

2. 选择 CRI 方案

K8s 靠 CRI 和运行时通信,1.24 移除内置 dockershim 后出现两种替代方案:

方案 架构 适用场景
Docker + cri-dockerd 加一层垫片,保留 Docker 体验 习惯 Docker 命令的团队
Docker + containerd 直连 Docker 仅作镜像工具,绕过 dockerd 新项目、追求性能

新项目建议选 containerd,如果团队强依赖 Docker 操作习惯就选 cri-dockerd。本文使用方案一。

3. 安装 CRI(三台主机执行)

Step 1 — 下载 cri-docker
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.17/cri-dockerd-0.3.17.amd64.tgz

[root@k8s-node02 ~]# ls
cri-dockerd-0.3.17.amd64.tgz
[root@k8s-node02 ~]# tar -xf cri-dockerd-0.3.17.amd64.tgz
[root@k8s-node02 ~]# cp cri-dockerd/cri-dockerd /usr/bin/
[root@k8s-node02 ~]# ls /usr/bin/ | grep cri-dockerd
cri-dockerd
[root@k8s-node02 ~]# chmod +x /usr/bin/cri-dockerd

4. 配置 cri-docker 服务

cat > /usr/lib/systemd/system/cri-docker.service <<EOF
[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

#--pod-infra-container-image=hb.reg.com/library/pause:3.10.2 指定Harbor镜像服务器pause镜像
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd \
  --container-runtime-endpoint fd:// \
  --network-plugin=cni \
  --pod-infra-container-image=hb.reg.com/library/pause:3.10.2
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
cat > /usr/lib/systemd/system/cri-docker.socket <<EOF
[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

注意:此文件也可以从 wget https://github.com/Mirantis/cri-dockerd/archive/refs/tags/v0.3.17.tar.gz 包中 packaging/systemd/ 目录下获取。然后修改 /etc/systemd/system/cri-docker.service 文件,为 Service.ExecStart 字段增加 --network-plugin--pod-infra-container-image 选项。--pod-infra-container-image 镜像 tag 需要根据具体 k8s 安装版本指定。也就是要修改网络和根容器镜像。

5. 启动服务

systemctl daemon-reload
systemctl enable --now cri-docker
systemctl is-active cri-docker

6. 安装 Kubernetes

Step 1 — 添加 Kubernetes 源

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

Step 2 — 安装 K8s
dnf install -y kubelet kubeadm kubectl

阿里云镜像站:Kubernetes镜像-Kubernetes镜像下载安装-开源镜像站-阿里云

#已安装软件包清单:
[root@k8s-node01 ~]# rpm -qa | grep kube
#CNI二进制插件集合:提供bridge、loopback等基础网络二进制文件,配合cri-dockerd的--network-plugin=cni参数使用
kubernetes-cni-1.9.1-150500.1.1.x86_64
#节点代理核心进程:与CRI(cri-dockerd)交互,负责创建、管理Pod;集群所有节点必须部署
kubelet-1.36.3-150500.1.1.x86_64
#客户端命令行工具:集群管理入口,执行kubectl get pod、kubectl apply等各类集群操作
kubectl-1.36.3-150500.1.1.x86_64
#集群部署工具:通过kubeadm init初始化控制平面、kubeadm join将工作节点接入集群
kubeadm-1.36.3-150500.1.1.x86_64

[root@k8s-master01 ~]# which kubelet kubeadm kubectl
/usr/bin/kubelet
/usr/bin/kubeadm
/usr/bin/kubectl

[root@k8s-master01 ~]# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"36", EmulationMajor:"", EmulationMinor:"", MinCompatibilityMajor:"", MinCompatibilityMinor:"", GitVersion:"v1.36.3", GitCommit:"0f29094e5b73085e3802ecc1298ecae13866bfe6", GitTreeState:"clean", BuildDate:"2026-07-22T18:09:52Z", GoVersion:"go1.26.5", Compiler:"gc", Platform:"linux/amd64"}

注意:现在不要尝试启动 kube,通过上述命令检验安装成功即可。

7. 拉取所需镜像

[root@k8s-master01 ~]# kubeadm config images list
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

注意:主节点需要导入全部镜像,从节点只需导入 kube-proxycorednspause 这三个镜像。

#我把所有镜像拉取到Harbor镜像服务器上,然后三个节点自动在Harbor上拉取

[root@harbor ~]# cat all-images.txt 
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

[root@harbor ~]# while read img; do docker pull $img; done < all-images.txt
[root@harbor ~]# while read img; do
  docker tag "${img}" hb.reg.com/library/"${img#registry.k8s.io/}"
  docker push hb.reg.com/library/"${img#registry.k8s.io/}"
done < all-images.txt


[root@harbor ~]# docker images
	……
hb.reg.com/library/coredns/coredns:v1.14.2           e7e6440cfd1e        102MB         23.3MB        
hb.reg.com/library/etcd:3.6.8-0                      397189418d1a       88.2MB         22.9MB        
hb.reg.com/library/kube-apiserver:v1.36.3            b4bc06c81fd7        128MB         29.8MB        
hb.reg.com/library/kube-controller-manager:v1.36.3   ed56454bf514        114MB         26.4MB        
hb.reg.com/library/kube-proxy:v1.36.3                919d710a0e8b        114MB           30MB        
hb.reg.com/library/kube-scheduler:v1.36.3            128fc07d278d         83MB         20.5MB        
hb.reg.com/library/pause:3.10.2                      f548e0e8e3dc       1.06MB          318kB        

#注意:coredns特殊格式:registry.k8s.io/coredns/coredns:v1.14.2(两层路径)kubeadm 的--image-repository参数设计上不支持二级镜像仓库路径,需要执行下面的命令

[root@harbor ~]# docker tag hb.reg.com/library/coredns/coredns:v1.14.2 hb.reg.com/library/coredns:v1.14.2
[root@harbor ~]# docker push hb.reg.com/library/coredns:v1.14.2

kubeadm 根据规则拼接镜像地址,通过 CRI 接口请求 cri-dockerd,最终由 Docker 向 Harbor 发起镜像拉取;控制平面镜像地址由 kubeadm 管控,pause 沙箱镜像由 cri-dockerd 独立配置决定。

8. 初始化主节点

镜像拉取过程:kubeadm → 通过CRI gRPC协议 → cri-dockerd → 调用docker接口 → docker pull镜像

[root@k8s-master01 ~]# kubeadm init --apiserver-advertise-address=192.168.142.150 \
--kubernetes-version=v1.36.3 \
--service-cidr=10.10.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository=hb.reg.com/library \
--cri-socket unix:///var/run/cri-dockerd.sock \
--ignore-preflight-errors=all

……
# 需要注意下面的输出,后面要用
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.142.150:6443 --token aqizik.2rg53a6j0gvqpm2m \
	--discovery-token-ca-cert-hash sha256:13ceb37049affce20b87038a16a09af73e07e2ad3d572644350ff3ab67612203

9. 创建 .kube 目录

[root@k8s-master01 ~]# mkdir -p $HOME/.kube
[root@k8s-master01 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master01 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-master01 ~]# export KUBECONFIG=/etc/kubernetes/admin.conf
[root@k8s-master01 ~]# kubectl get node
NAME           STATUS     ROLES           AGE   VERSION
k8s-master01   NotReady   control-plane   29m   v1.36.3

10. 增加工作节点

[root@k8s-node01 ~]# kubeadm join 192.168.142.150:6443 --token aqizik.2rg53a6j0gvqpm2m \
        --discovery-token-ca-cert-hash sha256:13ceb37049affce20b87038a16a09af73e07e2ad3d572644350ff3ab67612203 \
    --cri-socket unix:///var/run/cri-dockerd.sock
	……

[root@k8s-node02 ~]# kubeadm join 192.168.142.150:6443 --token aqizik.2rg53a6j0gvqpm2m \
        --discovery-token-ca-cert-hash sha256:13ceb37049affce20b87038a16a09af73e07e2ad3d572644350ff3ab67612203 \
    --cri-socket unix:///var/run/cri-dockerd.sock
	……
	
[root@k8s-master01 ~]# kubectl get node
NAME           STATUS     ROLES           AGE   VERSION
k8s-master01   NotReady   control-plane   34m   v1.36.3
k8s-node01     NotReady   <none>          67s   v1.36.3
k8s-node02     NotReady   <none>          60s   v1.36.3

五、部署网络插件 Calico

官方文档:https://docs.tigera.io/calico/latest/getting-started/kubernetes/self-managed-onprem/onpremises#install-calico

5-1-部署网络插件.jpg

1. 下载 Calico 部署文件

[root@k8s-master01 ~]# curl https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml -o calico.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  341k  100  341k    0     0   155k      0  0:00:02  0:00:02 --:--:--  155k
[root@k8s-master01 ~]# ll
总计 15748
-rw-------. 1 root root        719  8月 2日 18:31 anaconda-ks.cfg
-rw-r--r--. 1 root root     349572  8月 3日 17:52 calico.yaml
drwxr-xr-x. 2 1001 docker       25 2025年 4月 1日 cri-dockerd
-rw-r--r--. 1 root root   15767044 2025年 4月 1日 cri-dockerd-0.3.17.amd64.tgz
[root@k8s-master01 ~]# grep image* calico.yaml
          image: quay.io/calico/cni:v3.32.1
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/cni:v3.32.1
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/node:v3.32.1
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/node:v3.32.1
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/kube-controllers:v3.32.1
          imagePullPolicy: IfNotPresent
[root@k8s-master01 ~]# 

2. 拉取镜像并推送到 Harbor

#这里我也把需要的镜像拉取到Harbor上,在Harbor上操作:
docker pull quay.io/calico/cni:v3.32.1
docker pull quay.io/calico/node:v3.32.1
docker pull quay.io/calico/kube-controllers:v3.32.1

docker login hb.reg.com

docker tag quay.io/calico/cni:v3.32.1 hb.reg.com/library/calico/cni:v3.32.1
docker tag quay.io/calico/node:v3.32.1 hb.reg.com/library/calico/node:v3.32.1
docker tag quay.io/calico/kube-controllers:v3.32.1 hb.reg.com/library/calico/kube-controllers:v3.32.1

docker push hb.reg.com/library/calico/cni:v3.32.1
docker push hb.reg.com/library/calico/node:v3.32.1
docker push hb.reg.com/library/calico/kube-controllers:v3.32.1

3. 修改并部署 Calico

#修改calico.yaml文件内的镜像地址
[root@k8s-master01 ~]# sed -i 's#quay.io/calico/#hb.reg.com/library/calico/#g' calico.yaml
[root@k8s-master01 ~]# grep 'image:' calico.yaml
          image: hb.reg.com/library/calico/cni:v3.32.1
          image: hb.reg.com/library/calico/cni:v3.32.1
          image: hb.reg.com/library/calico/node:v3.32.1
          image: hb.reg.com/library/calico/node:v3.32.1
          image: hb.reg.com/library/calico/kube-controllers:v3.32.1

[root@k8s-master01 ~]# vim calico.yaml
……
7603             # Enable IPIP
7604             - name: CALICO_IPV4POOL_IPIP
7605               value: "off"
7606             # Enable or Disable VXLAN on the default IP pool.
7607             - name: CALICO_IPV4POOL_VXLAN
7608               value: "Never"
7609             # Enable or Disable VXLAN on the default IPv6 IP pool.
7610             - name: CALICO_IPV6POOL_VXLAN
7611               value: "Never"
……
7633             - name: CALICO_IPV4POOL_CIDR
7634               value: "10.244.0.0/16"



# 部署 calico
[root@k8s-master01 ~]# kubectl apply -f calico.yaml
poddisruptionbudget.policy/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
serviceaccount/calico-node created
serviceaccount/calico-cni-plugin created
configmap/calico-config created
……

4. 验证部署结果

[root@k8s-master01 ~]# kubectl get pods -n kube-system -w
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-5b95cfb5d8-fh9xb   1/1     Running   0          64s
calico-node-8g9fj                          1/1     Running   0          64s
calico-node-fr5b9                          1/1     Running   0          64s
calico-node-k8sd9                          1/1     Running   0          64s
coredns-8494d4c5fc-dh2n8                   1/1     Running   0          66m
coredns-8494d4c5fc-mblkx                   1/1     Running   0          66m
etcd-k8s-master01                          1/1     Running   0          66m
kube-apiserver-k8s-master01                1/1     Running   0          66m
kube-controller-manager-k8s-master01       1/1     Running   0          66m
kube-proxy-bpkm2                           1/1     Running   0          66m
kube-proxy-tkdlx                           1/1     Running   0          33m
kube-proxy-ww5rj                           1/1     Running   0          33m
kube-scheduler-k8s-master01                1/1     Running   0          66m
coredns-8494d4c5fc-mblkx                   1/1     Running   0          67m


[root@k8s-master01 ~]# kubectl get node
NAME           STATUS   ROLES           AGE   VERSION
k8s-master01   Ready    control-plane   67m   v1.36.3
k8s-node01     Ready    <none>          34m   v1.36.3
k8s-node02     Ready    <none>          34m   v1.36.3
[root@k8s-master01 ~]# kubectl get node -o wide
NAME           STATUS   ROLES           AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                        KERNEL-VERSION                              CONTAINER-RUNTIME
k8s-master01   Ready    control-plane   68m   v1.36.3   192.168.142.150   <none>        Rocky Linux 10.2 (Red Quartz)   6.12.0-211.16.1.el10_2.0.1.x86_64 (amd64)   docker://29.7.1
k8s-node01     Ready    <none>          34m   v1.36.3   192.168.142.151   <none>        Rocky Linux 10.2 (Red Quartz)   6.12.0-211.16.1.el10_2.0.1.x86_64 (amd64)   docker://29.7.1
k8s-node02     Ready    <none>          34m   v1.36.3   192.168.142.152   <none>        Rocky Linux 10.2 (Red Quartz)   6.12.0-211.16.1.el10_2.0.1.x86_64 (amd64)   docker://29.7.1
[root@k8s-master01 ~]# kubectl get pod -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-5b95cfb5d8-fh9xb   1/1     Running   0          4m2s
kube-system   calico-node-8g9fj                          1/1     Running   0          4m2s
kube-system   calico-node-fr5b9                          1/1     Running   0          4m2s
kube-system   calico-node-k8sd9                          1/1     Running   0          4m2s
kube-system   coredns-8494d4c5fc-dh2n8                   1/1     Running   0          69m
kube-system   coredns-8494d4c5fc-mblkx                   1/1     Running   0          69m
kube-system   etcd-k8s-master01                          1/1     Running   0          69m
kube-system   kube-apiserver-k8s-master01                1/1     Running   0          69m
kube-system   kube-controller-manager-k8s-master01       1/1     Running   0          69m
kube-system   kube-proxy-bpkm2                           1/1     Running   0          69m
kube-system   kube-proxy-tkdlx                           1/1     Running   0          36m
kube-system   kube-proxy-ww5rj                           1/1     Running   0          36m
kube-system   kube-scheduler-k8s-master01                1/1     Running   0          69m

至此,基于 cri-dockerd 搭建的三节点 K8s 集群部署完成,Calico 网络插件正常运行,三台节点全部进入 Ready 状态,集群具备 Pod 调度与网络通信能力。


六、功能测试

部署一个测试 Pod 验证集群可用性:

# 创建测试 Pod
[root@k8s-master01 ~]# kubectl run nginx-test --image=hb.reg.com/library/nginx:latest --port=80
pod/nginx-test created

# 暴露为 NodePort
[root@k8s-master01 ~]# kubectl expose pod nginx-test --port=80 --type=NodePort
service/nginx-test exposed

# 查看 Pod 和服务状态
[root@k8s-master01 ~]# kubectl get pod,svc
NAME             READY   STATUS    RESTARTS   AGE
pod/nginx-test   1/1     Running   0          30s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.10.0.1       <none>        443/TCP        78m
service/nginx-test   NodePort    10.10.117.216   <none>        80:31245/TCP   10s

# 测试访问(在任意节点执行)
[root@k8s-node01 ~]# curl http://192.168.142.151:31245
<!DOCTYPE html>……  # 返回 Nginx 欢迎页即表示集群正常

# 清理测试资源
[root@k8s-master01 ~]# kubectl delete pod nginx-test
[root@k8s-master01 ~]# kubectl delete svc nginx-test

集群常用命令

# 查看集群节点
kubectl get nodes -o wide
# 查看系统组件pod
kubectl get pods -n kube-system
# 查看集群健康状态
kubectl get cs
# calico查看IP池
kubectl get ippools -o yaml
# 查看集群所有资源简要信息
kubectl api-resources

强列建议:最后,强烈建议给四台虚拟机都拍个快照。


踩坑汇总

序号 问题 现象 解决方案
1 mount /dev/sr0 失败 Can't open blockdev 虚拟机设置中勾选"已连接"
2 跳过 ./prepare 导致启动异常 Harbor 启动后组件状态异常 必须先执行 ./prepare --with-trivy./install.sh
3 CoreDNS 镜像二级路径不兼容 kubeadm 无法拉取 coredns/coredns 额外打平标签:docker tag .../coredns/coredns:v1.14.2 .../coredns:v1.14.2
4 join 命令 token 过期 kubeadm join 报 token 无效 kubeadm token create --print-join-command 重新生成
5 网卡名称不一致 nmcli 配置后网络不生效 ls /etc/NetworkManager/system-connections/ 确认实际网卡名
6 Node 状态长期 NotReady CNI 网络插件未部署 部署 Calico 或 Flannel 等网络插件即可

Read more

每日一讲(8.4-5)

每日一讲(8.4-5)

一、描述 Linux 启动流程,从 BIOS 到用户登录。 Linux 启动流程,从 BIOS 到用户登录,大致流程为: BIOS→Boot Loader→内核→initramfs→PID 1→多用户目标→登录。 1. BIOS/UEFI 阶段 * 按下电源键后,BIOS(或 UEFI)执行自检(POST),检测 CPU、内存、硬盘等硬件。 * 按设定的启动顺序,从硬盘、U盘等介质读取引导程序。 * UEFI 模式下读取 ESP 分区中的 EFI 引导项;传统 BIOS 模式读取磁盘 MBR(主引导记录,

By Admin
虚拟机克隆

虚拟机克隆

VMware 虚拟机克隆完整指南 K8s 集群搭建前置篇 | 2026-08-03 为什么需要克隆虚拟机 搭建 Kubernetes 集群至少需要三台节点——一台 Master 和两台 Worker。如果用传统方式逐台安装操作系统、配置环境,不仅耗时费力,还容易产生配置偏差,导致后续集群组件无法正常工作。 VMware 的克隆功能可以完美解决这个问题:先精心配置一台"模板"虚拟机,安装好操作系统、基础工具和公共依赖,然后一键克隆出多台完全一致的节点。克隆完成后,只需修改每台节点的主机名和 IP 地址就能投入使用。 本文在 VMware Workstation 17 环境下,以 Rocky Linux 10.2 作为模板系统,演示克隆三台 K8s 节点的完整流程。文末附有克隆后必须修改的关键配置项,让你一步到位完成集群节点准备。 前置条件:关闭虚拟机

By Admin
Rock虚拟机安装教程

Rock虚拟机安装教程

本文基于 VMware Workstation Pro 17,从零开始记录 Rocky Linux 10.2 的完整安装过程,包括虚拟机创建、系统安装、SSH 远程连接及快照备份,适合新手一步步跟着操作。 一、前言 Rocky Linux 是一款基于 RHEL(Red Hat Enterprise Linux)源码构建的企业级 Linux 发行版,由 CentOS 创始人 Gregory Kurtzer 发起,旨在作为 CentOS 的替代方案,提供稳定、免费且长期支持的服务器操作系统。 本文以 Rocky Linux 10.2 为例,使用 VMware Workstation Pro

By Admin
IPVS 知识点总结

IPVS 知识点总结

一、IPVS 概述 IPVS(IP Virtual Server) 是运行在 Linux 内核中的四层负载均衡技术,是 LVS(Linux Virtual Server)的核心组件。 * 发展历程:早在 Linux 2.2 内核时以补丁形式出现,从 2.4.24 版本起正式并入 Linux 官方标准内核 * 工作层级:四层(传输层),根据 IP 加端口号分发请求 * 核心功能:负载均衡器根据指定调度算法和服务器负载,将客户端请求转发给后端真实服务器(RS) * 高可用支持:主备 IPVS 通过 UDP 组播同步连接状态,故障转移时备份节点可继承大多数连接状态 二、三种工作模式 1. NAT

By Admin