Kubernetes安装keepalived和haproxy

半兽人 发表于: 2022-08-15   最后更新时间: 2022-08-15 20:06:10  
{{totalSubscript}} 订阅, 1,345 游览

对于从虚拟IP提供负载均衡,keepalived和haproxy的组合已经存在了很长时间,可以说是众所周知、久经考验。

  • keepalived提供了一个由可配置的健康检查管理的虚拟IP。由于虚拟IP的实施方式,协商虚拟IP的所有主机必须在同一个IP子网中。

  • haproxy服务可以配置为简单的基于流的负载平衡,从而允许TLS终止由其后面的API服务器实例处理。

这种组合既可以作为操作系统上的服务运行,也可以在master节点上作为静态Pods运行。两种情况下的配置是相同的。

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 3
  weight -2
  fall 10
  rise 2
}

vrrp_instance VI_1 {
    state ${STATE}
    interface ${INTERFACE}
    virtual_router_id ${ROUTER_ID}
    priority ${PRIORITY}
    authentication {
        auth_type PASS
        auth_pass ${AUTH_PASS}
    }
    virtual_ipaddress {
        ${APISERVER_VIP}
    }
    track_script {
        check_apiserver
    }
}

bash变量样式中有一些占位符需要填写:

  • ${STATE}设置一个主机是MASTER,其他主机是BACKUP,因此虚拟IP最初将分配给MASTER
  • ${INTERFACE}是参与协商虚拟IP的网络接口,例如eth0
  • ${ROUTER_ID}对于所有keepalived集群主机来说,应该是相同的,同时在同一子网的所有集群中是唯一的。许多发行版将其值预先配置为51
  • ${PRIORITY} master上的优先级应高于backups。因此,101100就足够了。
  • ${AUTH_PASS} 对所有keepalived集群主机而言,应该是相同的,例如42
  • ${APISERVER_VIP}keepalived集群主机之间协商的虚拟IP地址。

上面的 keepalived 配置使用了一个健康检查脚本/etc/keepalived/check_apiserver.sh,负责确保在持有虚拟IP的节点上,API服务器是可用的。这个脚本可以是这样的。

#!/bin/sh

errorExit() {
    echo "*** $*" 1>&2
    exit 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}; then
    curl --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发行版可能会把它们放在其他地方。以下配置已经成功地用于haproxy2.1.4版本。

# /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log /dev/log local0
    log /dev/log local1 notice
    daemon

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 1
    timeout http-request    10s
    timeout queue           20s
    timeout connect         5s
    timeout client          20s
    timeout server          20s
    timeout http-keep-alive 10s
    timeout check           10s

#---------------------------------------------------------------------
# apiserver frontend which proxys to the masters
#---------------------------------------------------------------------
frontend apiserver
    bind *:${APISERVER_DEST_PORT}
    mode tcp
    option tcplog
    default_backend apiserver

#---------------------------------------------------------------------
# round robin balancing for apiserver
#---------------------------------------------------------------------
backend apiserver
    option httpchk GET /healthz
    http-check expect status 200
    mode tcp
    option ssl-hello-chk
    balance     roundrobin
        server ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT} check
        # [...]

同样,在bash变量样式中有一些占位符需要替换:

  • ${APISERVER_DEST_PORT} Kubernetes与API服务器对话的端口。
  • ${APISERVER_SRC_PORT} API服务器实例使用的端口。
  • ${HOST1_ID}第一个负载均衡的API服务器主机的符号名称。
  • ${HOST1_ADDRESS}第一个负载均衡API服务器主机的可解析地址(DNS名、IP地址)。
  • 额外的server行,每一个负载平衡的API服务器主机。

方式1:在操作系统上运行服务

为了在操作系统上运行这两个服务,可以使用各自发行版的包管理器来安装。如果它们将在不属于Kubernetes集群的专用主机上运行,这可能是有意义的(因为可以在k8s内运行)。

安装好上述配置后,就可以启用和启动服务了。在基于RedHat的最新系统中,将使用systemd来实现。

# systemctl enable haproxy --now
# systemctl enable keepalived --now

有了服务,现在可以使用kubeadm init来启动Kubernetes集群了。

方式2:以静态 pods 运行服务

如果 keepalivedhaproxy 将在控制平面节点上运行,它们可以被配置为静态pods运行。这里需要做的就是在引导集群之前,将各自的清单文件放在/etc/kubernetes/manifests目录中。在引导过程中,kubelet会将这些进程带上来,这样集群在启动时就可以使用它们。这是一个优雅的解决方案,特别是与堆栈控制平面和etcd节点下描述的设置。

对于这个设置,需要在/etc/kubernetes/manifests中创建两个清单文件(先创建目录)。

keepalived的清单, /etc/kubernetes/manifests/keepalived.yaml:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  name: keepalived
  namespace: kube-system
spec:
  containers:
  - image: osixia/keepalived:2.0.17
    name: keepalived
    resources: {}
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
        - NET_BROADCAST
        - NET_RAW
    volumeMounts:
    - mountPath: /usr/local/etc/keepalived/keepalived.conf
      name: config
    - mountPath: /etc/keepalived/check_apiserver.sh
      name: check
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/keepalived/keepalived.conf
    name: config
  - hostPath:
      path: /etc/keepalived/check_apiserver.sh
    name: check
status: {}

haproxy的清单, /etc/kubernetes/manifests/haproxy.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: haproxy
  namespace: kube-system
spec:
  containers:
  - image: haproxy:2.1.4
    name: haproxy
    livenessProbe:
      failureThreshold: 8
      httpGet:
        host: localhost
        path: /healthz
        port: ${APISERVER_DEST_PORT}
        scheme: HTTPS
    volumeMounts:
    - mountPath: /usr/local/etc/haproxy/haproxy.cfg
      name: haproxyconf
      readOnly: true
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/haproxy/haproxy.cfg
      type: FileOrCreate
    name: haproxyconf
status: {}

请注意,这里同样需要填写一个占位符。${APISERVER_DEST_PORT}需要与/etc/haproxy/haproxy.cfg中的值相同(见上文)。

这个组合已经成功地用于例子中使用的版本。其他版本可能也可以使用,或者需要修改配置文件。

验证

可以通过nc命令查看负载是否生效:

nc -v 192.168.0.40 6443
更新于 2022-08-15
在线,1小时前登录

查看kubernetes更多相关的文章或提一个关于kubernetes的问题,也可以与我们一起分享文章