基于 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.repo、Rocky-BaseOS.repo、Rocky-Extras.repo 等
  • 关键系统组件仓库:Rocky-PowerTools.repo(8 系列)、Rocky-CR.repo、Rocky-Debuginfo.repo、Rocky-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-proxy、coredns、pause 这三个镜像。

#我把所有镜像拉取到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

青藤云一面

青藤云一面

1、自我介绍 面试官您好,我叫XX,来自重庆。本科就读于重庆城市科技学院信息安全专业,是27届应届毕业生。今天应聘的是贵公司的技术支持工程师岗位。 我的技术方向主要围绕网络运维和云原生这一块。在校系统学过计算机网络、操作系统、数据库、云计算这些课程。技能上,我熟悉RedHat、Ubuntu这些主流Linux发行版,能独立完成服务器的系统部署、权限管理、日志分析和安全加固;数据库方面会 MySQL的基本的增删改查操作;自动化这块,我会用Shell写运维脚本,能用Ansible做批量运维,也了解CI/CD流水线的搭建。另外我也熟悉Docker的基本操作,也了解 Kubernetes 核心资源的基础应用与日常排查。 我做事有规划,责任心强,有较好的执行力,希望能够加入贵公司,把自己的专业技能转化为实际工作能力。 2、大学参加的社团活动中,让你意向深刻的 XXX 3、如果你和其他部门约定好在会议室一起规划活动时,对方迟迟没有来的话你会怎么解决 一、主动沟通。 先确认时间和地点有没有沟通清楚,然后主动联系对方,礼貌问一下是不是有什么事情耽搁了、大概多久能到,不干等、也不

By Admin
Linux 运维文件写入操作

Linux 运维文件写入操作

面向 Linux 运维/SRE 的文件写入操作参考手册。既讲每条命令怎么用,也讲它背后的机制(为什么这么行为),配真实输出示例与边界情况,最后给出常见陷阱速查表与标准动作模板。 目录 1. 总览:运维"写文件"的全景 2. Shell 重定向:机制与基础符号 3. 重定向顺序的坑:为什么 2>&1 > f 不行 4. 文件描述符与 exec:持久打开、交换、关闭 5. 防止误覆盖:noclobber 与 >| 6. Here 文档与 Here 字符串 7. tee:

By Admin