广告:Codex Token 低价中转站稳定接口 · 快速接入 · 开发者备用通道
Engineering article

Kubernetes高可用部署,真实项目总结

在实际部署Kubernetes高可用集群时,我见过太多哥们在命令行里把玩了三天,最后发现根本没搞对。高可用不是装几个节点就完事,它是一个系统工程,需要从底层网络、存储、负载均衡到上层调度策略全方位设计。我踩过一个坑,就是用默认的Kubeadm部署方式,结果节点崩了,服务也不可用。后来才知道,必须用Kubeadm的高可用模式,或者更稳妥的是

Kubernetes高可用部署,真实项目总结
配图来源于网络和AI生成,仅供参考。
▌ 技术引导
在实际部署Kubernetes高可用集群时,我见过太多哥们在命令行里把玩了三天,最后发现根本没搞对。高可用不是装几个节点就完事,它是一个系统工程,需要从底层网络、存储、负载均衡到上层调度策略全方位设计。我踩过一个坑,就是用默认的Kubeadm部署方式,结果节点崩了,服务也不可用。后来才知道,必须用Kubeadm的高可用模式,或者更稳妥的是用Kops,甚至用Kubeflow的工具来简化流程。另外,etcd的高可用配置是关键,我之前用单节点etcd导致整个集群不可用,后来强制用三个节点部署,问题才解决。还有,负载均衡器的选型要慎重,我试过用Nginx和HAProxy两种,发现Nginx在特定场景下反而更稳定。总之,得把每个环节都摸清楚,别想着一步到位。

▌ 技术参考
Kubernetes高可用部署的核心在于保证控制平面组件的冗余和网络的稳定性。通常,高可用集群需要至少三个Master节点,每个节点运行API Server、Controller Manager和Scheduler。三节点部署能防止单点故障,同时确保Raft一致性协议的正常运行。在我部署过程中,用Kubeadm的高可用模式时,必须确保所有Master节点的时间同步,否则选举会出问题。可以通过`ntpdate`或者`chronyd`来对齐时间。此外,etcd集群必须配置三个节点,使用`--initial-cluster`参数指定各个节点的地址。记得要设置`--quota-backend-bytes`,否则日志可能会撑爆磁盘。

在具体操作中,可以通过`kubeadm init phase etcd local`命令来初始化本地etcd集群,然后用`kubeadm init phase kube-apiserver local`来配置API Server。这里有个坑,必须确保所有节点的`/etc/kubernetes/manifests`目录下配置文件的权限正确,否则容器会启动失败。通常权限设为`644`,所有者设为`root:root`。另外,启动时的参数配置要准确,比如`--cluster-name`、`--apiserver-advertise-address`这些参数,我之前犯过错误,导致API Server无法访问。记住,每个节点的`--apiserver-advertise-address`必须指向该节点的IP,不能统一设置。

高可用部署中,负载均衡器的选型要根据实际环境来定。如果是在云平台,比如AWS、阿里云,它们提供的ELB或SLB可以直接用,但本地环境可能需要自己搭建。我之前用Nginx做负载均衡,配置了upstream模块,指向三个API Server的IP,然后用TCP代理来转发请求。在配置过程中,注意要设置`proxy_connect_timeout`和`proxy_read_timeout`,否则连接超时会导致服务异常。还有,必须配置健康检查,比如`health_check`参数,这样能及时剔除故障节点,不影响整体调度。

etcd的高可用部署需要特别注意数据一致性。三个节点的etcd集群必须使用相同的配置文件,否则会引发脑裂。在部署时,要确保每个节点的`--data-dir`路径不同,同时设置`--initial-cluster-state`为`new`,避免旧配置干扰。etcd的存储路径通常在`/var/lib/etcd`,这个目录的磁盘空间必须足够,否则会报错。我之前因为磁盘满了,导致etcd无法写入日志,整个集群就挂了。所以要在`/etc/default/etcd`中设置`ETCD_DATA_DIR`,并监控目录大小。

Kubernetes的高可用还需要考虑API Server的性能。如果集群规模大,单个API Server可能扛不住压力。我在部署时,用`--secure-port`设置为6443,并开启`--max-requests-per-second`和`--max-mutating-requests-per-second`来限制QPS,防止DDoS攻击。另外,建议使用`--etcd-servers`指向etcd集群的IP,而不是单节点,这样能提高API Server的响应速度和容错能力。配置文件里的`--anonymous-auth`要设为`false`,否则会暴露未认证的访问端口。

