Kubernetes Ingress實戰(四):Bare metal環境下Kubernetes Ingress邊緣節點的高可用
1.Kubernetes邊緣節點的單點故障
經過前面幾篇對Ingress的學習,我們已經可以在一個Kubernetes中部署nginx ingress,同時可以將叢集中的兩類服務HTTP和RPC/">gRPC暴露到叢集外部。 本篇將主要關注一下Bare metal環境下Kubernetes Ingress邊緣節點高可用相關的問題。我們的線上環境並沒有使用公有云,因此無法使用各種共有云提供的ingress controller。
在Bare metal環境中Kubernetes叢集,nginx ingress controller負責將叢集外部的流量接入到叢集內。 實際中需要將邊緣路由器或全域性統一接入層的負載均衡器將到達公網ip的外網流量轉發到nginx ingress controller所在Kubernetes節點(這裡成為邊緣節點edge節點)的內網ip上,外部通過域名訪問叢集中以ingress暴露的服務。
Bare metal環境的Ingress的實施往往採用下圖所示的形式:
Kubernetes的Node節點中的Edge節點用於接入叢集外部的流量,nginx ingress controller被部署到edge節點上。通過邊緣路由器,將公網ip上的流量轉到edge節點上。 例如公網ip的80和443埠對應edge節點內網ip的80和443埠。
但是當前的方案中edge節點是存在單點故障的,如果這個edge節點宕機的話,整個Kubernetes叢集將無法對叢集外部提供服務(所有的ingress都將不可用)。
2.高可用的Kubernetes邊緣節點
Kubernetes邊緣節點上部署的nginx ingress controller實際上就是一個負載均衡器。因此可以通過熱備的形式部署多個邊緣節點,多個邊緣節點爭搶一個VIP的形式。 即基於Keepavlied實現邊緣節點的高可用。
如上圖所示,部署了兩個邊緣節點 192.168.61.11
和 192.168.61.12
。邊緣路由器上公網ip對映到內網的VIP 192.168.61.10
上。
3.我們的實踐
Kubernetes有個Contrib的 keepalived-vip" rel="nofollow,noindex" target="_blank">kube-keepalived-vip 專案是專門來做這件事的,在這個專案中keepalived是以容器的形式部署。 但由於我們線上一些沒有部署在Kubernetes的一些服務和中介軟體都是用ansible部署的,這其中已經包括了keepalived的ansible role(包含keepalived+nginx和keepavlied+haproxy)。 所以我們在做Kubernetes邊緣節點的高可用時,直接使用已有的ansible role將keepavlied直接部署在邊緣節點上,而不是執行到容器中。
3.1 測試環境
根據前面的內容,一個Kubernetes叢集分為三種類型的節點,master節點、跑業務負載的node節點、用於將外部流量接入的邊緣節點edge節點。
這裡的測試環境只有兩個節點:
kubectl get node -o wide NAMESTATUSROLESAGEVERSIONINTERNAL-IP node1Readymaster38dv1.11.1192.168.61.11 node2Ready<none>38dv1.11.1192.168.61.12
node1同時作為master、node和edge節點,node2同時作為node和edge節點。
3.2 排程nginx-ingress-controller到邊緣節點
這個測試叢集的nginx ingress是使用helm部署的,這裡調整一下value file ingress-nginx.yaml的內容,externalIPs指定為 192.168.61.10
這個VIP以及所有邊緣節點的內網ip,同時通過nodeAffinity將 nginx-ingress-controller
排程到叢集中所有的邊緣節點,這裡是node1和node2。
controller: replicaCount: 2 service: externalIPs: - 192.168.61.10 - 192.168.61.11 - 192.168.61.12 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node1 - node2
helm upgrade nginx-ingress stable/nginx-ingress \ --namespace ingress-nginx \ --install \ -f ingress-nginx.yaml
3.3 在邊緣節點上安裝keepalived
接下來在所有邊緣節點上安裝keepalived和ipvsadmin。 ipvsadm是IPVS的管理命令,VIP由IPVS建立。
我們使用ansible完成各個邊緣節點上keepalived的部署和配置。 這裡將略過keepalived的安裝過程。
各個邊緣節點上的keepalived.conf配置如下:
! Configuration File for keepalived global_defs { router_id LVS_DEVEL } 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 { 192.168.61.10 } } virtual_server 192.168.61.10 443 { delay_loop 6 lb_algo loadbalance lb_kind DR nat_max 255.255.255.0 persistence_timeout 50 protocol TCP real_server 192.168.61.11 443 { weight 1 TCP_CHECK { connect_timeout 3 } } real_server 192.168.61.12 443 { weight 1 TCP_CHECK { connect_timeout 3 } } }
各個邊緣節點上的keepalvied啟動後,可以在某個邊緣節點上執行下面的命令檢視到該節點獲取到了VIP:
ip addr sh etn0 2: etn0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:7a:a0:d5 brd ff:ff:ff:ff:ff:ff inet 192.168.61.12/24 brd 192.168.61.255 scope global etn0 valid_lft forever preferred_lft forever inet 192.168.61.10/32 scope global etn0 valid_lft forever preferred_lft forever inet6 fe80::1f1d:9638:d8f5:c2a5/64 scope link valid_lft forever preferred_lft forever inet6 fe80::3a95:48aa:a404:4275/64 scope link tentative dadfailed valid_lft forever preferred_lft forever
下面模擬VIP所在邊緣節點宕機,將該節點關機。此時在剩餘邊緣節點上查,確認VIP漂到了剩餘邊緣節點的某個節點上。