ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ARM架构银河麒麟V10系统下K8S 1.26高可用集群部署实战

ARM架构银河麒麟V10系统下K8S 1.26高可用集群部署实战 简介容器化技术通过将应用及其依赖打包成标准单元实现了环境一致性与快速部署其核心原理在于操作系统层面的资源隔离与命名空间控制。作为容器编排的事实标准KubernetesK8S通过声明式API和控制器模式自动化了容器的部署、扩展与管理其技术价值在于为微服务架构提供了强大的运维能力与弹性伸缩基础。在国产化与信创背景下基于ARM架构服务器和银河麒麟Kylin等操作系统的部署需求日益增长。本文聚焦于ARM架构与银河麒麟Kylin V10这一特定组合详细阐述了从系统调优、容器运行时containerd配置到K8S核心组件安装与高可用集群搭建的完整工程实践路径为在国产化平台上构建稳定容器平台提供了具体解决方案。1. 项目概述与背景最近在给一个国产化项目做技术预研客户那边指定了硬件平台是ARM架构的服务器操作系统要求用银河麒麟Kylin V10。任务很明确要在上面搭建一套K8S集群用于后续微服务应用的部署。说实话这个组合——Kylin V10 ARM K8S——在网上的现成、能直接“抄作业”的教程确实不多尤其是涉及到containerd这个容器运行时很多细节都得自己趟一遍。我这次的目标是搭建一个最小化的高可用生产原型一个主节点Master加一个工作节点Node。别看规模小麻雀虽小五脏俱全从系统调优、容器运行时配置到K8S组件的安装与认证一个环节都不能少。选择K8S 1.26.15这个版本主要是考虑到它在1.26这个大版本里属于较新的补丁版修复了不少早期的问题稳定性相对更好同时其API和特性也足够我们当前项目使用。至于为什么用containerd而不是Docker一方面是K8S社区自1.24版本后已经将dockershim移除containerd是更“原生”和推荐的选择另一方面containerd更轻量资源占用少符合我们对底层基础设施简洁、可控的要求。整个部署过程我会把重点放在ARM架构和Kylin系统下的“特殊性”上。比如软件包从哪里获取内核参数和系统服务有哪些需要调整那些在x86环境下可能一键完成的命令在这里可能会遇到什么坑我会把这些实操细节、排查过程和最终验证方法都记录下来。如果你也在类似的国产化或ARM平台上进行容器化部署希望这份从零开始的记录能给你提供一个清晰的路线图。2. 基础环境准备与系统调优在真正动手安装K8S之前把底层系统打磨好是至关重要的一步。这就像盖房子前打地基地基不稳后面再漂亮的架构都可能出问题。在ARM架构的Kylin V10上我们需要特别注意一些与通用Linux发行版不同的地方。2.1 操作系统安装与初始配置我使用的Kylin V10是SP1版本内核版本基于4.19。在安装系统时有几个点需要留意分区方案对于K8S节点特别是主节点/var目录会存放大量的容器镜像、日志和etcd数据。我建议给/var单独分区并预留充足的空间比如100GB以上。/tmp目录大小也需要关注虽然安装时可能提示从1048kb到10MB的范围但在后续软件编译或临时文件操作时可能不够可以通过后面提到的tmpfs或修改/etc/fstab来调整。软件源配置Kylin V10默认的源可能不包含所有需要的软件包。我们需要配置合适的源。通常可以添加Kylin的官方更新源和EPEL源针对ARM架构。有时也需要配置国内的镜像源如华为、阿里云镜像来加速下载。一个典型的操作是备份原有的/etc/yum.repos.d/kylin_aarch64.repo然后修改baseurl指向更快的镜像地址。关闭防火墙与SELinux在实验或内部集群环境中为了减少复杂度我们通常会暂时关闭防火墙和SELinux。但在生产环境中需要根据安全策略进行精细配置。# 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 关闭SELinux需重启生效 sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config setenforce 0 # 临时生效2.2 内核参数与系统服务调优K8S对Linux内核有一些要求我们需要确保相关模块已启用并优化系统参数。加载内核模块overlay和br_netfilter是必须的。overlay是containerd和Docker使用的存储驱动之一br_netfilter用于让iptables能够查看桥接流量这是K8S Service网络正常工作所必需的。cat /etc/modules-load.d/k8s.conf EOF overlay br_netfilter EOF # 手动加载模块 modprobe overlay modprobe br_netfilter配置sysctl参数需要修改网络和虚拟内存相关的内核参数。将这些配置写入/etc/sysctl.d/k8s.conf然后执行sysctl --system使其生效。cat /etc/sysctl.d/k8s.conf EOF net.bridge.bridge-nf-call-ip6tables 1 net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 vm.swappiness 0 EOF sysctl --systemnet.ipv4.ip_forward1开启IPv4转发这是Pod跨节点通信的基础。vm.swappiness0尽量使用物理内存避免使用swap因为swap会导致kubelet等组件性能不稳定。关闭swapK8S从1.8版本开始要求关闭swap以确保调度器性能。可以通过swapoff -a临时关闭并注释掉/etc/fstab中swap分区的挂载项以实现永久关闭。时间同步集群内所有节点时间必须同步否则会导致证书错误、日志时间错乱等问题。使用chronyd服务进行时间同步。yum install -y chrony systemctl enable --now chronyd chronyc sources # 查看同步状态2.3 安装与配置containerdcontainerd将作为我们的容器运行时。在ARM架构上我们需要获取aarch64版本的安装包。下载containerd从GitHub releases页面下载适用于ARM64即aarch64的containerd二进制包。例如我选择版本1.6.28。wget https://github.com/containerd/containerd/releases/download/v1.6.28/containerd-1.6.28-linux-arm64.tar.gz解压与安装将二进制文件解压到系统的/usr/local/bin/目录。tar Cxzvf /usr/local/bin containerd-1.6.28-linux-arm64.tar.gz生成systemd服务文件containerd包中通常不包含service文件需要手动创建。cat /etc/systemd/system/containerd.service EOF [Unit] Descriptioncontainerd container runtime Documentationhttps://containerd.io Afternetwork.target local-fs.target [Service] ExecStartPre-/sbin/modprobe overlay ExecStart/usr/local/bin/containerd Typenotify Delegateyes KillModeprocess Restartalways RestartSec5 LimitNPROCinfinity LimitCOREinfinity LimitNOFILEinfinity TasksMaxinfinity OOMScoreAdjust-999 [Install] WantedBymulti-user.target EOF配置containerd生成默认配置文件并修改关键参数。mkdir -p /etc/containerd containerd config default /etc/containerd/config.toml需要修改config.toml中的两处将SystemdCgroup设置为true以便与systemd的cgroup驱动配合。[plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options] SystemdCgroup true配置镜像加速器国内环境必备。在[plugins.io.containerd.grpc.v1.cri.registry.mirrors]下添加国内镜像地址如阿里云。[plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io] endpoint [https://your-mirror.mirror.aliyuncs.com]启动并验证containerdsystemctl daemon-reload systemctl enable --now containerd systemctl status containerd ctr version # 验证客户端命令注意如果ctr命令找不到可能是因为/usr/local/bin不在PATH中可以创建软链接ln -s /usr/local/bin/ctr /usr/bin/。3. K8S核心组件安装与配置基础环境就绪后我们就可以安装K8S的核心三件套kubeadm、kubelet和kubectl。kubeadm是集群的引导工具kubelet是运行在每个节点上的代理kubectl是命令行管理工具。3.1 配置K8S软件源并安装组件在ARM架构的Kylin上我们需要使用针对aarch64的K8S仓库。添加K8S yum源创建repo文件。cat /etc/yum.repos.d/kubernetes.repo EOF [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-aarch64/ enabled1 gpgcheck1 repo_gpgcheck1 gpgkeyhttps://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF这里使用了阿里云的镜像源速度更快。注意路径中的aarch64。安装指定版本组件我们需要精确安装1.26.15版本。yum install -y kubelet-1.26.15 kubeadm-1.26.15 kubectl-1.26.15 --disableexcludeskubernetes--disableexcludeskubernetes参数是为了防止某些系统排除kubernetes仓库的更新。设置kubelet开机自启暂不启动systemctl enable kubelet注意此时先不要启动kubelet因为它的配置文件由kubeadm init生成还不存在启动会报错。3.2 使用kubeadm初始化主节点Master这是搭建集群最核心的一步。我们将在主节点上执行kubeadm init。生成初始化配置文件先导出一份默认配置然后按需修改。kubeadm config print init-defaults kubeadm-config.yaml编辑配置文件主要修改以下几个关键部分apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration nodeRegistration: criSocket: unix:///var/run/containerd/containerd.sock # 指定containerd的socket路径 imagePullPolicy: IfNotPresent --- apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.26.15 # 指定版本 controlPlaneEndpoint: master-node-ip:6443 # 如果是单主就写主节点的IP。如果后续考虑高可用这里应配置负载均衡器的VIP。 networking: podSubnet: 10.244.0.0/16 # 设置Pod网络CIDR需要与后续安装的CNI插件匹配这里以Flannel为例 serviceSubnet: 10.96.0.0/12 imageRepository: registry.aliyuncs.com/google_containers # 使用国内镜像仓库加速镜像拉取criSocket必须正确指向containerd的socket这是kubelet与容器运行时通信的接口。podSubnet这个值必须与你将要安装的Pod网络插件CNI的默认网段一致。例如Flannel的默认网段就是10.244.0.0/16。如果这里不匹配Pod将无法分配IP。预拉取镜像可以提前拉取所需镜像避免初始化时因网络问题超时。kubeadm config images pull --config kubeadm-config.yaml观察拉取的镜像确认都是从registry.aliyuncs.com/google_containers这个仓库拉取的。执行初始化命令kubeadm init --config kubeadm-config.yaml --upload-certs--upload-certs将控制平面证书上传到集群方便后续其他控制平面节点或工作节点加入。 这个过程会持续几分钟如果一切顺利你会在最后看到类似如下的成功信息其中包含kubeadm join命令和用于kubectl的管理员配置命令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.1.100:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx务必妥善保存这个kubeadm join命令后续工作节点加入集群时需要用到。配置kubectl按照上述提示为当前用户配置kubectl。mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config验证主节点状态kubectl get nodes此时主节点状态应为NotReady因为还没有安装Pod网络插件CNI。3.3 安装Pod网络插件CNICNI是K8S集群的“神经系统”负责Pod之间的网络通信。这里我们选择最经典的Flannel。下载Flannel的ARM架构manifest文件Flannel的DaemonSet需要拉取ARM架构的镜像。wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml可选但重要修改镜像地址原始yaml中的quay.io镜像仓库在国内可能拉取缓慢或失败。我们可以将其替换为国内镜像。 使用sed命令进行替换sed -i s#quay.io/coreos/flannel#registry.cn-hangzhou.aliyuncs.com/google-containers/flannel#g kube-flannel.yml这个命令将镜像地址换成了阿里云镜像仓库的对应镜像。部署Flannelkubectl apply -f kube-flannel.yml验证部署kubectl get pods -n kube-system -l appflannel等待所有kube-flannelPod的状态变为Running。再次检查节点状态kubectl get nodes此时主节点的状态应该变为Ready。4. 工作节点Node加入集群主节点配置完成后工作节点的加入就相对简单了。在工作节点上你需要重复第2节基础环境准备与系统调优和第3.1节安装K8S组件的所有步骤。确保containerd、kubelet、kubeadm的版本与主节点完全一致。在工作节点上执行使用之前从主节点初始化成功输出中保存的kubeadm join命令。kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx验证节点加入回到主节点执行kubectl get nodes稍等片刻你应该能看到两个节点状态都是Ready。至此一个基于Kylin V10和ARM架构的双节点K8S集群就搭建完成了。5. 集群功能验证与基础问题排查集群搭建完成后不能只看状态是Ready就完事必须运行一些实际的工作负载来验证其核心功能是否正常。5.1 核心功能验证部署一个测试应用我们部署一个最简单的Nginx Deployment和Service。kubectl create deployment nginx-test --imagenginx:alpine kubectl expose deployment nginx-test --port80 --typeNodePort检查Pod和Servicekubectl get pods -o wide kubectl get svc nginx-test观察Pod是否运行在某个节点上比如工作节点并处于Running状态。查看Service的NodePort端口例如32688。访问测试在集群内或集群外通过节点的IP地址和NodePort端口访问这个Nginx服务。curl 工作节点IP:NodePort端口如果能看到Nginx的欢迎页面说明Pod调度、网络Service和NodePort功能均正常。5.2 常见问题与排查技巧实录在实际操作中你几乎一定会遇到一些问题。下面是我在部署过程中遇到的一些典型问题及解决方法。问题1kubeadm init时卡在[kubelet-check]或提示kubelet服务未运行。排查思路首先检查kubelet服务状态systemctl status kubelet。如果没启动尝试systemctl start kubelet并查看日志journalctl -xeu kubelet。最常见的错误是cgroup驱动不匹配。Kylin V10默认使用systemd作为cgroup驱动。你需要确保两处配置一致containerd配置在/etc/containerd/config.toml中SystemdCgroup需要设为true。kubelet配置在/var/lib/kubelet/config.yaml由kubeadm生成或通过kubeadm的配置文件确保cgroupDriver也是systemd。修改containerd配置后必须重启containerd服务systemctl restart containerd。如果问题依旧可以重置kubeadmkubeadm reset -f清理环境后重新init。问题2Pod一直处于Pending状态描述信息显示0/1 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }。排查思路这说明节点虽然有Ready标签但可能存在污点Taint或节点本身并未完全就绪。首先检查节点详情kubectl describe node 节点名。查看Conditions部分确认NetworkReady、MemoryPressure、DiskPressure等是否为False。如果Ready为False则节点未就绪。最常见的原因是CNI插件如Flannel没有成功运行。检查kube-system命名空间下的Podkubectl get pods -n kube-system。查看flannel或coredns的Pod是否处于CrashLoopBackOff或Error状态。查看问题Pod的日志kubectl logs -n kube-system flannel-pod-name。常见错误是镜像拉取失败网络问题或CNI二进制文件缺失。确保已按照前面步骤修改了Flannel的镜像地址。问题3Pod状态为ContainerCreating并长时间无进展describe pod显示Failed to create pod sandbox: rpc error: code Unknown desc failed to get sandbox image ...。排查思路这是containerd拉取pause镜像失败。K8S需要一个基础的sandbox镜像通常是pause。检查containerd是否能拉取镜像crictl pull registry.aliyuncs.com/google_containers/pause:3.9。crictl是CRI容器运行时接口的调试工具需要单独安装(yum install cri-tools)。如果拉取失败检查containerd的配置文件/etc/containerd/config.toml中的registry.mirrors配置是否正确以及主机网络是否通畅。可以手动拉取并打标签ctr -n k8s.io images pull registry.aliyuncs.com/google_containers/pause:3.9 ctr -n k8s.io images tag registry.aliyuncs.com/google_containers/pause:3.9 registry.k8s.io/pause:3.9问题4工作节点kubeadm join失败提示token过期或无效。排查思路kubeadm token默认24小时有效。如果过期需要在主节点上生成新的token和hash。kubeadm token create --print-join-command这个命令会直接输出完整的kubeadm join命令包含新的token和hash。如果忘记了--discovery-token-ca-cert-hash可以在主节点上通过以下命令重新获取openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2/dev/null | openssl dgst -sha256 -hex | sed s/^.* //问题5使用kubectl命令时提示The connection to the server localhost:8080 was refused。排查思路这说明kubectl没有找到正确的配置文件。你需要确保已经按照3.2节第5步将/etc/kubernetes/admin.conf复制到了$HOME/.kube/config。或者每次使用前显式指定配置文件kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes。也可以将KUBECONFIG环境变量设置为配置文件路径export KUBECONFIG/etc/kubernetes/admin.conf可写入~/.bashrc永久生效。实操心得在ARM平台上所有问题的排查第一步都应该是确认架构和版本。无论是系统包、容器镜像还是二进制工具aarch64/arm64是关键标签。从错误的源安装了x86_64的包或者拉取了不对架构的镜像都会导致各种诡异且难以直接看出的错误。养成习惯在下载或拉取任何东西前先确认其是否支持ARM。本文还有配套的精品资源点击获取
返回列表