华为云信创:openEuler+K8s生产集群搭建从零到上线
文章摘要:本文记录了在 openEuler 22.03 上搭建生产级 K8s 集群的完整过程,包括 CRI-O 容器运行时配置、Calico 网络方案选型、持久化存储对接(华为云 EVS/NFS),以及集群初始化后的性能调优和安全加固。所有步骤均经过生产验证,可以直接作为基础设施搭建的标准操作手册使用。
关键词:openEuler、Kubernetes、CRI-O、Calico、容器编排、生产集群、信创、云原生
集群架构

部署工作流

第一步:基础环境配置
节点信息
| 主机名 | IP | 配置 | 角色 |
|---|---|---|---|
| master-01 | 192.168.1.10 | 8C/32GB | Control Plane |
| master-02 | 192.168.1.11 | 8C/32GB | Control Plane |
| master-03 | 192.168.1.12 | 8C/32GB | Control Plane |
| worker-01~05 | 192.168.1.20~24 | 32C/64GB | Worker |
所有节点执行
# 1. 关闭防火墙(K8s 自己管理网络规则)
systemctl stop firewalld && systemctl disable firewalld
# 2. 关闭 SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 3. 关闭 SWAP
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/' /etc/fstab
# 4. 加载内核模块
cat >> /etc/modules-load.d/k8s.conf << 'EOF'
br_netfilter
overlay
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4
EOF
# 5. 配置内核参数
cat >> /etc/sysctl.d/k8s.conf << 'EOF'
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
net.ipv4.conf.all.forwarding = 1
vm.swappiness = 0
EOF
sysctl --system
# 6. 配置 hosts
cat >> /etc/hosts << 'EOF'
192.168.1.10 master-01
192.168.1.11 master-02
192.168.1.12 master-03
192.168.1.20 worker-01
192.168.1.21 worker-02
192.168.1.22 worker-03
192.168.1.23 worker-04
192.168.1.24 worker-05
EOF
第二步:安装 CRI-O
不用 Docker,用 CRI-O 作为容器运行时,它比 Docker 更轻量、跟 K8s 集成更好。
# 1. 安装 CRI-O(openEuler 官方仓库包含)
yum install -y cri-o cri-tools
# 2. 配置 CRI-O 镜像仓库(使用华为云镜像,国内下载更快)
cat > /etc/crio/crio.conf.d/01-registries.conf << 'EOF'
[crio.image]
registries = ["registry.huaweicloud.com", "docker.io"]
[crio.image.insecure_registries]
registries = ["registry.company.com:5000"]
EOF
# 3. 启动 CRI-O
systemctl daemon-reload
systemctl enable crio --now
# 4. 验证
crictl version
# Version: 0.1.0
# RuntimeName: cri-o
# RuntimeVersion: 1.27.1
第三步:安装 Kubernetes
# 1. 添加 K8s 仓库
cat > /etc/yum.repos.d/kubernetes.repo << 'EOF'
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.huaweicloud.com/kubernetes/yum/repos/kubernetes-el7-aarch64
enabled=1
gpgcheck=0
EOF
# 2. 安装(指定版本,避免自动升级)
yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2
systemctl enable kubelet --now
# 3. 在 master-01 上初始化集群
kubeadm init \
--control-plane-endpoint "192.168.1.100:6443" \
--apiserver-advertise-address 192.168.1.10 \
--pod-network-cidr 10.244.0.0/16 \
--service-cidr 10.96.0.0/12 \
--kubernetes-version 1.28.2 \
--cri-socket /var/run/crio/crio.sock \
--upload-certs
# 4. 配置 kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 5. 加入其他 master 节点(在 master-02/03 上执行)
kubeadm join 192.168.1.100:6443 \
--token ${TOKEN} \
--discovery-token-ca-cert-hash ${HASH} \
--control-plane \
--certificate-key ${CERT_KEY}
# 6. 加入 worker 节点(在 worker-01~05 上执行)
kubeadm join 192.168.1.100:6443 \
--token ${TOKEN} \
--discovery-token-ca-cert-hash ${HASH}
# 7. 验证集群
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# master-01 Ready control-plane 10m v1.28.2
# master-02 Ready control-plane 8m v1.28.2
# master-03 Ready control-plane 8m v1.28.2
# worker-01 Ready worker 5m v1.28.2
# worker-02 Ready worker 5m v1.28.2
# worker-03 Ready worker 4m v1.28.2
# worker-04 Ready worker 4m v1.28.2
# worker-05 Ready worker 3m v1.28.2
第四步:Calico 网络
# 1. 安装 Calico
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27/manifests/calico.yaml
# 2. 等待所有 calico-node pod 运行
kubectl -n kube-system get pods | grep calico
# calico-node-xxxxx 1/1 Running 0 2m
# 3. 验证 CoreDNS 是否正常
kubectl -n kube-system get pods | grep coredns
# coredns-xxxxx 1/1 Running 0 3m
第五步:持久化存储
# 1. 安装华为云 CSI 驱动(对接 EVS 块存储)
kubectl apply -f https://raw.githubusercontent.com/huaweicloud/huaweicloud-csi-driver/master/deploy/csi-controller.yaml
kubectl apply -f https://raw.githubusercontent.com/huaweicloud/huaweicloud-csi-driver/master/deploy/csi-node.yaml
# 2. 创建 StorageClass
cat > sc.yaml << 'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: huawei-evsslow
parameters:
type: SAS # SAS / SSD
availability-zone: cn-south-1a
provisioner: evs.csi.huaweicloud.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
EOF
kubectl apply -f sc.yaml
1. CRI-O 的 pod 和 sandbox 镜像拉取失败
现象:kubeadm init 时卡在 Waiting for control plane to become ready,查看日志发现 pause 镜像拉不下来。
原因:openEuler 上 CRI-O 默认的 pause 镜像地址是 k8s.gcr.io/pause:3.9,但 gcr.io 在国内无法访问。
解决:
# 配置 CRI-O 使用国内镜像
cat > /etc/crio/crio.conf.d/10-pause.conf << 'EOF'
[crio.image]
pause_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9"
EOF
systemctl restart crio
2. kubeadm init 卡在 control plane 启动
现象:执行 kubeadm init 后,输出一直卡在:
[control-plane] Creating static Pod manifest for "kube-apiserver"
[wait-control-plane] Waiting for the kubelet to boot the control plane as static Pods
等了 10 分钟还没动静。
排查:
# 查看 kubelet 日志
journalctl -u kubelet -f --no-tail
# 发现关键错误:找不到 kubelet 配置文件
# open /etc/kubernetes/kubelet.conf: no such file or directory"
# 还有 CRI 连接超时错误
# failed to connect to CRI: context deadline exceeded"
原因:两个问题叠加:
- CRI-O 没完全启动就执行了
kubeadm init。crio.service虽然在 running 状态,但 socket 文件/var/run/crio/crio.sock还没创建好。 - openEuler 上
kubelet启动比 CRI-O 快,kubelet 在 CRI-O socket 就绪前就开始连接了。
解决:
# 1. 确认 CRI-O socket 已就绪
ls -la /var/run/crio/crio.sock
# srw-rw---- 1 root root 0 ... /var/run/crio/crio.sock
# 2. 重启 kubelet,让它在 CRI-O 就绪后再启动
systemctl restart kubelet
# 3. 重新执行 kubeadm init(先 reset 清理)
kubeadm reset -f
rm -rf /etc/kubernetes/*
systemctl restart crio
kubeadm init \
--control-plane-endpoint "192.168.1.100:6443" \
--apiserver-advertise-address 192.168.1.10 \
--pod-network-cidr 10.244.0.0/16 \
--service-cidr 10.96.0.0/12 \
--kubernetes-version 1.28.2 \
--cri-socket /var/run/crio/crio.sock \
--upload-certs
教训:初始化前用 crictl info 确认 CRI-O 完全就绪,而不是只看 systemd 状态。
3. CRI-O 版本与 K8s 版本不匹配
现象:kubeadm init 能执行,但初始化完成后 kubectl get nodes 看到 master 节点一直 NotReady,kubelet 日志报:
"Failed to run kubelet" err="failed to run Kubelet: misconfiguration: kubelet cgroup driver: \"systemd\" is different from docker cgroup driver: \"cgroupfs\""
排查:
# 查看 CRI-O 的 cgroup 驱动配置
crio config | grep cgroup_manager
# cgroup_manager = "cgroupfs"
# 查看 kubelet 的 cgroup 驱动
ps aux | grep kubelet | grep cgroup-driver
# 没有指定,默认用 systemd
原因:openEuler 22.03 上通过 yum 安装的 CRI-O 1.27.x 默认使用 cgroupfs 驱动,而 kubelet 1.28 默认使用 systemd 驱动。两边的 cgroup 驱动不一致,导致 kubelet 无法管理容器资源。
解决:
# 1. 修改 CRI-O 使用 systemd cgroup 驱动
cat > /etc/crio/crio.conf.d/10-cgroup.conf << 'EOF'
[crio.runtime]
cgroup_manager = "systemd"
conmon_cgroup = "pod"
EOF
# 2. 重启 CRI-O
systemctl restart crio
# 3. 确认配置生效
crio config | grep cgroup_manager
# cgroup_manager = "systemd"
# 4. 重置并重新初始化集群
kubeadm reset -f
rm -rf /etc/kubernetes/*
systemctl restart kubelet
kubeadm init \
--control-plane-endpoint "192.168.1.100:6443" \
--apiserver-advertise-address 192.168.1.10 \
--pod-network-cidr 10.244.0.0/16 \
--service-cidr 10.96.0.0/12 \
--kubernetes-version 1.28.2 \
--cri-socket /var/run/crio/crio.sock \
--upload-certs
教训:装完 CRI-O 之后第一时间检查 cgroup 驱动配置,跟 kubelet 保持一致。推荐全部用 systemd。
集群调优
# 1. 调整 kubelet 参数(提升性能)
cat > /etc/sysconfig/kubelet << 'EOF'
KUBELET_EXTRA_ARGS="--max-pods=110 --kube-reserved=cpu=1,memory=2Gi --system-reserved=cpu=1,memory=2Gi"
EOF
# 2. 调整 Pod 数限制
kubectl -n kube-system edit configmap kubelet-config
# 3. 验证集群状态
kubectl cluster-info
kubectl get componentstatuses
kubectl -n kube-system get pods -o wide
运维检查清单
# 日常检查命令
kubectl get nodes # 节点状态
kubectl get pods -A # 所有 pod 状态
kubectl top nodes # 节点资源使用
kubectl top pods -A # Pod 资源使用
kubectl describe node worker-01 # 节点详细信息
journalctl -u kubelet -f # kubelet 日志
crictl ps # CRI-O 容器列表
常见问题
Q1:为什么不直接用 Docker,而用 CRI-O?
Docker 在 K8s 1.24+ 已经被弃用。CRI-O 专为 K8s 设计,更轻量(不需要 dockerd 守护进程),内存占用少 60%。
Q2:3 个 Master 节点够不够?我的集群小能不能只 1 个?
生产环境建议 3 个 Master,满足 etcd 多数派要求。如果集群规模很小(< 10 个节点),1 个 Master 也可以(就是万一挂了整个集群不可用)。
Q3:网络方案一定要选 Calico 吗?
Calico 是首选(性能好、功能全)。如果对网络隔离有特殊要求(比如金融行业的多租户网络策略),也可以选 Cilium(基于 eBPF,功能更丰富但学习曲线更陡)。
总结
在 openEuler 上搭建 K8s 集群跟 CentOS 上差别不大,主要注意三点:
- CRI-O 的 pause 镜像地址要改成国内可访问的
- ARM64 版本的镜像(kubeadm/kubelet/kubectl 和 Calico 都要用 ARM64 版)
- 存储对接时确认 CSI 驱动支持 ARM64
集群搭建完成后,下一篇进入华为云方案篇:CCE + 鲲鹏节点池,把应用容器化部署到云上。
你们生产环境用的什么 K8s 网络方案?Calico 还是 Cilium?
关键词:openEuler、Kubernetes、CRI-O、Calico、容器编排、生产集群、kubeadm、信创
- 点赞
- 收藏
- 关注作者
评论(0)