在高可用集群中,网络策略的配置也至关重要。我之前在跨节点通信时,因为没正确配置CNI插件,导致Service无法正确解析IP。使用Calico或者Flannel时,必须确保所有节点的CNI配置一致。比如在Calico的配置文件中,设置`--ipam-type=kubernetes`,并指定`--conf`路径为`/etc/cni/net.d`。另外,网络插件的版本要和Kubernetes的版本匹配,否则会出现兼容性问题。在部署前,最好先测试一个小集群,确认网络策略是否正常。

高可用部署的另一个关键点是存储后端。etcd默认使用本地存储,但如果高可用集群需要跨节点同步,建议用远程存储,比如Ceph或者GlusterFS。在etcd配置中,可以用`--data-dir`指定存储路径,同时配置`--name`来标识每个节点。在使用远程存储时,需要确保所有节点都能访问,否则会导致数据不一致。我之前用Ceph,发现存储性能不足,后来换成本地SSD,问题才缓解。另外,etcd的备份和恢复策略也要提前规划好,比如通过`etcdctl`工具定期备份。

Kubernetes高可用集群需要考虑节点的自动恢复机制。在Kubeadm的配置文件中,`--node-name`必须设置为实际的主机名,否则节点会无法加入集群。另外,使用`--ignore-preflight-errors`可以绕过某些检查,但必须谨慎,避免隐藏真正的问题。我之前在部署时,因为DNS解析错误,导致节点无法加入,最后通过`kubeadm reset`和重新配置`--dns`参数才解决。同时,建议用`--control-plane`参数来标记Master节点,确保它们保持运行状态。

在高可用场景下,Service的类型选择也很重要。如果使用NodePort,需要确保所有Master节点都有相同的端口映射,否则会出现访问不一致的问题。而ClusterIP类型的Service更适合内部通信,但需要考虑是否需要暴露到集群外。我在部署时,用了`--external-ip`来指定负载均衡器的地址,这样Service就可以自动指向正确的IP。此外,Service的`sessionAffinity`配置也会影响高可用,建议在需要会话保持的场景下启用。

Kubernetes高可用的运维也需要关注节点的健康状态。通过`kubectl get nodes`可以查看节点的状态,如果出现`NotReady`,需要检查`systemd`服务是否正常,尤其是`kubelet`、`kube-proxy`和`docker`服务。如果发现某个节点CPU或内存使用率过高,可以通过`kubectl top nodes`来定位问题。我之前遇到过一个节点CPU突然飙升,检查发现是某个容器占用过高,通过`kubectl describe pod`和`kubectl logs`才找到原因。此外,建议定期检查`kubectl describe scheduler`和`kubectl describe controller-manager`,确保调度和控制组件没有异常。

在高可用部署中,Kubernetes的自动扩展能力也很关键。使用HPA(Horizontal Pod Autoscaler)可以自动调整Pod数量,但需要配置正确的指标。比如在HPA的配置文件中,`--cpu-percent`和`--memory-percent`参数要合理设置,否则会频繁重启Pod。我在实际测试中发现,如果CPU阈值设得太低,会导致Pod不断扩容,浪费资源。所以建议根据业务负载来调整这些值,比如设置为60%或80%。同时,使用`kubectl autoscale`命令来指定自动扩展策略,确保集群能应对突发流量。

Kubernetes高可用需要考虑持久化存储的高可用。如果使用StatefulSet,需要确保后端存储支持副本和故障转移。比如在使用iSCSI时,每个Pod要有独立的存储卷,同时配置`volumeClaimTemplates`来动态分配存储。我之前部署一个数据库StatefulSet,因为没有正确配置存储类,导致数据无法持久化。后来改用Ceph RBD,配置`spec.storage.className`和`spec.volumeMode`,问题才解决。此外,存储的访问策略也要设置正确,比如`ReadWriteMany`支持多节点挂载。

高可用集群的监控系统也必不可少。我在部署时推荐使用Prometheus + Grafana来监控CPU、内存、网络和磁盘使用情况。通过`kubectl apply -f https://github.com/kubernetes-monitoring/deployment/releases/download/manifests/prometheus-ec2.yaml`可以快速部署Prometheus。同时,配置`--logtostderr=true`和`--v=4`来增加日志详细度,方便排查问题。在监控API Server时,可以使用`/metrics`端口,通过`kubectl top apiserver`查看负载情况。如果发现API Server资源不足,可以增加`--max-concurrent-migrations`参数。

