kubernetes haproxy+keepalive实现master集群高可用

前言

master的HA,实际是apiserver的HA。Master的其他组件controller-manager、scheduler都是可以通过etcd做选举(--leader-elect),而APIServer设计的就是可扩展性,所以做到APIServer很容易,只要前面加一个负载均衡轮训转发请求即可。下面简单描述下haproxy和keepalive。
注意⚠️便于大家使用,所以先码部署,有兴趣的可以看下后面的原理。

一、实操篇

1. haproxy部署

1.1. 安装haproxy

yum -y install haproxy生产环境可以用二进制包部署

1.2. 修改配置文件

cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg-back
vim /etc/haproxy/haproxy.cfg

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    tcp
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend  main *:16443
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static          if url_static
    default_backend             kube-apiserver

backend static
    balance     roundrobin
    server      static 127.0.0.1:4331 check

backend kube-apiserver
    balance     roundrobin
    server  k8s1-matser1 10.8.4.91:6443 check
    server  k8s1-matser2 10.8.4.92:6443 check
    server  k8s1-matser3 10.8.4.93:6443 check

⚠️注意

  1. defaults 模块中的 mode http 要改为 tcp(或者在下面的 frontend 和 backend 模块中单独定义 mode tcp )如果不改,后续 kubectl get node 会处于 NotReady 状态。
  2. frontend 端口需指定非 6443 端口,要不然其他 master 节点会启动异常(如果 haproxy 单独主机,则可用 6443 端口)
  3. 配置文件可以拷贝其他节点,配置文件保持一样。
1.3.启动haproxy

systemctl start haproxy && systemctl enable haproxy && systemctl status haproxy

2. keepalive部署

2.1. 安装keepalive

yum install -y keepalived

2.2. 修改配置文件

cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf-back
vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id LVS_1
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.8.4.55/24
    }
}

⚠️注意

  1. global_defs 只保留 router_id(每个节点都不同);
  2. 修改 interface(vip绑定的网卡),及 virtual_ipaddress(vip地址及掩码长度);
  3. 删除后面的示例
  4. 其他节点只需修改 state 为 BACKUP,优先级 priority 低于100即可。
2.3. 启动keeplive

systemctl start keepalived && systemctl enable keepalived && systemctl status keepalived

2.4. 查看状态

ip addr show eth0如图
master1-eth0
master2-eth0

可以看到vip只在一台机器上;如果两个机器都有vip,可能是防火墙拦截了vrrp协议。

二、概述篇(作者摘抄整理)

1.haproxy+keepalived实现高可用负载均衡

软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载实现。LVS就是基于Linux操作系统实现的一种软负载,HAProxy就是开源的并且基于第三应用实现的软负载。

HAProxy相比LVS的使用要简单很多,功能方面也很丰富。当前,HAProxy支持两种主要的代理模式:"tcp"也即4层(大多用于邮件服务器、内部协议通信服务器等),和7层(HTTP)。在4层模式 下,HAProxy仅在客户端和服务器之间转发双向流量。7层模式下,HAProxy会分析协议,并且能通过允许、拒绝、交换、增加、修改或者删除请求 (request)或者回应(response)里指定内容来控制协议,这种操作要基于特定规则。

1.1.Haproxy简介

反向代理服务器,支持双机热备支持虚拟主机,但其配置简单,拥有非常不错的服务器健康检查功能,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。自1.3引入了frontend,backend;frontend根据任意 HTTP请求头内容做规则匹配,然后把请求定向到相关的backend.

1.2.keepalived简介

keepalived是一个类似于layer3, 4 & 5交换机制的软件,也就是我们平时说的第3层、第4层和第5层交换。Keepalived的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器。

⚠️类似的HA工具还有heatbeat、drbd等,heatbeat、drbd配置都较为复杂。

1.2.1. keepalived理论工作原理

keepalived可提供vrrp以及health-check功能,可以只用它提供双机浮动的vip(vrrp虚拟路由功能),这样可以简单实现一个双机热备高可用功能。

keepalived是一个类似于layer3, 4 & 5交换机制的软件,也就是我们平时说的第3层、第4层和第5层交换。Keepalived的作用是检测web 服务器的状态。 Layer3,4&5工作在IP/TCP协议栈的IP层,TCP层,及应用层,原理分别如下:

  • Layer3:Keepalived使用Layer3的方式工作式时,Keepalived会定期向服务器群中的服务器发送一个ICMP的数据包(既我们平时用的Ping程序),如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除,这种情况的典型例子是某台服务器被非法关机。Layer3的方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。
  • Layer4:如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP端口的状态来决定服务器工作正常与否。如web server的服务端口一般是80,如果Keepalived检测到80端口没有启动,则Keepalived将把这台服务器从服务器群中剔除。
  • Layer5:Layer5就是工作在具体的应用层了,比Layer3,Layer4要复杂一点,在网络上占用的带宽也要大一些。Keepalived将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则Keepalived将把服务器从服务器群中剔除。

vip即虚拟ip,是附在主机网卡上的,即对主机网卡进行虚拟,此IP仍然是占用了此网段的某个IP。

1.2.2.tcp层的keepalive原理(本文所用)

tcp的keepalive是侧重在保持客户端和服务端的连接,一方会不定期发送心跳包给另一方,当一方端掉的时候,没有断掉的定时发送几次心跳包,如果间隔发送几次,对方都返回的是RST,而不是ACK,那么就释放当前链接。设想一下,如果tcp层没有keepalive的机制,一旦一方断开连接却没有发送FIN给另外一方的话,那么另外一方会一直以为这个连接还是存活的,几天,几月。那么这对服务器资源的影响是很大的。

tcp的keepalive就是为了检测链接的可用性。主要调节的参数有三个:

  • tcp_keepalive_time // 距离上次传送数据多少时间未收到判断为开始检测
  • tcp_keepalive_intvl // 检测开始每多少时间发送心跳包
  • tcp_keepalive_probes // 发送几次心跳包对方未响应则close连接
    基本上的流程:
  1. 在客户端和服务端进行完三次握手之后,客户端和服务端都处在ESTABLISH状态,这个时候进行正常的PSH和ACK交互,但是一旦一方服务中断了,另一方在距离上次PSH时间tcp_keepalive_time发现对方未发送数据,则开始心跳检测。
  2. 心跳检测实际就是发送一个PSH的空心跳包,这里说的空心跳包就是包的数据为空,但是TCP包的头部的数据和标识和正常包一样。如果这个包获取到的是RST返回的话,下面就会继续每隔tcp_keepalive_intval的时长发送一个空心跳包,如果tcp_keepalive_probes次心跳包对方都是返回RST而不是ACK,则心跳发起方就判断这个连接已经失效,主动CLOST这个连接。
    这三个参数可以每个TCP连接都不同,使用tcp设置变量的函数可以设置当前tcp连接的这三个对应的值。
int setsockopt(int s, int level, int optname,
               const void *optval, socklen_t optlen)

⚠️ http层的keepalive原理

http的keep-alive一般我们都会带上中间的横杠,普通的http连接是客户端连接上服务端,然后结束请求后,由客户端或者服务端进行http连接的关闭。下次再发送请求的时候,客户端再发起一个连接,传送数据,关闭连接。这么个流程反复。但是一旦客户端发送connection:keep-alive头给服务端,且服务端也接受这个keep-alive的话,两边对上暗号,这个连接就可以复用了,一个http处理完之后,另外一个http数据直接从这个连接走了。

原文地址:https://www.cnblogs.com/keep-live/p/11543871.html