银河麒麟V10鲲鹏ARM64服务器搭建Kubernetes集群环境

2026-08-07 12:24:00
丁国栋
原创 9
摘要:本文以腾讯云"标准型 SK2"鲲鹏实例(银河麒麟 V10 Arm64 系统)为例,完整记录使用 kubeadm 搭建双节点 Kubernetes 1.26.9 集群的全过程,涵盖 cgroup v1 切换、containerd 安装与镜像源配置、flannel 网络部署及 CNI 配置冲突的踩坑排查、NFS 动态存储、本地镜像导入、traefik 网关与 CLB 接入等内容,适合需要在国产化 ARM 平台上从零搭建 Kubernetes 环境的读者参考。
本文以腾讯云"标准型 SK2"鲲鹏实例(银河麒麟 V10 Arm64 系统)为例,完整记录使用 kubeadm 搭建双节点 Kubernetes 1.26.9 集群的全过程,涵盖 cgroup v1 切换、containerd 安装与镜像源配置、flannel 网络部署及 CNI 配置冲突的踩坑排查、NFS 动态存储、本地镜像导入、traefik 网关与 CLB 接入等内容,适合需要在国产化 ARM 平台上从零搭建 Kubernetes 环境的读者参考。

环境说明

鲲鹏实例与普通 ARM 实例的区别

腾讯云默认不提供鲲鹏架构的服务器,需要先提交申请。虽然从 CPU 信息上看不出明显差别,但两类实例支持的指令特性存在差异。

标准型 SK1 的 CPU 信息(以 Debian 系统的双核实例为例):

root@VM-1-8-debian:~# cat /proc/cpuinfo 
processor       : 0
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0xd01
CPU revision    : 0
processor       : 1
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0xd01
CPU revision    : 0
root@VM-1-8-debian:~# uname -a
Linux VM-1-8-debian 5.10.0-33-arm64 #1 SMP Debian 5.10.226-1 (2024-10-03) aarch64 GNU/Linux
root@VM-1-8-debian:~# 
root@VM-1-8-debian:~# lscpu
Architecture:                         aarch64
CPU op-mode(s):                       64-bit
Byte Order:                           Little Endian
CPU(s):                               2
On-line CPU(s) list:                  0,1
Thread(s) per core:                   1
Core(s) per socket:                   2
Socket(s):                            1
NUMA node(s):                         1
Vendor ID:                            HiSilicon
Model:                                0
Model name:                           Kunpeng-920
Stepping:                             0x1
BogoMIPS:                             200.00
L1d cache:                            128 KiB
L1i cache:                            128 KiB
L2 cache:                             1 MiB
L3 cache:                             32 MiB
NUMA node0 CPU(s):                    0,1
Vulnerability Gather data sampling:   Not affected
Vulnerability Itlb multihit:          Not affected
Vulnerability L1tf:                   Not affected
Vulnerability Mds:                    Not affected
Vulnerability Meltdown:               Not affected
Vulnerability Mmio stale data:        Not affected
Vulnerability Reg file data sampling: Not affected
Vulnerability Retbleed:               Not affected
Vulnerability Spec rstack overflow:   Not affected
Vulnerability Spec store bypass:      Not affected
Vulnerability Spectre v1:             Mitigation; __user pointer sanitization
Vulnerability Spectre v2:             Not affected
Vulnerability Srbds:                  Not affected
Vulnerability Tsx async abort:        Not affected
Flags:                                fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimd
                                      dp asimdfhm
root@VM-1-8-debian:~# 
root@VM-1-8-debian:~# dmidecode -t processor | grep -E "Manufacturer|Version|Family"
        Family: Other
        Manufacturer: QEMU
        Version: virt-rhel8.2.0
root@VM-1-8-debian:~# 

同样是标准型 SK1,银河麒麟 V10 系统上的输出如下:

