前文咱们搭建了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的计划也做了比拟,我总结如下:

  • 重叠形式

    1. 所需硬件资源少
    2. 部署简略、利于治理
    3. 横向扩大容易
    4. 毛病在于一台宿主机挂了,Master节点和etcd就少了一套,会大大降低集群冗余度和健壮性。
  • 内部形式

    1. Master节点和etcd解耦,Master节点挂了后不影响etcd,集群健壮性加强
    2. 毛病是硬件资源简直2倍于重叠计划,并且运维复杂度会变高。

不论从我集体角度还是企业角度,我毫不犹豫抉择重叠形式,横向扩大的便捷性以及对于硬件的需要这2点理由就足够了。另外在收集材料的时候还发现了一篇文章-Scaling Kubernetes to 2,500 Nodes,外面实践证明,etcd挂载本地ssd的形式会大幅提高超大规模(节点大于2000)集群性能。

除了上述2种形式之外,在网上冲浪时还发现了一篇文章提到另一种形式:

  • CoreOS提出的self-hosted etcd计划

    将本应在底层为Kubernetes提供服务的etcd运行在Kubernetes之上。实现Kubernetes对本身依赖组件的治理。在这一模式下的etcd集群能够间接应用etcd-operator来自动化运维,最合乎Kubernetes的应用习惯。

当然,这种形式材料并不多,也没找到具体的实际形式,并且在官网文档中多带有实验性的前缀,并且官网文档如下阐明:

  1. 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 有三种运行模式,每种都有不同的实现技术:userspaceiptables 或者 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/v1alpha1kind: KubeProxyConfigurationfeatureGates:  SupportIPVSProxyMode: true  # 这个配置谬误谬误谬误!!!依照网上材料这样配,kubeproxy组件会启动失败并始终重试!!mode: ipvs# 正确配置apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationmode: 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是eth0

    interface 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/kubectlkubeadm completion bash > /etc/bash_completion.d/kubeadm