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數據直接從這個連接走了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM