前文咱们搭建了 3Master 节点 4Node 节点的高可用集群,本文讨论一下过程中的总结。
高可用策略
前文说了 Kubernetes 集群高可用的关键在于 Master 节点的高可用,官网也给出了 2 种高可用拓扑构造:
-
Stacked etcd topology(重叠 etcd)
该计划中,所有 Master 节点都部署 kube-apiserver,kube-controller-manager,kube-scheduler,以及 etcd 等组件;kube-apiserver 均与本地的 etcd 进行通信,etcd 在三个节点间同步数据
-
External etcd topology(内部 etcd)
该计划中,所有 Master 节点都部署 kube-apiserver,kube-controller-manager,kube-scheduler 组件,而 etcd 分布式数据存储集群独立运行。这种拓扑构造解耦了 Master 节点组件和 etcd。
vcontrol plane node 即 Master 节点
高可用计划剖析
通过官网给的拓扑图,有 2 个要害的中央:
- etcd
- load balancer
也就是说,只有实现上述两者的高可用,整个 Kubernetes 集群即达到了高可用的目标。
etcd 高可用
Kubernetes 选用 etcd 作为它的后端数据存储仓库也正是看重了其应用分布式架构,没有单点故障的个性。尽管单节点的 etcd 也能够失常运行,然而举荐的部署计划均是采纳 3 个或者 5 个节点组成 etcd 集群,供 Kubernetes 应用。
etcd 的高可用计划是官网 2 种拓扑构造中最显著的差别,区别就是 etcd 的地位不同。官网对于 2 种 etcd 的计划也做了比拟,我总结如下:
-
重叠形式
- 所需硬件资源少
- 部署简略、利于治理
- 横向扩大容易
- 毛病在于一台宿主机挂了,Master 节点和 etcd 就少了一套,会大大降低集群冗余度和健壮性。
-
内部形式
- Master 节点和 etcd 解耦,Master 节点挂了后不影响 etcd,集群健壮性加强
- 毛病是硬件资源简直 2 倍于重叠计划,并且运维复杂度会变高。
不论从我集体角度还是企业角度,我毫不犹豫抉择重叠形式,横向扩大的便捷性以及对于硬件的需要这 2 点理由就足够了。另外在收集材料的时候还发现了一篇文章 -Scaling Kubernetes to 2,500 Nodes,外面实践证明,etcd 挂载本地 ssd 的形式会大幅提高 超大规模(节点大于 2000)集群性能。
除了上述 2 种形式之外,在网上冲浪时还发现了一篇文章提到另一种形式:
-
CoreOS 提出的 self-hosted etcd 计划
将本应在底层为 Kubernetes 提供服务的 etcd 运行在 Kubernetes 之上。实现 Kubernetes 对本身依赖组件的治理。在这一模式下的 etcd 集群能够间接应用 etcd-operator 来自动化运维,最合乎 Kubernetes 的应用习惯。
当然,这种形式材料并不多,也没找到具体的实际形式,并且在官网文档中多带有 实验性
的前缀,并且官网文档如下阐明:
- The self-hosted portion of the control plane does not include etcd, which still runs as a static Pod.
也不晓得是已经版本中反对过起初勾销还是怎么的,在此不做深究吧,只是提一句题外话。所有还是以官网文档的两种形式为准。
kube-apiserver 高可用
在官网的拓扑图中,除了 etcd 以外很容易疏忽 load balancer
这个节点。kube-apiserver
节点通过前置负载均衡器 load balancer
实现高可用,然而目前尚没有官网的举荐计划。罕用的思路或者计划大抵演绎有以下几种:
-
内部负载均衡器
不论是应用私有云提供的负载均衡器服务或是在公有云中应用 LVS 或者 HaProxy 自建负载均衡器都能够归到这一类。负载均衡器是十分成熟的计划,如何保障负载均衡器的高可用,则是抉择这一计划须要思考的新问题。
目前网上大部分材料都是通过
HAproxy
实现kube-apiserver
的高可用并且通过Keepalived
形式确保 HAproxy 本身的高可用,前文咱们应用的就是这种形式,刚入门随大流总没有错的。 -
网络层做负载平衡
比方在 Master 节点上用 BGP 做 ECMP,或者在 Node 节点上用 iptables 做 NAT 都能够实现。采纳这一计划不须要额定的内部服务,然而对网络配置有肯定的要求。
-
在 Node 节点上应用反向代理对多个 Master 做负载平衡
这一计划同样不须要依赖内部的组件,然而当 Master 节点有增减时,如何动静配置 Node 节点上的负载均衡器成为了另外一个须要解决的问题。
目前除了本人用的形式外,对于其余形式还需留待后续钻研和尝试。
kube-controller-manager 与 kube-scheduler 高可用
这两项服务是 Master 节点的组件,他们的高可用绝对容易,仅须要运行多份实例即可。Kubernetes 本身通过 leader election
机制保障以后只有一个正本是处于运行状态。
至于 leader 选举的机制,简略来说是:多个 kube-controller-manager 与 kube-scheduler 的正本对 endpoint 锁资源做抢占,谁能抢到并将本人的信息写入 endpoint 的 annotation 中,谁就成为了 leader,leader 须要在可配置的一个间隔时间内更新音讯,其余节点也能看见以后的 leader 和过期工夫;当过期工夫到并且 leader 没有更新后,其余正本会尝试去获取锁,去竞争 leader,直到本人成为 leader。
对于 Kubernetes 的高可用计划就总结这些。
ipvs VS iptables
上文部署过程中,我应用了 ipvs 的形式代替了默认的 iptables,起初呢只是抱着不明觉厉,自定义的必定要比默认的强哈的想法,事实上呢还是要本人调研比照下才行。
从前文集群配置文件 kubeadm.yaml 中能够看到 ipvs 配置是针对 kube-proxy 组件的。kube-proxy 是 Kubernetes 中的要害组件。他的角色就是在服务(仅限 ClusterIP 和 NodePort 形式)和其后端 Pod 之间进行负载平衡。kube-proxy 有三种运行模式,每种都有不同的实现技术:userspace、iptables 或者 IPVS。userspace 模式十分古老、迟缓,曾经不举荐应用。
-
iptables
iptables 是一个 Linux 内核性能,是一个高效的防火墙,并提供了大量的数据包解决和过滤方面的能力。它能够在外围数据包解决管线上用 Hook 挂接一系列的规定。iptables 模式中 kube-proxy 在
NAT pre-routing
Hook 中实现它的 NAT 和负载平衡性能。这种办法简略无效,依赖于成熟的内核性能,并且可能和其它跟 iptables 合作的利用(例如 Calico)融洽相处。然而 kube-proxy 的用法是一种 O(n) 算法,其中的 n 随集群规模同步增长,这里的集群规模,更明确的说就是服务和后端 Pod 的数量。
-
ipvs
IPVS 是一个用于负载平衡的 Linux 内核性能。IPVS 模式下,kube-proxy 应用 IPVS 负载平衡代替了 iptable。这种模式同样无效,IPVS 的设计就是用来为大量服务进行负载平衡的,它有一套优化过的 API,应用优化的查找算法,而不是简略的从列表中查找规定。
这样一来,kube-proxy 在 IPVS 模式下,其连贯过程的复杂度为 O(1)。换句话说,少数状况下,他的连贯解决效率是和集群规模无关的。
另外作为一个独立的负载均衡器,IPVS 蕴含了多种不同的负载平衡算法,例如轮询、最短期望提早、起码连贯以及各种哈希办法等。而 iptables 就只有一种随机平等的抉择算法。
IPVS 的一个潜在毛病就是,IPVS 解决数据包的门路和通常状况下 iptables 过滤器的门路是不同的。如果打算在有其余程序应用 iptables 的环境中应用 IPVS,须要进行一些钻研,看看他们是否可能协调工作。(Calico 曾经和 IPVS kube-proxy 兼容)
看完概念还是不明觉厉,这里我贴出一篇文章供大家理解一下 kube-proxy 模式比照:iptables 还是 IPVS?这是一篇译文,原文地址 Comparing kube-proxy modes: iptables or IPVS?,感激二位作者,这篇文章具体比照了两种模式的优劣。我间接贴出论断:
在超过 1000 服务的规模下,kube-proxy 的 IPVS 模式会有更好的性能体现。尽管可能有多种不同状况,然而通常来说,让微服务应用长久连贯、运行古代内核,也能获得较好的成果。如果运行的内核较旧,或者无奈应用长久连贯,那么 IPVS 模式可能是个更好的抉择。
抛开性能问题不谈,IPVS 模式还有个益处就是具备更多的负载平衡算法可供选择。
如果你还不确定 IPVS 是否适合,那就持续应用 iptables 模式好了。这种传统模式有大量的生产案例撑持,他是一个不完满的缺省选项。
我本人宛转的总结就是:以一般企业的业务规模,两者没有差别。
对于初始化集群时 ipvs 配置问题
在应用 kubeadm 初始化集群时,开启 ipvs 配置如下,这里我着实遇到一个小坑:
# 谬误配置
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true # 这个配置谬误谬误谬误!!!依照网上材料这样配,kubeproxy 组件会启动失败并始终重试!!mode: ipvs
# 正确配置
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
曾经搭建好的集群中开启 ipvs
批改 kube-proxy 配置
kubectl edit configmap kube-proxy -n kube-system
minSyncPeriod: 0s
scheduler: ""
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 127.0.0.1:10249
mode: "ipvs" # 批改此处
nodePortAddresses: null
删除所有 kube-proxy 的 pod
kubectl delete pod xxx -n kube-system
校验
kubectl logs kube-proxy-xxx -n kube-system
日志呈现 Using ipvs Proxier
即可
查看 ipvs 代理规定
kubectl get svc --all-namespaces
#能够看到 service 对应的很多规定
ipvsadm -ln
乏味的景象 -kubelet 的默认 cgroup driver
在初始化过程中呈现谬误:
failed to create kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"
后面咱们在部署 Docker 时设置了 cgroupfs driver
为 systemd,因为 Kubernetes 官网这么倡议,你这么倡议就倡议吧,为什么本人还默认 cngroupfs?所以在理论部署时,Docker 和 kubelet 都须要设置为systemd
。
Keepalived 配置文件须知
检测脚本
vrrp_script chk_haproxy {script "/bin/bash -c'if [[ $(netstat -nlp | grep 9443) ]]; then exit 0; else exit 1; fi'" # haproxy 检测脚本,这里须要依据本人理论状况判断
interval 2 # 每 2 秒执行一次检测
weight 11 # 权重变动
}
检测衰弱的脚本须要依据理论状况判断,如果 Haproxy 是二进制形式装置,须要判断过程。如果是 docker 形式装置,光判断过程就有效了,须要判断 Haproxy 的端口号是否有监听存在。
当然,我感觉最完满的形式应该是判断 apiserver 的状态,这点还须要后续再欠缺,先留个问题待处理。
配置文件留神点
-
interface
默认的 Keepalived 文件
interface
是 eth0interface eth0
此处要依据本人的理论状况,否则 Keepalived 会失败
-
unicast_peer
首先我的三台 Master 节点是跨网段的,keepalived 默认的形式是组播,并不反对跨网段,所以我刚开始采纳默认配置启动时呈现了不同网段的 2 个 Master,解决办法就是改成单播模式:
unicast_peer { 10.128.2.53 10.128.2.52 }
-
nopreempt 抢占 / 非抢占
抢占模式是当 master 从故障中复原后,会将 VIP 从 BACKUP 中抢过来,非抢占模式是 master 复原后不抢占 backup 降级为 master 后的 vip。
vrrp_instance myland_slb { ... state MASTER # 状态 nopreempt #不抢占示意 priority 90 # 优先级(0~255)... }
Kubectl get cs 废除
在第一篇疾速搭建集群时候遇到以上问题,并也给出了解决办法:查看配置文件 /etc/kubernetes/manifests/kube-scheduler.yaml
与/etc/kubernetes/manifests/kube-controller-manager.yaml
并将两个配置文件的配置项 - --port=0
均正文掉。
本次部署也依照此办法打消了谬误,然而版本升级过后配置文件又恢复原状,这显著不合乎常理,阐明官网并不认同批改配置文件。于是乎查找材料,发现自 1.19 版本后 kubectl get cs
已弃用,减少port=0
是为了合乎 CIS kubernetes 平安白皮书要求而增加。不举荐开启此 http 端口。
参考文章:
#553
#1998
间接查看相干组件 pod 运行状态即可
kubectl get po -n kube-system
配置主动补全命令
所有 master 节点执行
# 装置 bash 主动补全插件
yum install bash-completion -y
设置 kubectl 与 kubeadm 命令补全,下次 login 失效
kubectl completion bash >/etc/bash_completion.d/kubectl
kubeadm completion bash > /etc/bash_completion.d/kubeadm