➜  ~ cat /proc/cpuinfo
processor       : 0
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0xd01
CPU revision    : 0
processor       : 1
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0xd01
CPU revision    : 0
processor       : 2
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0xd01
CPU revision    : 0
processor       : 3
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0xd01
CPU revision    : 0
➜  ~ uname -a
Linux VM-1-10-kylin 4.19.90-89.11.v2401.ky10.aarch64 #1 SMP Thu Apr 25 18:20:10 CST 2024 aarch64 aarch64 aarch64 GNU/Linux
➜  ~ 
➜  ~ lscpu
Architecture:                       aarch64
CPU op-mode(s):                     64-bit
Byte Order:                         Little Endian
CPU(s):                             4
On-line CPU(s) list:                0-3
Thread(s) per core:                 1
Core(s) per socket:                 4
Socket(s):                          1
NUMA node(s):                       1
Vendor ID:                          HiSilicon
BIOS Vendor ID:                     QEMU
Model:                              0
Model name:                         Kunpeng-920
BIOS Model name:                    virt-rhel8.2.0
Stepping:                           0x1
BogoMIPS:                           200.00
L1d cache:                          256 KiB
L1i cache:                          256 KiB
L2 cache:                           2 MiB
L3 cache:                           32 MiB
NUMA node0 CPU(s):                  0-3
Vulnerability Gather data sampling: Not affected
Vulnerability Itlb multihit:        Not affected
Vulnerability L1tf:                 Not affected
Vulnerability Mds:                  Not affected
Vulnerability Meltdown:             Not affected
Vulnerability Mmio stale data:      Not affected
Vulnerability Retbleed:             Not affected
Vulnerability Spec store bypass:    Not affected
Vulnerability Spectre v1:           Mitigation; __user pointer sanitization
Vulnerability Spectre v2:           Not affected
Vulnerability Srbds:                Not affected
Vulnerability Tsx async abort:      Not affected
Flags:                              fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp
                                     asimdfhm
➜  ~ 
➜  ~ dmidecode -t processor | grep -E "Manufacturer|Version|Family"
        Family: Other
        Manufacturer: QEMU
        Version: virt-rhel8.2.0
➜  ~ 

而鲲鹏服务器的实例类型为"标准型 SK2",CPU 信息如下:

[root@kunpeng1 ~]# cat /proc/cpuinfo 
processor       : 0
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd02
CPU revision    : 0
processor       : 1
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd02
CPU revision    : 0
processor       : 2
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd02
CPU revision    : 0
processor       : 3
model name      : ARMv8 Processor rev 0 (v8l)
BogoMIPS        : 200.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs
CPU implementer : 0x48
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd02
CPU revision    : 0
[root@kunpeng1 ~]# uname -a
Linux kunpeng1 4.19.90-89.11.v2401.ky10.aarch64 #1 SMP Thu Apr 25 18:20:10 CST 2024 aarch64 aarch64 aarch64 GNU/Linux
[root@kunpeng1 ~]# 
[root@kunpeng1 ~]# lscpu
Architecture:                       aarch64
CPU op-mode(s):                     64-bit
Byte Order:                         Little Endian
CPU(s):                             4
On-line CPU(s) list:                0-3
Thread(s) per core:                 2
Core(s) per socket:                 2
Socket(s):                          1
NUMA node(s):                       1
Vendor ID:                          HiSilicon
BIOS Vendor ID:                     QEMU
Model:                              0
Model name:                         ARMv8 Processor rev 0 (v8l)
BIOS Model name:                    virt-rhel8.2.0
Stepping:                           0x0
BogoMIPS:                           200.00
L1d cache:                          128 KiB
L1i cache:                          128 KiB
L2 cache:                           2.5 MiB
L3 cache:                           70 MiB
NUMA node0 CPU(s):                  0-3
Vulnerability Gather data sampling: Not affected
Vulnerability Itlb multihit:        Not affected
Vulnerability L1tf:                 Not affected
Vulnerability Mds:                  Not affected
Vulnerability Meltdown:             Not affected
Vulnerability Mmio stale data:      Not affected
Vulnerability Retbleed:             Not affected
Vulnerability Spec store bypass:    Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:           Mitigation; __user pointer sanitization
Vulnerability Spectre v2:           Not affected
Vulnerability Srbds:                Not affected
Vulnerability Tsx async abort:      Not affected
Flags:                              fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop s
                                    ha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs
[root@kunpeng1 ~]# dmidecode -t processor | grep -E "Manufacturer|Version|Family"
        Family: Other
        Manufacturer: QEMU
        Version: virt-rhel8.2.0
[root@kunpeng1 ~]# 

对比可以看出:SK1 实例的 CPU part 为 0xd01,指令特性中不包含 svesm3sm4sha3 等能力;而 SK2 实例的 CPU part 为 0xd02,是海思鲲鹏 920 处理器,额外支持 svesm3/sm4(国产商用密码算法)、sha3sha512lrcpcdit 等指令。由于腾讯云虚拟化环境(QEMU)的原因,lscpu 显示的型号名称可能具有迷惑性(SK1 的 lscpu 同样显示 Kunpeng-920),判断是否具备完整鲲鹏能力应以 /proc/cpuinfo 中的 CPU part 与 Features 为准。

本次环境

本次搭建的是一套使用鲲鹏服务器与银河麒麟(Kylinos 10.0 Arm64)的 Kubernetes 环境,先使用两个节点搭建,节点配置相同,均为标准型 SK2.LARGE8(4 核 8G)。操作系统信息如下:

[root@kunpeng1 ~]# cat /etc/os-release 
NAME="Kylin Linux Advanced Server"
VERSION="V10 (Halberd)"
ID="kylin"
VERSION_ID="V10"
PRETTY_NAME="Kylin Linux Advanced Server V10 (Halberd)"
ANSI_COLOR="0;31"
[root@kunpeng1 ~]# 

一、基础环境配置

1.1 设置主机名与 hosts

两个节点分别设置主机名(本文为 kunpeng1、kunpeng2):

hostnamectl set-hostname kunpeng1
hostnamectl set-hostname kunpeng2

在节点的 /etc/hosts 中追加主机名解析:

cat >>/etc/hosts<<'eof'
10.14.0.5  kunpeng1
10.14.0.12 kunpeng2
eof

1.2 配置 SSH 互信登录

# 在 kunpeng1 上生成密钥并分发到其他节点(本例为 kunpeng2)
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
ssh-copy-id -i ~/.ssh/id_ed25519.pub kunpeng2
# 验证互信
ssh kunpeng2 hostname

二、系统级前置配置

2.1 切换 cgroup v1

本环境 kubelet 使用 systemd cgroup 驱动,依赖 cgroup v1,必须确保系统有 cpuset 挂载点。由于麒麟 V10 服务器版本限制,需要关闭 cgroup v2:

grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"
reboot
stat -fc %T /sys/fs/cgroup/ # 应当输出 tmpfs
mount | grep cpuset # 应当输出 cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)

2.2 关闭 swap 分区

swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
systemctl mask dev-vda3.swap # 不可逆操作,vda3 按实际设备调整
wipefs -a -t swap /dev/vda3 # vda3 按实际设备调整
blkid /dev/vda3 # vda3 按实际设备调整

2.3 加载内核模块

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

2.4 配置内核参数与 IPv4 转发

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

麒麟 V10 默认禁用 IPv4 路由,需要修改配置文件:

sed -i 's@net.ipv4.ip_forward=0@net.ipv4.ip_forward=1@g' /etc/sysctl.conf
# 立即加载
sysctl --system
# 验证
cat /proc/sys/net/ipv4/ip_forward

2.5 关闭 SELinux

setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

三、安装并配置 containerd

下载 arm64 版本的 cri-containerd 发布包并解压到根目录:

wget https://github.com/containerd/containerd/releases/download/v1.7.2/cri-containerd-cni-1.7.2-linux-arm64.tar.gz
tar axf cri-containerd-cni-1.7.2-linux-arm64.tar.gz -C /

生成默认配置,然后调整两处:

mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

第一处是 cgroup 驱动。SystemdCgroup 选项决定 containerd 使用 systemd 还是 cgroupfs 作为 cgroup 驱动,部署时需要与 kubelet 的 cgroup 驱动保持一致,请结合实际环境核对后修改:

# 将 SystemdCgroup = true 改为 false。该选项只决定 containerd 用 systemd 还是 cgroupfs 作为 cgroup 驱动
sed -i 's/SystemdCgroup = true/SystemdCgroup = false/g' /etc/containerd/config.toml

第二处是 sandbox(pause)镜像,改为阿里云镜像仓库,否则 kubeadm init 时拉取不到:

# pause 镜像改为阿里云,否则 init 时拉不到
sed -i 's#sandbox_image = "registry.k8s.io/pause:3.8"#sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9"#g' /etc/containerd/config.toml

启动 containerd 并设置开机自启:

systemctl daemon-reload
systemctl restart containerd
systemctl enable containerd

四、安装 kubeadm、kubelet、kubectl

配置阿里云 Kubernetes yum 源(aarch64 架构)并安装 1.26.9 版本:

cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-aarch64/
enabled=1
gpgcheck=0
EOF
yum install -y kubelet-1.26.9 kubeadm-1.26.9 kubectl-1.26.9
systemctl enable kubelet