Kubernetes高可用部署中,网络策略的配置不能遗漏。比如在使用Calico时,需要配置`--ipam-type`和`--conf`参数,确保IP分配正确。同时,设置`--policy`参数来控制网络隔离,避免Pod之间互相干扰。我之前因为配置错误,导致某些Pod无法访问外部服务,后来通过`kubectl describe pod`和`kubectl get events`才发现问题。此外,在跨集群通信时,要确保使用正确的DNS解析,比如配置`--dns`参数指向内部DNS服务器。

在高可用场景下,Kubernetes的证书管理要格外注意。证书过期会导致API Server无法访问,所以必须设置定期轮换机制。使用`--cert-dir`参数指定证书存放路径,并定期通过`kubeadm certs renew`来更新证书。我之前因为证书过期,导致集群无法连接,后来手动删除旧证书,重新生成后才恢复。此外,建议在证书配置中开启`--server-cert`和`--client-cert`,确保所有节点都能正确认证。

▌ 技术参考
高可用部署的节点调度策略也要考虑。使用`--schedule-node-selector`可以控制Pod调度到特定节点,避免资源浪费。在测试环境中,我曾遇到调度混乱的问题,后来通过`kubectl describe node`和`kubectl get pods -o wide`来定位Pod分布不均的原因。此外,`--max-pods`参数要根据节点资源合理设置,比如在Master节点上设置为5,避免Pod过多影响系统稳定性。在部署时,建议用`--taint`来防止Pod被调度到Master节点,除非确实需要。

Kubernetes的高可用部署需要关注配置文件的版本一致性。在使用Kubeadm时,每个节点的`/etc/kubernetes/manifests`目录下的配置文件必须保持同步,否则会引发版本不一致的问题。我之前因为某个节点的配置文件版本过旧,导致API Server无法启动,后来通过`kubeadm upgrade`命令来统一版本。此外,在启动集群时,`--config`参数要指定正确的配置文件路径,确保所有节点使用相同的参数。

高可用集群的网络策略还涉及到防火墙和安全组的配置。在部署时,必须确保每个节点的端口都对外开放,尤其是6443(API Server)、10250(kubelet)、10251(kube-scheduler)、10252(kube-controller-manager)等端口。我之前因为安全组限制,导致Master节点无法通信,最后通过`iptables`命令检查端口开放状态,才发现是规则配置错误。建议在部署前用`nmap`扫描端口,确保所有节点都能正常通信。

Kubernetes的高可用还需要考虑节点的连接稳定性。在使用`kubeadm join`时,确保所有节点的网络是稳定的,否则会频繁断连。我之前遇到一个节点经常断连,后来发现是交换机配置错误,导致网络波动。在部署时,建议用`--discovery-token-ca-certificate`指定证书路径,并设置`--discovery-token-unsafe-skip-ca-verification`为`true`,避免证书验证失败。另外,`--node-name`参数也要正确,否则节点无法加入集群。

高可用部署的另一个关键点是存储的故障转移能力。如果使用NFS作为存储后端,必须确保NFS服务器支持多节点访问,并配置正确的权限。在部署时,使用`--mount`参数指定存储挂载路径,同时设置`--read-only`和`--mount-propagation`选项。我之前部署时,因为NFS挂载权限不足,导致Pod无法启动。后来通过`chmod`和`chown`命令调整权限,问题才解决。

Kubernetes高可用的网络插件配置也要仔细。比如在使用Calico时,需要在每个节点上运行`calico-node`容器,并配置正确的网络策略。通过`calicoctl`命令可以管理网络策略,确保Pod之间的通信正常。我之前因为没有正确配置`--ipam-type`,导致IP分配异常,后来修改配置文件后才恢复。此外,Calico的`--conf`参数要指定正确的配置文件路径,确保所有节点使用相同的策略。

高可用集群的监控系统还需要集成日志收集工具。比如使用Fluentd和Elasticsearch来收集和分析日志,通过`kubectl apply -f https://github.com/fluent/fluentd-kubernetes-daemonset/blob/master/fluentd-daemonset.yaml`部署Fluentd。日志收集后,可以配置Grafana来展示日志信息,帮助排查问题。我之前因为没有日志收集,导致问题排查困难,后来通过Fluentd和Elasticsearch解决了这个痛点。

