RockyLinux 9.5 部署 Kubernetes 集群(Containerd)
一、资源下载
1、阿里云官方镜像站
Rocky Linux 9.5 镜像地址:https://mirrors.aliyun.com/rockylinux/9.5/isos/x86_64/Rocky-9.5-x86_64-minimal.iso
2、Calico 3.28.4
(1)百度网盘下载链接:
Calico images:
链接: https://pan.baidu.com/s/137bmlXkxgDrlo4ot41ADJw 提取码: 9hvv
calico-v3.28.4.yaml
链接: https://pan.baidu.com/s/1Fn00SHrPpq34gy4mT6BY1A 提取码: nr55
3、dashboard 2.7.0
通过网盘分享的文件:recommended.yaml
链接: https://pan.baidu.com/s/1LhhFs4z9T9DyImmWYzvU0Q 提取码: h42p
二、环境准备
1、关闭防火墙
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 查看防火墙状态
firewall-cmd --state
2、禁用swap
# 临时关闭
swapoff -a
# 永久关闭,(编辑 /etc/fstab 文件,找到包含 swap 的行(如果有的话),并在行首添加 # 来注释掉该行)
sed -ri 's/.*swap.*/#&/' /etc/fstab
3、关闭 selinux
# 关闭 selinux
修改配置文件/etc/selinux/config
SELINUX=disabled
setenforce 0
# 本地部署建议直接关闭 selinux 或将其设置为宽容模式(SELINUX=permissive)
# 生产环境:如果需要更高的安全性,建议保持 SELinux 启用
4、开启 bridge 网桥过滤
# 创建一个配置文件 /etc/sysctl.d/k8s.conf,并通过 sysctl 配置内核参数
cat > /etc/sysctl.d/k8s.conf <
5、设置 hostname
# 配置集群之间本地解析,集群在初始化时需要能够解析主机名
# 不配置的话,初始化集群会有警告信息,但不影响最终执行结果
# master node1 node2 都需要执行
echo -e "192.168.31.106 master
192.168.31.107 node1
192.168.31.108 node2" | sudo tee -a /etc/hosts
6、集群规划
主机名 | IP | 角色 | 配置 |
---|---|---|---|
master | 192.168.31.106 | 管理节点 | 2CPU/4G内存/20G |
node1 | 192.168.31.107 | 工作节点 | 2CPU/4G内存/20G |
node2 | 192.168.31.108 | 工作节点 | 2CPU/4G内存/20G |
docker harbor | 192.168.31.109 | 镜像仓库 | 2CPU/4G内存/20G |
三、Containerd
1、安装 Containerd 软件包
# 添加阿里云 docker-ce 仓库
dnf config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 列出当前系统中所有可安装的 containerd 版本,并按照版本号从高到低进行排序,同时显示重复的版本。
dnf list containerd.io --showduplicates | sort -r
# 安装最新版本 containerd,也可以指定版本安装(dnf install -y containerd.io-1.6.20-3.1.el9.x86_64)
dnf install containerd.io -y
# 生成containerd配置文件
containerd config default | tee /etc/containerd/config.toml
# 启用 Cgroup 用于限制进程的资源使用量,如CPU、内存资源
sed -i 's#SystemdCgroup = false#SystemdCgroup = true#' /etc/containerd/config.toml
# 替换文件中 pause 镜像的下载地址为阿里云仓库
# 可先查看 /etc/containerd/config.toml 中 sandbox_image 中 pause 是否是 3.8 版本,不是的话自行修改
sed -i 's#sandbox_image = "registry.k8s.io/pause:3.8"#sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"#' /etc/containerd/config.toml
# 指定 contaienrd 接口文件地址,在k8s环境中,kubelet 通过 containerd.sock 文件与 containerd 进行通信
cat <
2、配置镜像加速器
# 配置 containerd 的镜像加速
# 创建文件夹
sudo mkdir -p /etc/containerd/certs.d/docker.io
# /etc/containerd/certs.d/docker.io 目录下添加 hosts.toml 文件,内容如下
server = "https://registry-1.docker.io"
[host."https://qa9ktbtj.mirror.aliyuncs.com"]
capabilities = ["pull", "resolve"]
[host."https://mirror.ccs.tencentyun.com"]
capabilities = ["pull", "resolve"]
[host."https://docker.m.daocloud.io"]
capabilities = ["pull", "resolve"]
[host."https://docker.mirrors.ustc.edu.cn"]
capabilities = ["pull", "resolve"]
[host."https://www.daocloud.io/mirror"]
capabilities = ["pull", "resolve"]
[host."https://registry-1.docker.io"]
capabilities = ["pull", "resolve"]
# 检查 containerd 主配置 /etc/containerd/config.toml
# 找到 config_path , 添加 /etc/containerd/certs.d
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
# 重启 containerd:
sudo systemctl restart containerd
四、Kubernetes
1、安装 kubeadm / kubectl / kubelet
# 配置 kubeadm 仓库,使用阿里云YUM源
cat > /etc/yum.repos.d/k8s.repo < /etc/sysconfig/kubelet <
2、集群初始化
# 在 master 节点生成初始化集群的配置文件
kubeadm config print init-defaults > kubeadm-config.yaml
# 打开配置文件修改以下内容
# 本机的IP地址
advertiseAddress: 192.168.31.106
# 本机名称
name: master
#集群镜像下载地址,修改为阿里云
imageRepository: registry.aliyuncs.com/google_containers
# 通过配置文件初始化集群,一个 master 节点
kubeadm init --config kubeadm-config.yaml
# 如果打算配置多个 master 节点,执行下面命令
kubeadm init --config kubeadm-config.yaml --upload-certs
# 根据集群初始化后的提示,master节点直接执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# node 节点加入集群的命令初始后会一并输出,放在 node 节点执行
kubeadm join 192.168.31.106:6443 --token abcdef.0123456789abcdef
--discovery-token-ca-cert-hash sha256:cc364e5e0d15d81a9ee2ca0cafd987a77ca8563366d19e16f67e53a46a52e156
# 根据提示将node节点加入集群,加入成功后在master节点验证
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady control-plane 3m31s v1.28.2
node1 NotReady 12s v1.28.2
node2 NotReady 89s v1.28.2
# 如果哪个节点出现问题,可以使用下列命令重置当前节点后再执行加入集群的命令
kubeadm reset
# 在 maste 节点执行,获取子节点加入集群令牌,将输出命令直接在 node 节点执行
kubeadm token create --print-join-command
3、部署集群网络 Calico
方式一:
# master 节点下载 Calico 文件
wget https://raw.githubusercontent.com/projectcalico/calico/v3.28.4/manifests/calico.yaml
# 创建 Calico 网络
kubectl apply -f calico.yaml
# 查看 Calico Pod 状态是否为 Running
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-9d57d8f49-xv6lh 1/1 Running 27 (31m ago) 129m
calico-node-66shx 1/1 Running 2 (5h40m ago) 25h
calico-node-gjwjc 1/1 Running 2 (5h40m ago) 25h
calico-node-xhnxw 1/1 Running 2 (5h35m ago) 25h
coredns-6554b8b87f-cw5tx 1/1 Running 0 129m
coredns-6554b8b87f-l5pkj 1/1 Running 0 129m
etcd-master 1/1 Running 2 (5h40m ago) 26h
kube-apiserver-master 1/1 Running 3 (30m ago) 26h
kube-controller-manager-master 1/1 Running 3 (31m ago) 26h
kube-proxy-q5flt 1/1 Running 2 (5h40m ago) 26h
kube-proxy-qcxhp 1/1 Running 2 (5h35m ago) 26h
kube-proxy-vw9dm 1/1 Running 2 (5h40m ago) 26h
kube-scheduler-master 1/1 Running 3 (31m ago) 26h
# 如果失败,可查看日志
kubectl describe pod calico-kube-controllers-9d57d8f49-xv6lh -n kube-system
方式二:
# 必选组件
# 1、calico-node.tar
# Calico 的核心组件之一,在每个节点(包括单节点集群)上运行。
# 它负责配置网络接口、路由和防火墙规则,确保 Pod 之间的网络连接和隔离。
# 2、calico-cni.tar
# 提供 Container Network Interface (CNI) 插件支持,用于为容器分配 IP 地址,并配置网络接口。
# 3、calico-kube-controllers.tar
# 监听 Kubernetes API Server 的事件,同步 Kubernetes 的网络策略到 Calico 的数据平面。
# 尽管在单节点集群中可能不使用复杂的网络策略,但该控制器有助于维护集群的网络状态一致性。
# 可选组件
# calico-typha.tar:Typha 主要用于大规模集群中减轻 kube-apiserver 的负担。在单节点集群中,通常不需要此组件。
# calico-flannel-migration-controller.tar, calico-pod2daemon.tar, calico-dikastes.tar, calico-key-cert-provisioner.tar:这些组件主要适用于特定需求或迁移场景,在标准单节点集群部署中通常是不必要的。
# 列出所有可用的命名空间
ctr namespaces list
# 下载上面提供的 Calico 3.28.4,解压缩
tar -xzvf calico-3.28.4.tar.gz
# 将必选的三个镜像导入到 containerd 中
# 只在 master 导入就可以
ctr -n k8s.io images import calico-cni.tar
ctr -n k8s.io images import calico-node.tar
ctr -n k8s.io images import calico-kube-controllers.tar
# 执行
kubectl apply -f calico.yaml
4、crictl 常用命令
# crictl 是 Kubernetes 容器运行时接口(CRI)的命令行工具,用于与支持 CRI 的容器运行时(如 containerd 或 CRI-O)交互。它可以在 Kubernetes 环境中调试和管理容器、镜像和 Pod
# crictl 全称可以理解为 Container Runtime Interface Control
# 1、镜像管理
# 拉取镜像
crictl pull
# 示例:
sudo crictl pull docker.io/nginx:latest
# 列出本地镜像
sudo crictl images
# 删除镜像
sudo crictl rmi
# 2、容器管理
# 列出正在运行的容器
sudo crictl ps
# 列出所有容器(包括已停止的)
sudo crictl ps -a
# 启动容器
sudo crictl start
# 停止容器
sudo crictl stop
# 删除容器
sudo crictl rm
# 查看容器日志
sudo crictl logs
# 实时查看日志
sudo crictl logs -f
5、kubernetes 证书续订
# 检查 API Server 证书有效期
openssl x509 -noout -dates -in /etc/kubernetes/pki/apiserver.crt
# 检查所有 kubeadm 证书
# ca 证书是 10 年,其它都是 1 年
[root@master ~]# kubeadm certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Apr 23, 2026 09:03 UTC 364d ca no
apiserver Apr 23, 2026 09:03 UTC 364d ca no
apiserver-etcd-client Apr 23, 2026 09:03 UTC 364d etcd-ca no
apiserver-kubelet-client Apr 23, 2026 09:03 UTC 364d ca no
controller-manager.conf Apr 23, 2026 09:03 UTC 364d ca no
etcd-healthcheck-client Apr 23, 2026 09:03 UTC 364d etcd-ca no
etcd-peer Apr 23, 2026 09:03 UTC 364d etcd-ca no
etcd-server Apr 23, 2026 09:03 UTC 364d etcd-ca no
front-proxy-client Apr 23, 2026 09:03 UTC 364d front-proxy-ca no
scheduler.conf Apr 23, 2026 09:03 UTC 364d ca no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Apr 21, 2035 04:54 UTC 9y no
etcd-ca Apr 21, 2035 04:54 UTC 9y no
front-proxy-ca Apr 21, 2035 04:54 UTC 9y no
# 续订所有证书
kubeadm certs renew all
# 重启控制平面组件(静态 Pod)
systemctl restart kubelet
五、部署 dashboard
# 下载 Dashboard v2.7.0 官方 YAML 文件
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
# image: kubernetesui/dashboard:v2.7.0 替换为
# image: registry.cn-hangzhou.aliyuncs.com/google_containers/dashboard:v2.7.0
# image: kubernetesui/metrics-scraper:v1.0.8 替换为
# image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-scraper:v1.0.8
# 部署到集群
kubectl apply -f recommended.yaml
# 验证 Pod 状态
kubectl get pods -n kubernetes-dashboard
# 正常输出应显示 kubernetes-dashboard Pod 状态为 Running:
[root@master ~]# kubectl get pods -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-7c85965fd4-2ww7m 1/1 Running 0 26s
kubernetes-dashboard-7d8bbf6bb6-czqrc 1/1 Running 0 26s
# kubectl edit 命令并不会直接编辑一个文件,
# 而是通过临时打开一个文本编辑器(比如 vi、nano 或系统默认的编辑器)来修改 Kubernetes 集群中存储的对象配置。
# 这些对象的数据实际上存储在 Kubernetes 的 etcd 数据库中,而不是以文件的形式存储在本地。
# 修改 SVC 访问模式,目的是为了从集群外部访问 Kubernetes Dashboard 服务
# 将 ClusterIP 改为 NodePort
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
# 查看 SVC 访问模式是否修改
# svc 是 Service 的简称,没修改之前 TYPE 全都是 ClusterIP
[root@master ~]# kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.108.39.200 8000/TCP 3m47s
kubernetes-dashboard NodePort 10.105.95.211 443:31950/TCP 3m47s
# 创建 dashboard-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard # 必须与 Dashboard 所在的命名空间一致
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin # 赋予集群管理员权限
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
# 应用配置
kubectl apply -f dashboard-admin.yaml
# 获取 Token 登录 Dashboard
kubectl -n kubernetes-dashboard create token admin-user
# 访问 dashboard,获取 Token 即可登录查看
https://192.168.31.106:31950
六、部署 Docker Harbor
点击查看部署教程
七、部署项目
1、获取 kubernetes 集群可用的镜像
# 在 docker harbor 服务器上拉取一个 nginx 镜像,然后上传到 docker harbor
# 登录到私有镜像仓库,输入账号密码
docker login i.dd.com:443
# 拉取 nginx:latest 镜像到本地
docker pull nginx:latest
# 为本地的 nginx:latest 镜像创建一个新的标签(tag),并将其标记为私有镜像仓库的路径
docker tag nginx:latest i.dd.com:443/nginx/nginx:1.0
# 将本地标记为 i.dd.com:443/nginx/nginx:1.0 的镜像推送到私有镜像仓库
docker push i.dd.com:443/nginx/nginx:1.0
2、存储访问私有 Docker Harbor 镜像仓库的认证信息
# master 节点创建docker registry secret
kubectl create secret docker-registry tt
--docker-server=i.dd.com:443
--docker-username=admin
--docker-password=Harbor12345
--docker-email=jcn@example.com
# 列出命名空间中的所有 Secret:
kubectl get secrets
# 如果你想要查看特定命名空间中的 Secret,请加上 -n 参数
kubectl get secrets -n
# 查看 secret 详细信息
kubectl get secret tt --output=yaml
3、配置 nginx-test.yaml
# 新建一个 nginx-test.yaml 文件,放到 master 节点根目录下,内容如下
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: i.dd.com:8443/nginx/mynginx:1.0
ports:
- containerPort: 80
imagePullPolicy: Always
env:
- name: ENVIRONMENT
value: "production"
imagePullSecrets:
- name: tt
---
# Service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30001
---
# Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # 根据 CPU 利用率自动扩展或缩减副本数
4、将 Harbor 中的测试项目 nginx 部署到集群中
# 将资源配置应用到 Kubernetes 集群中
kubectl apply -f nginx-test.yaml
# 查看 pod,也可以登陆 dashboard 查看
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5dfc977c65-7kmnf 1/1 Running 0 15s
nginx-deployment-5dfc977c65-7lmhp 1/1 Running 0 15s
# 浏览器访问 http://IP:30001 即可查看项目 nginx-test