五、初始化集群

5.1 预拉取镜像

kubeadm config images pull \
  --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
  --kubernetes-version v1.26.9

5.2 初始化控制平面

注意:--apiserver-advertise-address=10.14.0.5 需要改为第一个节点的内网 IP 地址

kubeadm init \
  --kubernetes-version=v1.26.9 \
  --apiserver-advertise-address=10.14.0.5 \
  --pod-network-cidr=10.244.0.0/16 \
  --service-cidr=10.96.0.0/12 \
  --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
  --v=5

5.3 配置 kubectl 配置文件

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

六、部署 flannel 网络插件

ghcr.io 在国内访问不便,先从 m.daocloud.io 拉取 flannel 及其 CNI 插件镜像到 k8s.io 命名空间(kubelet 默认从这个命名空间查找镜像),再打回原始 tag,让 kubelet 认为本地已有 ghcr.io 原始镜像:

# 进入 k8s.io 命名空间拉取(kubelet 默认从这个命名空间找镜像)
ctr -n k8s.io images pull m.daocloud.io/ghcr.io/flannel-io/flannel:v0.28.8
ctr -n k8s.io images pull m.daocloud.io/ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel2
# 打回原始 tag,让 kubelet 认为这是本地已有的 ghcr.io 原镜像
ctr -n k8s.io images tag m.daocloud.io/ghcr.io/flannel-io/flannel:v0.28.8 \
  ghcr.io/flannel-io/flannel:v0.28.8
ctr -n k8s.io images tag m.daocloud.io/ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel2 \
  ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel2
ctr -n k8s.io images list | grep flannel-io
wget https://github.com/flannel-io/flannel/releases/download/v0.28.8/kube-flannel.yml
kubectl apply -f kube-flannel.yml

6.1 踩坑记录:CNI 配置文件冲突

部署过程中踩了一个坑:containerd 的 CNI 配置文件和 flannel 的 CNI 配置文件冲突,导致 flannel 插件无法正常工作,表现为 NodePort 类型的 Service 无法访问、DNS 解析失败。

原因在于:节点上同时存在多个容器运行时(containerd、podman、nerdctl),它们的 CNI 配置文件都堆放在 /etc/cni/net.d/ 目录下。containerd 自带的 10-containerd-net.conflist(网段 10.88.0.0/16)按文件名排序抢在 flannel 的 10-flannel.conflist(网段 10.244.0.0/16)前面,导致所有节点 Pod 使用了同一网段、flannel 被架空,最终跨节点不通、CoreDNS 挂掉、DNS 解析全部失败。

解决方案是部署前确保 CNI 目录"干净":

