Kubernetes K8s从入门到精通系列之十三:软件负载平衡选项
- 一、软件负载平衡选项
- 二、keepalived and haproxy
- 三、keepalived配置
- 四、haproxy配置
- 五、选项 1:在操作系统上运行服务
- 六、选项 2:将服务作为静态 Pod 运行
一、软件负载平衡选项
当设置具有多个控制平面的集群时,可以通过将 API Server 实例置于负载均衡器后面并在运行 kubeadm init 以便新集群使用它时使用 --control-plane-endpoint 选项来实现更高的可用性。
当然,负载均衡器本身也应该具有高可用性。这通常是通过向负载均衡器添加冗余来实现的。为此,需要建立一个管理虚拟 IP 的主机集群,每个主机都运行一个负载均衡器实例,以便始终使用当前持有 vIP 的主机上的负载均衡器,而其他主机则处于备用状态。
在某些环境中,例如在具有专用负载平衡组件(例如由某些云提供商提供)的数据中心中,此功能可能已经可用。如果不是,可以使用用户管理的负载平衡。在这种情况下,在引导集群之前需要进行一些准备。
由于这不是 Kubernetes 或 kubeadm 的一部分,因此必须单独处理。在以下部分中,我们给出了对某些人有效的示例,当然还有可能有数十种其他可能的配置。
二、keepalived and haproxy
为了从虚拟 IP 提供负载平衡,keepalived 和 haproxy 的组合已经存在很长时间了,并且可以被认为是众所周知且经过充分测试的:
- keepalived 服务提供由可配置的健康检查管理的虚拟 IP。由于虚拟 IP 的实现方式,协商虚拟 IP 的所有主机都需要位于同一 IP 子网中。
- haproxy 服务可以配置为简单的基于流的负载平衡,从而允许 TLS 终止由其背后的 API 服务器实例处理。
此组合可以作为操作系统上的服务运行,也可以作为控制平面主机上的静态 Pod 运行。两种情况下的服务配置是相同的。
三、keepalived配置
keepalived 配置由两个文件组成:服务配置文件和健康检查脚本,该脚本将定期调用以验证持有虚拟 IP 的节点是否仍在运行。
假定这些文件位于 /etc/keepalived 目录中。但请注意,某些 Linux 发行版可能会将它们保留在其他地方。以下配置已成功用于 keepalived 版本 2.0.17:
! /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {router_id LVS_DEVEL
}
vrrp_script check_apiserver {script "/etc/keepalived/check_apiserver.sh"interval 3weight -2fall 10rise 2
}vrrp_instance VI_1 {state ${STATE}interface ${INTERFACE}virtual_router_id ${ROUTER_ID}priority ${PRIORITY}authentication {auth_type PASSauth_pass ${AUTH_PASS}}virtual_ipaddress {${APISERVER_VIP}}track_script {check_apiserver}
}
bash 变量样式中有一些占位符需要填写:
- ${STATE} 对于一台主机来说是 MASTER,对于所有其他主机来说是 BACKUP,因此虚拟 IP 最初将分配给 MASTER。
- ${INTERFACE} 是参与虚拟IP协商的网络接口,例如eth0。
- 对于所有 keepalived 集群主机,${ROUTER_ID} 应该相同,但在同一子网中的所有集群中是唯一的。许多发行版将其值预先配置为 51。
- 控制平面节点上的 ${PRIORITY} 应高于备份节点上的 ${PRIORITY}。因此 101 和 100 分别就足够了。
- 对于所有 keepalived 集群主机,${AUTH_PASS} 应该相同,例如42
- ${APISERVER_VIP} 是 keepalived 集群主机之间协商的虚拟 IP 地址。
上面的 keepalived 配置使用健康检查脚本 /etc/keepalived/check_apiserver.sh 负责确保在持有虚拟 IP 的节点上 API Server 可用。该脚本可能如下所示:
#!/bin/sherrorExit() {echo "*** $*" 1>&2exit 1
}curl --silent --max-time 2 --insecure https://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://localhost:${APISERVER_DEST_PORT}/"
if ip addr | grep -q ${APISERVER_VIP}; thencurl --silent --max-time 2 --insecure https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/"
fi
bash 变量样式中有一些占位符需要填写:
- ${APISERVER_VIP} 是 keepalived 集群主机之间协商的虚拟 IP 地址。
- ${APISERVER_DEST_PORT} Kubernetes 将通过其与 API 服务器通信的端口。
四、haproxy配置
haproxy 配置由一个文件组成:服务配置文件,假定驻留在 /etc/haproxy 目录中。但请注意,某些 Linux 发行版可能会将它们保留在其他地方。以下配置已成功用于 haproxy 版本 2.1.4:
# /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
globallog /dev/log local0log /dev/log local1 noticedaemon#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaultsmode httplog globaloption httplogoption dontlognulloption http-server-closeoption forwardfor except 127.0.0.0/8option redispatchretries 1timeout http-request 10stimeout queue 20stimeout connect 5stimeout client 20stimeout server 20stimeout http-keep-alive 10stimeout check 10s#---------------------------------------------------------------------
# apiserver frontend which proxys to the control plane nodes
#---------------------------------------------------------------------
frontend apiserverbind *:${APISERVER_DEST_PORT}mode tcpoption tcplogdefault_backend apiserver#---------------------------------------------------------------------
# round robin balancing for apiserver
#---------------------------------------------------------------------
backend apiserveroption httpchk GET /healthzhttp-check expect status 200mode tcpoption ssl-hello-chkbalance roundrobinserver ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT} check# [...]
同样,bash 变量样式中有一些占位符可以扩展:
- ${APISERVER_DEST_PORT} Kubernetes 将通过其与 API 服务器通信的端口。
- ${APISERVER_SRC_PORT} API Server 实例使用的端口
- ${HOST1_ID} 第一个负载平衡 API Server 主机的符号名称
- ${HOST1_ADDRESS} 第一个负载平衡 API Server 主机的可解析地址(DNS 名称、IP 地址)
- 额外的服务器线路,每个负载平衡的 API 服务器主机各一条
五、选项 1:在操作系统上运行服务
为了在操作系统上运行这两个服务,可以使用各自发行版的包管理器来安装软件。如果它们将在不属于 Kubernetes 集群的专用主机上运行,那么这是有意义的。
现在安装了上述配置,可以启用并启动服务。在最近的基于 RedHat 的系统上,systemd 将用于此目的:
# systemctl enable haproxy --now
# systemctl enable keepalived --now
服务启动后,现在可以使用 kubeadm init 引导 Kubernetes集群。
六、选项 2:将服务作为静态 Pod 运行
如果 keepalived 和 haproxy 将在控制平面节点上运行,则可以将它们配置为作为静态 Pod 运行。这里所需要做的就是在引导集群之前将相应的清单文件放置在 /etc/kubernetes/manifests 目录中。在引导过程中,kubelet 会启动进程,以便集群在启动时可以使用它们。这是一个优雅的解决方案,特别是使用堆叠控制平面和 etcd 节点中描述的设置。
对于此设置,需要在 /etc/kubernetes/manifests 中创建两个清单文件(首先创建目录)。
keepalived 的清单 /etc/kubernetes/manifests/keepalived.yaml:
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nullname: keepalivednamespace: kube-system
spec:containers:- image: osixia/keepalived:2.0.17name: keepalivedresources: {}securityContext:capabilities:add:- NET_ADMIN- NET_BROADCAST- NET_RAWvolumeMounts:- mountPath: /usr/local/etc/keepalived/keepalived.confname: config- mountPath: /etc/keepalived/check_apiserver.shname: checkhostNetwork: truevolumes:- hostPath:path: /etc/keepalived/keepalived.confname: config- hostPath:path: /etc/keepalived/check_apiserver.shname: check
status: {}
haproxy 的清单 /etc/kubernetes/manifests/haproxy.yaml:
apiVersion: v1
kind: Pod
metadata:name: haproxynamespace: kube-system
spec:containers:- image: haproxy:2.1.4name: haproxylivenessProbe:failureThreshold: 8httpGet:host: localhostpath: /healthzport: ${APISERVER_DEST_PORT}scheme: HTTPSvolumeMounts:- mountPath: /usr/local/etc/haproxy/haproxy.cfgname: haproxyconfreadOnly: truehostNetwork: truevolumes:- hostPath:path: /etc/haproxy/haproxy.cfgtype: FileOrCreatename: haproxyconf
status: {}
请注意,这里需要再次填写占位符:${APISERVER_DEST_PORT} 需要保持与 /etc/haproxy/haproxy.cfg 中相同的值(见上文)。
该组合已成功地与示例中使用的版本一起使用。其他版本可能也可以工作,或者可能需要更改配置文件。
服务启动后,现在可以使用 kubeadm init 引导 Kubernetes 集群。