关于kubernetes:Kubernetes高可用集群部署中一些可以说的

3次阅读

共计 5951 个字符,预计需要花费 15 分钟才能阅读完成。

前文咱们搭建了 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/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 是 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/kubectl
kubeadm completion bash > /etc/bash_completion.d/kubeadm
正文完
 0