在高可用部署中,节点的资源分配要合理。每个Master节点至少需要2核4GB内存,否则会因为资源不足导致API Server崩溃。我之前因为资源分配不当,导致一个节点频繁重启,后来通过`kubectl describe node`查看资源使用情况,调整了`--cpu`和`--memory`参数。建议在部署前用`kubectl top node`检查资源使用情况,确保所有节点都有足够的资源。

Kubernetes高可用的节点隔离策略也要考虑。使用`--taint`参数给Master节点打上`node-role.kubernetes.io/master:NoSchedule`标签,防止普通Pod被调度到Master节点。这能减少Master节点的负载,提高稳定性。我之前因为没有打标签,导致某些Pod占用Master节点资源,影响了API Server的性能。后来通过`kubectl taint`加上标签后,问题才缓解。

高可用部署还需要考虑SSH连接的稳定性。在使用`kubeadm join`时,SSH连接失败会导致节点无法加入。我之前因为SSH密钥配置错误,导致节点无法连接。后来通过`ssh-keygen`生成密钥,并用`--ssh-key`参数指定路径,问题才解决。建议在部署前测试SSH连接,确保所有节点之间可以互相访问。

▌ 技术参考
Kubernetes高可用部署的最后一步是配置负载均衡器。如果使用Nginx,需要在配置文件中设置`upstream`模块,指向三个API Server的IP。同时,配置`proxy_connect_timeout`和`proxy_read_timeout`来避免超时问题。我之前在配置Nginx时,因为没有设置`proxy_ssl_verify`,导致证书验证失败,后来通过添加`proxy_ssl_verify on`解决了问题。此外,负载均衡器的健康检查配置也要正确,比如设置`health_check`参数来隔绝故障节点。

高可用部署的整个流程需要反复测试。在测试环境中,可以通过`kubectl get nodes`和`kubectl get pods`来验证节点是否正常。如果发现某个节点状态异常,需要立即排查,比如检查`systemd`服务状态,确保`kubelet`、`kube-proxy`和`docker`都在运行。我之前因为某个节点的`kubelet`服务崩溃,导致整个集群无法调度,后来通过`systemctl status kubelet`找到了原因,重启服务后问题解决。

在高可用部署中,节点的存储配置不能遗漏。每个节点的`/etc/kubernetes/manifests`目录下要有完整的服务配置文件,比如`kube-apiserver.yaml`、`kube-controller-manager.yaml`和`kube-scheduler.yaml`。这些文件的参数必须一致,否则会导致集群状态不一致。我之前因为一个节点的`--etcd-servers`配置错误,导致API Server无法连接etcd,集群就崩溃了。后来通过`kubectl get configmaps`和`kubectl get secrets`检查配置一致性,问题才解决。

Kubernetes高可用的最后一点是确保所有配置文件的版本一致。每个节点的`/etc/kubernetes/manifests`目录下的配置文件必须同步,否则会引发版本不一致的问题。我之前因为某个节点的配置文件版本过旧,导致API Server启动失败,后来通过`kubeadm upgrade`命令统一版本后才恢复。同时,在部署时,`--config`参数要指定正确的配置文件路径,确保所有节点使用相同的参数。

高可用部署的整个过程需要严格按照步骤执行,不能跳过任何环节。从安装etcd到配置API Server,再到设置负载均衡器,每一步都可能影响到集群的稳定性。我之前因为忽略etcd的存储路径配置,导致数据丢失,后来通过`kubeadm init phase etcd local`重新初始化了etcd。此外,部署完成后,还要检查每个节点的`systemd`服务状态,确保所有组件正常运行。

▌ 技术参考
在部署Kubernetes高可用时,网络策略的配置必须仔细。如果使用Calico,需要在每个节点上运行`calico-node`容器,并配置正确的网络策略。我之前因为没有正确配置`--ipam-type`,导致IP分配异常,后来通过修改配置文件解决了问题。同时,Calico的`--conf`参数要指定正确的配置文件路径,确保所有节点使用相同的策略。

高可用集群的部署还需要考虑节点的连接稳定性。在使用`kubeadm join`时,SSH连接失败会导致节点无法加入。我之前因为SSH密钥配置错误,导致节点无法连接。后来通过`ssh-keygen`生成密钥,并用`--ssh-key`参数指定路径,问题才解决。建议在部署前测试SSH连接,确保所有节点之间可以互相访问。