# 只保留一个 CRI(containerd),卸载/停用 podman、nerdctl
# 全新安装时,/etc/cni/net.d/ 应为空(或不存在)
rm -rf /etc/cni/net.d/*
# 尤其注意:containerd 的 rpm/deb 包会自带 10-containerd-net.conflist,必须删掉
# kubeadm 初始化时指定 Pod 网段,必须与 flannel 的 Network 完全一致
kubeadm init --pod-network-cidr=10.244.0.0/16 ...
# 再部署 flannel(DaemonSet),确认其 configmap 中 net-conf.json 的 Network 也是 10.244.0.0/16
kubectl apply -f kube-flannel.yml

部署完成后进行验证:

# 各节点 PodCIDR 互不重叠(应为 10.244.0.0/24、10.244.1.0/24...)
kubectl get nodes -o custom-columns='NAME:.metadata.name,PODCIDR:.spec.podCIDR'
# 每个节点 cni0 的 IP 应为 10.244.x.1/24,且各节点 x 不同
kubectl get nodes -o name | cut -d/ -f2 | xargs -I{} ssh {} 'echo ==={}===; ip -4 addr show cni0 | grep inet'
# 每个节点 /etc/cni/net.d/ 里只有 flannel 配置(绝不能有 10-containerd-net.conflist)
kubectl get nodes -o name | cut -d/ -f2 | xargs -I{} ssh {} 'echo ==={}===; ls /etc/cni/net.d/'
# 跨节点 Pod 连通性(关键!)
kubectl run ping-a --image=busybox --restart=Never -- sleep 3600
kubectl run ping-b --image=busybox --restart=Never -- sleep 3600
kubectl exec ping-a -- ping -c2 $(kubectl get pod ping-b -o jsonpath='{.status.podIP}')
# DNS 解析验证
kubectl run dns-test --image=busybox --restart=Never -- nslookup kubernetes.default.svc.cluster.local
kubectl logs dns-test

6.2 已踩坑后的补救处理

如果一开始没有按上述方式配置,可以按以下步骤补救。需要注意:以下步骤必须在每个节点上执行,所以尽量在一开始就配置正确。

第 1 步:确认残留 IP

ip addr show cni0 # 如果看到 inet 10.88.0.1/16,就说明配置存在问题,需要处理

第 2 步:删除 cni0(若 busy 先删 veth)

for v in $(ip -o link show | awk -F': ' '{print $2}' | grep '^veth'); do ip link delete "$v" 2>/dev/null; done
ip link delete cni0
ip link show cni0 2>&1   # 无输出 = 删除成功

第 3 步:重启运行时,让 flannel 用 10.244.1.1/24 重建

systemctl restart containerd kubelet

第 4 步:回 kunpeng1 验证整体状态

kubectl get pods -A -o wide | grep -v "10\.88"
# 最终验证 DNS + Redis
kubectl apply -f /tmp/pod-debug.yaml   # 若 redis-debug 已被删则重建
kubectl exec -it -n zentao redis-debug -- redis-cli -h zentao-redis.zentao.svc -p 6379 ping

七、加入第二个节点

在 kunpeng2 上先确认控制平面健康,并预拉取镜像:

curl -sSk https://10.14.0.5:6443/healthz
kubeadm config images pull \
  --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
  --kubernetes-version v1.26.9

使用 kubeadm init 输出的 token 与证书哈希将节点加入集群:

kubeadm join 10.14.0.5:6443 --token mypn6g.xi7txd4s6zrbc9rg \
        --discovery-token-ca-cert-hash sha256:b1288efa2a6e4852c535130a467655858f0b8b8975422718af7e7932adcc53ab

在主节点上验证节点状态:

kubectl get nodes

若希望 master 也承载业务,需执行 kubectl taint nodes --all node-role.kubernetes.io/control-plane- 去除污点

八、安装 Helm

helm 用于安装 nfs-subdir-external-provisioner Chart 和 traefik Chart,后续也可以安装其他 Chart:

wget https://get.helm.sh/helm-v4.2.3-linux-arm64.tar.gz
tar xf helm-v4.2.3-linux-arm64.tar.gz
mv linux-arm64/helm /usr/local/bin/
chmod +x /usr/local/bin/helm

九、配置 NFS 存储与默认 StorageClass

9.1 搭建 NFS 服务器(kunpeng1)

yum install -y nfs-utils rpcbind
mkdir -p /data/k8s-nfs
chmod 755 /data/k8s-nfs
chown nfsnobody:nfsnobody /data/k8s-nfs 2>/dev/null || chown nobody:nobody /data/k8s-nfs
cat >> /etc/exports <<EOF
/data/k8s-nfs 10.14.0.0/24(rw,sync,no_subtree_check,no_root_squash)
EOF
systemctl enable --now rpcbind
systemctl enable --now nfs-server
# 重新加载导出配置
exportfs -arv
showmount -e localhost # 应该看到 /data/k8s-nfs 10.14.0.0/24

9.2 客户端验证(kunpeng2)

yum install -y nfs-utils
showmount -e 10.14.0.5

9.3 安装 nfs-subdir-external-provisioner

官方 Chart 仓库托管在 GitHub 上,国内访问不便:

helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
  --set nfs.server=10.14.0.5 \
  --set nfs.path=/data/k8s-nfs \
  --set storageClass.name=nfs-sc

为节省时间,这里使用腾讯云国内 Chart 仓库中准备好的 nfs-subdir-external-provisioner Chart 替代:

helm repo add qucheng-stable https://qucheng.tencentcloudcr.com/chartrepo/stable
helm install nfs-provisioner qucheng-stable/nfs-subdir-external-provisioner \
  --set nfs.server=10.14.0.5 \
  --set nfs.path=/data/k8s-nfs \
  --set storageClass.name=nfs-sc

注意:helm install 没有指定命名空间会默认安装到 default 命名空间

确认 nfs-sc 是否创建成功:

kubectl get sc

十、导入本地镜像到 k8s.io 命名空间

有时需要将本地镜像导入 k8s.io 命名空间,以便在 Kubernetes 中使用。下面这个流程虽然繁琐,但是可行的。

先尝试用 ctr 直接导入,但导入后看不到期望的 tag,因此改用 nerdctl 再导入:

tar -tf /data/tidbx-71853-arm.tar
ctr -n k8s.io --debug images import /data/tidbx-71853-arm.tar # 导入后看不到预期的 tag,改用 nerdctl 再导入

安装 nerdctl 并用其导入镜像:

# https://github.com/containerd/nerdctl/releases/download/v2.3.5/nerdctl-full-2.3.5-linux-arm64.tar.gz
wget https://github.com/containerd/nerdctl/releases/download/v2.3.5/nerdctl-2.3.5-linux-arm64.tar.gz
tar xf nerdctl-2.3.5-linux-arm64.tar.gz
mv nerdctl /usr/local/bin/
nerdctl -n k8s.io images
nerdctl -n k8s.io load -i /data/tidbx-71853-arm.tar
ctr -n k8s.io images tag import@sha256:a84d5734cc745c2c3bc77daddebf5d399b2c558f7081e37695f52853e047d256 tidbx:v7.1.8-5.3
ctr -n k8s.io images tag import@sha256:a84d5734cc745c2c3bc77daddebf5d399b2c558f7081e37695f52853e047d256 hub.zentao.net/app/tidbx:v7.1.8-5.3
ctr -n k8s.io images ls|grep tidbx
nerdctl login hub.zentao.net
nerdctl -n k8s.io push hub.zentao.net/app/tidbx:v7.1.8-5.3
nerdctl run --rm -it --entrypoint=bash hub.zentao.net/app/tidbx:v7.1.8-5.3
nerdctl pull hub.zentao.net/app/zentao:max8.4.k8s-php7
nerdctl save hub.zentao.net/app/zentao:max8.4.k8s-php7 -o max8.4.k8s-php7.3bc186ddb8b7.tar

十一、安装 traefik 网关

traefik 用于将集群内服务路由到外部,安装方法参见官方文档:https://doc.traefik.io/traefik/getting-started/kubernetes/

11.1 部署 Gateway API 的 CRD

# kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
wget -O /tmp/standard-install.yaml https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
kubectl apply -f /tmp/standard-install.yaml

11.2 使用 Helm 安装 traefik

helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik --wait \
  --set image.registry=hub.zentao.net \
  --set image.repository=app/traefik \
  --set image.tag=v3.7.9 \
  --set image.pullPolicy=IfNotPresent \
  --set service.type=NodePort \
  --set ingressRoute.dashboard.enabled=true \
  --set ingressRoute.dashboard.entryPoints={web} \
  --set providers.kubernetesGateway.enabled=true \
  --set gateway.listeners.web.namespacePolicy.from=All

这里有两处调整:

  1. 将 traefik 的镜像仓库指定为自建的 hub.zentao.net,避免从公网拉取;
  2. 将 service.type 设置为 NodePort,以便在外部访问 traefik,并配合 CLB 实现标准的 80、443 外部流量接入。

注意:执行 kubectl get svc traefik 查看 80/443 在节点上映射的端口,后续需要根据这个端口配置 CLB,实现标准的 80、443 外部流量接入,配合域名使用。

11.3 配置 CLB 接入外部流量

为了让 traefik 能够正常工作,需要配置 CLB 将外部流量路由到 traefik 服务。在腾讯云同地区、同 VPC 内购买一个 CLB,配置 TCP/UDP/TCP SSL/QUIC 类型监听器,分别添加 tcp: 80、tcp: 443 两个监听器,将后端服务绑定到 Kubernetes 节点,端口填写 traefik 的 NodePort 端口;再将一个域名记录泛解析指向 CLB 的公网 IP,就可以通过域名访问集群内的服务了。

十二、添加 Ingress / IngressRoute 路由

traefik 支持 Ingress 和 IngressRoute 两种类型的路由配置。

12.1 使用 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: whoami
  namespace: default
spec:
  ingressClassName: traefik
  rules:
    - host: whoami.kunpeng.thedf.cc
      http:
        paths:
          - backend:
              service:
                name: whoami
                port:
                  number: 80
            path: /
            pathType: Prefix

12.2 使用 IngressRoute

# whoami-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`whoami.kunpeng.thedf.cc`)
      kind: Rule
      services:
        - name: whoami
          port: 80
发表评论
博客分类