今天来填一个大坑:K8s集群1.31版本的手工安装。先说清楚这篇东西是什么:一份从零开始、能在你本地或测试环境里把Kubernetes 1.31集群搭起来、并且能稳定运行的手册。别看网上k8s安装教程一抓一大把,真到1.31这种较新版本,很多老文章要么参数对不上,要么kubeadm配置格式变了还硬套旧写法,踩起坑来相当耽误时间。这篇适合两类人看:一类是刚接触k8s没几天、想完整走一遍集群搭建流程的新手,另一类是有一定基础、但需要在测试环境快速拉起一套1.31版本集群的运维或开发。我不讲花里胡哨的理论,只讲怎么落地、每一步为什么要这么做、哪些坑我替你踩过了。
1. 环境规划与前置准备
1.1 版本选择与组件搭配
先聊版本。Kubernetes没有LTS的说法,每个大版本滚动支持大约14个月,1.31属于当前迭代较快的一个版本。选它做安装目标,主要是组件支持比较新,kubeadm、kubelet、kubectl版本一致,后续维护也有足够时间窗口。
需要注意的是,kubeadm在1.29之后引入了v1beta4配置格式,1.31版本同样使用这个格式。很多老教程还在用v1beta3甚至v1beta2,直接复制过来大概率报错。另外,kubelet版本不需要和apiserver完全一致,官方允许kubelet比apiserver低一个小版本,比如apiserver是1.31,kubelet可以用1.30,但不建议差距拉太大,不然特性开关和行为差异会让你排查问题排查到怀疑人生。
容器运行时我建议用containerd。Docker作为k8s运行时的时代早就过去了,从1.24开始kubelet就移除了dockershim,现在官方默认就是containerd。选择版本时,containerd 2.x已经发布,但大量生产环境和镜像兼容性测试还是集中在1.7.x系列,所以我建议选1.7系列的最新patch版本,稳。
还有个容易被忽略的点:crictl命令行工具。它用来跟containerd交互,排查问题时查容器状态、看容器日志都靠它。安装containerd时一般会带出来,但也有人单独装的,记得确认版本能和containerd对上。
1.2 主机规划与网络拓扑设计
搭建集群之前,先把机器和网络规划好。我常用的方案是三台Master加三台Worker,生产环境最低也建议三台Master。如果你只是自己学习,一台Master加一台Worker也能跑起来。以下假设你用三台机器做实验,至少留出2核4G内存,磁盘20G以上,不然etcd和apiserver跑起来会非常吃力。
| 角色 | 主机名 | IP规划(示例) |
|---|---|---|
| Master-1 | k8s-master01 | 192.168.10.11 |
| Master-2 | k8s-master02 | 192.168.10.12 |
| Master-3 | k8s-master03 | 192.168.10.13 |
| Worker-1 | k8s-node01 | 192.168.10.21 |
| Worker-2 | k8s-node02 | 192.168.10.22 |
| Worker-3 | k8s-node03 | 192.168.10.23 |
网络规划上要注意几点:
- 所有节点内网互通,延迟不要太高,kubelet和kube-proxy之间有心跳和同步机制,网络抖动大容易让节点误判为NotReady。
- /etc/hosts统一写上所有主机名和IP,避免解析问题。不要依赖企业内部DNS,除非你确定DNS记录一定正确。
- 预留一个负载均衡地址,也就是VIP,用于API Server的HA访问。生产环境一般用Keepalived或者云厂商的LB,测试环境可以先用Master-1的IP顶着。
除此之外,时间同步一定要做。k8s里证书验证、日志时间戳、etcd选主都依赖时间一致,偏差太大会出现莫名其妙的“证书尚未生效”错误。建议统一配置chrony或者ntpd,别在这上面省事。
1.3 系统初始化:关闭swap、加载内核模块、配置镜像加速
这一步是纯体力活,但每一件都不能少。我按顺序列一下:
# 关闭swap,注释掉/etc/fstab中的swap行 swapoff -a sed -i '/ swap / s/^/#/' /etc/fstab # 加载内核模块 modprobe br_netfilter modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr modprobe ip_vs_sh modprobe nf_conntrack # 设置网络转发 sysctl -w net.ipv4.ip_forward=1然后写入sysctl配置,让重启后自动生效:
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.route_localnet = 1 EOF sysctl --system为什么要加载ip_vs这些模块?因为kube-proxy默认会往IPVS模式走,如果模块没加载,它只能回退到iptables模式。不是说iptables不行,而是IPVS在service数量较多时性能更好、规则更清晰。既然想用,就提前把模块备好。
镜像加速这里要单独提一句。拉起k8s组件时kubeadm会拉取镜像,默认registry是registry.k8s.io,国内访问经常失败。我一般是把kubeadm的镜像源改成国内镜像仓库,方法是在kubeadm init时指定--image-repository参数,后面实操会写。containerd的pause镜像也需要同步处理,改config.toml里的sandbox_image字段。
防火墙方面,如果你用的是firewalld,需要放行几个端口:6443(apiserver)、2379/2380(etcd)、10250(kubelet)、10259(kube-scheduler)、10257(kube-controller-manager)、30000-32767(NodePort服务段)。如果不想麻烦,测试环境直接关掉firewalld也行,生产环境建议用安全组规则精确控制。
2. kubeadm工作流程与关键参数拆解
2.1 kubeadm init在背后做了什么
kubeadm init不是一条简单的命令,它内部按固定顺序做了这几件事:
- 生成证书:包括CA证书、apiserver证书、etcd证书、service account密钥等,默认有效期是1年。
- 生成kubeconfig文件:admin.conf、kubelet.conf等,分别给管理端和kubelet用。
- 生成静态Pod清单:把etcd、kube-apiserver、kube-controller-manager、kube-scheduler都以静态Pod的形式放到
/etc/kubernetes/manifests目录下。 - 拉取镜像:根据你指定的镜像仓库和版本拉取各组件镜像。
- 初始化控制平面:把集群状态写入etcd,并部署完核心组件。
- 生成节点加入命令:输出一段包含token的join命令,给其他节点用。
这里回答一个很多人困惑的点:为什么要用静态Pod?因为apiserver、etcd这些组件是集群自身的基础设施,如果它们跑在普通Pod里就会形成循环依赖——没有kubelet就没有Pod,没有Pod就没有控制平面。静态Pod由kubelet直接启动和管理,不依赖集群API,这样基础组件才能自举。明白了这一点,你就知道如果apiserver出问题,正确的方式不是去kubectl delete pod,而是直接检查/etc/kubernetes/manifests/kube-apiserver.yaml这个文件,修改后kubelet会自动重启新的Pod。
2.2 网络与证书参数怎么选
kubeadm init最核心的参数是这几个:
| 参数 | 含义 | 我常用的值 |
|---|---|---|
--apiserver-advertise-address | apiserver对外广播的地址 | 当前节点IP |
--control-plane-endpoint | 高可用时的负载均衡地址 | VIP或域名 |
--pod-network-cidr | Pod网段 | 取决于CNI插件 |
--service-cidr | Service网段 | 10.96.0.0/12 |
--image-repository | 镜像仓库 | 国内镜像源 |
--kubernetes-version | 版本 | v1.31.x |
--pod-network-cidr这个参数最容易踩坑,因为它必须和后续安装的CNI插件要求的网段一致。比如flannel默认用10.244.0.0/16,calico默认用192.168.0.0/16。如果你初始化时指定了一个网段,后面装的CNI插件用的是另一个网段,那Pod之间的网络直接不通,coredns也一直CrashLoopBackOff。先确定CNI再确定这个值,别反过来。
--service-cidr建议保持10.96.0.0/12默认值,除非你物理网络正好占了这一段。Service网段和Pod网段都不能和宿主机网段重叠,否则路由混乱。
还有一个容易忽略的是证书。kubeadm生成的所有证书默认一年有效期,这不算bug,是设计如此。很多集群跑着一半年后突然出现kubectl认证失败,排查半天才发现是apiserver的client证书过期了。解决方案要么是定期执行kubeadm certs renew all,要么是做证书自动轮换。1.31版本里kubelet的证书自动轮换默认已经支持,但控制平面的证书还是需要手动续。我在生产环境里是写了个cron job,在证书过期前一个月自动执行续期并重启相关组件。
2.3 containerd配置的细节
containerd的配置在/etc/containerd/config.toml,有两个地方必须注意。第一个是SystemdCgroup,这个值必须改成true。因为systemd作为init进程会管理cgroup,如果containerd不用systemd cgroup驱动,kubelet和容器运行时会因为cgroup driver不一致而报错,节点直接NotReady。网上很多人卡在这一步,其实就是一个布尔值的问题。
第二个是sandbox_image。这个是pause镜像,每个Pod都会用到它。默认值指向的仓库在国内基本拉不动。建议改成能访问的镜像地址,比如你用的镜像仓库里对应的pause镜像地址。
修改完配置后记得重启containerd并验证:
systemctl restart containerd crictl infocrictl info输出里能直接看到容器运行时的状态,确保它在Running。如果这一步没做好,后面kubeadm init会卡在等待kubelet启动那里,报告里全是Connection refused。
3. 手工初始化Master节点与worker节点加入
3.1 Master节点初始化命令与配置
环境准备好后,在Master-1上执行初始化。我建议把kubeadm配置写成文件,而不是全部用命令行参数,因为配置文件更好管理,后续看记录也方便。
apiVersion: kubeadm.k8s.io/v1beta4 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.10.11 bindPort: 6443 --- apiVersion: kubeadm.k8s.io/v1beta4 kind: ClusterConfiguration kubernetesVersion: v1.31.0 controlPlaneEndpoint: "192.168.10.11:6443" networking: podSubnet: "10.244.0.0/16" serviceSubnet: "10.96.0.0/12" imageRepository: "registry.cn-hangzhou.aliyuncs.com/google_containers"注意看这里我用的podSubnet是10.244.0.0/16,对应后面会装flannel网段。
执行初始化:
kubeadm init --config kubeadm-config.yaml --upload-certs--upload-certs参数用于HA场景,它会把控制平面证书上传到集群,方便后续节点加入控制平面时自动获取。如果是单Master,不需要这个参数。
整个初始化过程大概3到5分钟,取决于镜像拉取速度。顺利的话,最后会输出这样一段内容:
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 You can now join any number of control-plane nodes by copying certificate authorities and service account signing keys to each node and then running the following as root: kubeadm join 192.168.10.11:6443 --token ... --discovery-token-ca-cert-hash sha256:... Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.10.11:6443 --token ... --discovery-token-ca-cert-hash sha256:...先把这两段输出保存好,特别是join命令,token默认24小时过期,过期后还要重新生成。
然后配置kubectl访问权限:
mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config这里我要多说一句:admin.conf本质上是一个超级权限的kubeconfig文件,拥有cluster-admin权限,务必保管好。有些人图方便把它到处拷贝,到后来分不清哪个环境是哪个环境,安全隐患非常大。建议各节点的kubeconfig分开管理,不要混用。
3.2 控制平面节点和Worker节点加入
Master初始化好之后,如果还有Master-2和Master-3,需要分别在它们上面执行控制平面加入命令。控制平面加入和Worker加入最大的区别在于,命令加了--control-plane参数,并且需要指定证书路径:
kubeadm join 192.168.10.11:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx --control-plane --certificate-key xxx这里用到的--certificate-key就是前面--upload-certs生成的,用来解密上传到集群的证书。没有这个key,控制平面节点是加入不了的。
Worker节点加入就简单了,直接用输出里的join命令:
kubeadm join 192.168.10.11:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx等待每个节点加入后,回到Master-1上查看节点状态:
kubectl get nodes如果一切正常,所有节点状态应该是NotReady。对,你没看错,是NotReady而不是Ready,因为现在还没有安装CNI网络插件,Node的网络状态没办法报告就绪。没装网络插件之前节点NotReady是正常现象,不要慌,这和故障是有区别的。
3.3 验证集群核心组件状态
在安装CNI之前,可以先验证控制平面各组件是否正常:
kubectl get pods -n kube-system正常情况下能看到etcd、kube-apiserver、kube-controller-manager、kube-scheduler这几个Pod在Running。coredns很可能处于Pending状态,这也不要急,CNI装完它会自动调度起来。
还有一个常被忽略但很有用的验证项:检查各组件健康状态。
kubectl get --raw=/healthz返回ok就说明apiserver本身健康。如果想看etcd、controller-manager这些组件的健康情况,分别请求对应的健康端点:
kubectl get --raw=/livez?verbose这个方法比看Pod状态更准确。Pod一直Running不代表内部goroutine没卡死,健康检查能直接暴露问题。
3.4 token过期后的处理方式
很多人搭集群时速度慢,折腾了两三天才想起还有Worker节点没加入,结果token早就过期了。重新生成token的方法:
kubeadm token create --print-join-command这条命令会生成一个新的token,并直接打印出完整join命令。如果还需要控制平面加入的那个--certificate-key,要重新生成:
kubeadm init phase upload-certs --upload-certs需要注意的是,token的最小粒度是节点级别,每个节点加入后可以在kubeadm token list里看到对应的token记录。为了方便管理,也可以在Kubernetes的Secret里查看bootstrap-token的详情,这个原理属于kubeadm的控制平面启动引导机制,有兴趣可以再看看官方文档。
4. CNI网络插件安装与集群健康检查
4.1 flannel与calico怎么选
CNI插件是k8s集群里最不能拍脑袋选的组件。常见选择是flannel和calico,两者工作原理差异很大:
- flannel使用VXLAN或者host-gw模式,纯三层网络,部署简单,性能中规中矩,排错容易。
- calico通过BGP协议分发路由,原生支持NetworkPolicy,性能更好,但组件更多,配置项也更复杂。
我的建议:学习环境和不需要精细网络策略的场景直接用flannel;需要NetworkPolicy、多租户隔离、复杂网络策略的生产环境用calico。很多人觉得calico一定比flannel好,其实不一定,calico的BGP全互联模式在大集群里会撑爆连接数,还得切换成RR模式,反而更折腾。
以flannel为例,安装命令很简单:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml如果你在离线环境或者无法访问GitHub的环境里,就自己下载好这个yaml文件,然后apply本地文件。
装完后回到Master-1看节点状态:
kubectl get nodes等待一两分钟,节点应该全部变成Ready。如果还是NotReady,用kubectl describe node看具体原因,最常见的几个原因我放在下一章排查部分详聊。
4.2 多网卡环境的IP自动检测问题
多网卡服务器是网络插件最容易翻车的地方。flannel和calico都有自动检测网卡的逻辑,但自动检测不一定总是选对。比如服务器上有eth0和eth1,k8s业务网段在eth1上,但默认路由走的是eth0,网络插件可能就会选错网卡,造成Pod可以启动但互相ping不通。
flannel的处理方式:在启动参数里加--iface=eth1。calico的处理方式:修改manifest里环境变量IP_AUTODETECTION_METHOD=interface=eth1。
这个问题在物理机和虚拟机混布的集群里特别常见,还没有一个万能的自动方案,装完插件后最好做一次Pod间的网络连通性测试。我的习惯是起一个测试Pod,从里面ping集群里其他节点上的Pod IP,能通才算真正装好。如果这时候发现不通,不要怀疑CNI,先去检查网卡选择。
4.3 关键检查项:coredns、kube-proxy、IPVS模式
CNI装好后,集群才算有了基本的网络能力。此时有几个必须验证的点:
第一,coredns必须Running。它在初始化时就已经创建,只是等待网络插件就绪。如果CNI装完它还是Pending,用kubectl describe pod -n kube-system coredns-xxx看事件,最常见的是节点亲和性或者内存不足导致调度失败。
第二,kube-proxy是否真的跑在IPVS模式。检查方法:
kubectl logs -n kube-system kube-proxy-xxx | grep ipvskube-proxy启动时会记录当前使用哪种模式,如果你看到Using ipvs Proxier,说明IPVS模块加载成功;看到Using iptables Proxier,说明模块没加载,回退到了iptables。想切回IPVS就回头补加载内核模块并重启kube-proxy。
第三,用kubectl get svc创建或查看已有Service,确认ClusterIP能正常访问。一个简单的验证方式:
kubectl run test --image=busybox --rm -it -- sh wget -qO- http://kubernetes.default.svc.cluster.local能返回内容说明Service和DNS链路都是通的。
4.4 资源压力对集群健康的影响
还有一个很多人忽略的健康杀手:磁盘和内存压力。kubelet会定期汇报节点状态,如果磁盘使用率超过eviction threshold,节点上的Pod会被驱逐,甚至节点直接NotReady。我见过一个测试环境,master节点上跑了几个大日志文件进程,把磁盘打满,然后apiserver和etcd同时Status变成Unknown,整个集群进入“假死”状态。
所以健康检查别只盯Pod,也要看节点级别:
kubectl describe node k8s-master01 | grep -A10 Conditions重点关注MemoryPressure、DiskPressure、PIDPressure这几个条件。任何一个为True,说明节点已经处于资源紧张状态,先腾资源再继续后面的操作。
5. 常见问题与排查技巧实录
5.1 “The API server is not healthy”的完整排查逻辑
这个错误大概是kubeadm init过程中最多人遇到的拦路虎。报错信息类似:
[kubeadm] waiting for the kubelet to boot the control plane as static Pods ... The api server is not healthy after 4m0.00747357s这句话翻译过来是:kubeadm等了4分钟,apiserver一直没能通过健康检查,于是放弃等待并报错。问题根源不一定真的在apiserver,也可能是kubelet根本没能把静态Pod拉起来。
我一般按这个顺序排查,几乎每次都管用。
第一步,看kubelet日志:
journalctl -u kubelet -f如果kubelet反复报错,说明它没有正常工作。常见原因包括配置目录权限不对、containerd连接失败、kubelet版本不匹配等。
第二步,看静态Pod有没有创建:
crictl ps -a | grep kube-apiserver如果没有apiserver容器,说明kubelet没有正确读取manifest目录,去检查/etc/kubernetes/manifests是否存在、配置文件格式是否正确。如果有容器但状态不是Running,重点看日志:
crictl logs <container-id>第三步,针对日志内容分情况处理:
- 如果报镜像拉取失败,就去检查imageRepository配置,手动拉一次镜像验证。
- 如果报证书相关问题,检查
/etc/kubernetes/pki目录里的证书文件是否完整,apiserver启动时读不到证书就是这类报错。 - 如果报端口占用,用
ss -lntp | grep 6443检查,6443被占用时apiserver根本启动不了。 - 如果报etcd连接不上,检查etcd容器状态,或者看
/etc/kubernetes/manifests/etcd.yaml里的listen-client-urls配置。
第四步,查一个最容易忽略的点:磁盘和内存是否充足。apiserver对资源要求不高,但如果机器本身因为内存不足触发OOM,容器起来一个挂一个,kubeadm当然等不到健康状态。用dmesg | grep -i oom基本能看出来。
5.2 证书相关:一年过期后怎么办
证书过期问题不是安装当天的坑,而是集群跑了一段时间后的坑。症状很典型:kubectl get nodes突然报error: You must be logged in to the server (Unauthorized),或者apiserver日志里刷certificate has expired or is not yet valid。
处理方法是续期证书并重启相关组件:
kubeadm certs renew all kubectl -n kube-system rollout restart deployment/coredns但这里有个坑:如果kubelet的配置还是旧证书,续期后还要重新生成admin.conf和kubelet.conf。正规律师做法是:
kubeadm init phase kubeconfig admin --config kubeadm-config.yaml然后更新$HOME/.kube/config。
我的建议是别等到出了故障再管证书。生产环境一定要加监控,比如prometheus里加一个证书过期的exporter,提前三周告警。没有监控的话,至少写个cron脚本定期检查kubeadm certs check-expiration。这个命令在1.31版本里可以直接看所有证书和kubeconfig的过期时间,非常方便。
5.3 Worker节点一直NotReady的常见原因
Workder节点加入后状态一直是NotReady,排除CNI没装这个因素外,还有这么几种可能。
第一,kubelet和apiserver版本差距过大。检查kubelet日志里有没有failed to run Kubelet: invalid configuration之类的字样,有就降级或升级kubelet到匹配版本。
第二,节点时间不同步。这个前面提过,这里再强调一次,轻则证书验证失败,重则etcd选举混乱。测试方法就是随便在两台机器上执行date,看输出时间差异。
第三,防火墙没放行10250端口。kubelet通过这个端口向apiserver上报状态,apiserver拿不到心跳就会把节点标记NotReady。排查方法是:
curl -k https://<node-ip>:10250/healthz第四,kubelet启动失败但没有明显报错。这种情况多做一步:删除kubelet的遗留状态文件再重启:
rm -rf /var/lib/kubelet/cpu_manager_state systemctl restart kubelet有时候cgroup相关文件损坏也会卡住kubelet,删掉重建就恢复了。
第五,节点资源不足。如果一个节点上已经跑满了Pod,新加入的Pod调度不上来,但节点本身依然是Ready状态。真正让节点变NotReady的是上面说的磁盘、内存、PID压力。用kubectl describe node看Conditions最直观。
5.4 问题速查表
整理一个速查表,方便直接对号入座。
| 症状 | 可能原因 | 排查命令 | 推荐解法 |
|---|---|---|---|
| kubeadm init等待超时 | apiserver容器起不来 | crictl ps -a和journalctl -u kubelet | 根据日志排查证书、镜像、端口问题 |
| coredns一直Pending | CNI未安装或网段不匹配 | kubectl describe pod -n kube-system coredns-xxx | 安装CNI或确保podSubnet与CNI一致 |
| Pod网络互ping不通 | 多网卡选错网卡 | kubectl logs -n kube-system <flannel-pod> | 指定网卡参数重启网络插件 |
| kubectl报Unauthorized | 证书过期或kubeconfig失效 | kubeadm certs check-expiration | 续期证书并更新kubeconfig |
| 节点NotReady | kubelet心跳丢失 | journalctl -u kubelet | 检查时间同步、防火墙、kubelet配置 |
| Service ClusterIP无法访问 | kube-proxy未正常工作 | kubectl logs -n kube-system kube-proxy-xxx | 检查IPVS模块或重建kube-proxy |
| 组件Pod反复重启 | 磁盘压力触发驱逐 | kubectl describe node | 清理日志和无用镜像腾出磁盘 |
5.5 containerd频繁重启的隐藏原因
有时候kubelet没报错、配置也没问题,但containerd就是一直重启,需要检查一下它依赖的runc或CNI插件二进制是否还有权限。有一种真实发生过的场景:某些运维平台会把/usr/bin目录权限改了,containerd启动时报权限错误,然后一直crash循环。排查方式就是看journalctl -u containerd的日志,重点找permission denied。
另外一个隐患:containerd的root目录满了。用du -sh /var/lib/containerd看下大小,如果占满分区,镜像拉取、容器创建都会失败。这是我见过好多次的隐藏故障,不是配置问题,是容量问题。
6. 个人实操经验与建议
这套流程我在测试环境和生产环境都完整走过,最大的体会是:安装过程本身难度其实不大,真正的复杂度在于环境差异和细节把控。kubeadm把控制平面积淀得很成熟,你只要按官方文档走,基本都能成功,但成功和稳定是两码事。
个人建议有时间的话,装一次1.31版本集群后,一定要刻意做几个练习:把某个Master节点重启,看集群怎么恢复;模拟etcd单节点故障,看剩余节点能否继续提供API服务;关闭一台Worker的网络,看Pod如何被驱逐到其他节点。只有亲手制造过故障,你才真正理解k8s的自我保护机制是怎么工作的。
再分享一个小技巧:安装过程中所有关键日志和数据备份好,特别是/etc/kubernetes目录和kubeadm-config.yaml文件。如果哪次升级或变更搞砸了,回滚时能直接恢复控制平面。我个人的习惯是把这些配置纳入git管理,每次变更有记录,出了问题能快速对比找出差异。
1.31版本的集群搭建到这就完成了,后面可以继续做dashboard、监控、日志收集这些周边设施。建议先从监控告警开始搭,没有监控的集群等于盲飞。如果搭建过程中遇到本文没覆盖到的问题,欢迎带着日志来交流,我看到就会回复。