搭建高可用K8S集群
說明:高可用的K8S集群,需要用到虛擬IP漂移技術。虛擬IP跟多台主機的IP相映射,外界只需要訪問虛擬IP,就可以訪問到主機,而無需關注具體訪問的是哪一台主機。虛擬IP技術,可參考 https://www.cnblogs.com/fasionchan/p/10417177.html 和 https://www.cnblogs.com/myseries/p/11409895.html。本文重點在實操。
一、主機和網絡規划
K8S高可用集群,需要用到etcd存儲,etcd是一個采用了raft一致性算法的分布式鍵值存儲系統。因此至少需要3台主機作為master。主機的 存活數 和 失敗容忍 可參考 https://www.cnblogs.com/ants/p/11489598.html#_label0 。我的主機和網絡規划如下:
ens33 k8s-master01 172.20.111.73
ens33 k8s-master02 172.20.111.80
ens33 k8s-master03 172.20.111.86
k8s-vip 172.20.111.22
其中,虛擬IP是沒有被其他主機使用的IP。這台IP不會綁定到任何主機上。
二、安裝和配置 keepalived
需要在三台 k8s master主機上操作。
1. 安裝keepalived
keepalived 是實現IP虛擬漂移的關鍵技術。需要在三台K8S master主機上安裝。
yum install -y keepalived
2.配置keepalived 虛擬漂移
三台K8S master主機,都需要進行配置。
cat <<EOF > /etc/keepalived/keepalived.conf
! /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
script_user root
enable_script_security
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 BACKUP
interface eth0
virtual_router_id 51
priority 50
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
172.20.111.22
}
track_script {
check_apiserver
}
}
EOF
在上面的文件中替換自己相應的內容:
STATE
如果是主節點 則為MASTER
其他則為 BACKUP
。我這里選擇k8s-master01
為MASTER
;k8s-master02
、k8s-master03
為BACKUP
;
INTERFACE
是網絡接口,即服務器網卡的,我的服務器均為eth33
;
ROUTER_ID
這個值只要在keepalived
集群中保持一致即可,我使用的是默認值51;
PRIORITY
優先級,在master
上比在備份服務器上高就行了。我的master
設為100,備份服務50;
AUTH_PASS
這個值只要在keepalived
集群中保持一致即可;123456
APISERVER_VIP
就是VIP
的地址,我的為:172.20.111.22。
3.配置keepalived 健康檢查
三台k8s master主機都要配置。
vi /etc/keepalived/check_apiserver.sh
### 添加內容
#!/bin/sh
errorExit() {
echo "*** $*" 1>&2
exit 1
}
curl --silent --max-time 2 --insecure https://localhost:16443/ -o /dev/null || errorExit "Error GET https://localhost:16443/"
if ip addr | grep -q 172.20.111.22; then
curl --silent --max-time 2 --insecure https://172.20.111.22:16443/ -o /dev/null || errorExit "Error GET https://172.20.111.22:16443/"
fi
APISERVER_VIP
就是VIP
的地址,172.20.111.22;
APISERVER_DEST_PORT
這個是和apiserver
交互的端口號,其實就是HAProxy
綁定的端口號,因為HAProxy
和k8s一起部署,這里做一個區分,我使用了16443,這個下面會說到。
4.啟動keepalived,並設置開啟自啟動。
三台k8s master 主機都要啟動
systemctl start keepalived #啟動keepalived
systemctl enable keepalived #寫入注冊表,開啟自啟動
5.測試虛擬IP漂移
在master01上查看虛擬IP映射情況
ip addr show ens33
執行命令后,可以看到虛擬IP映射到了master01上。
ping 虛擬IP,如果虛擬IP能ping通,說明是可以工作的。
ping 172.20.111.22
關掉 master01,在執行 ping 172.20.111.22
,如果發現還能ping通,說明已經漂移到其他master主機,在其他主機 執行ip addr show ens33
,可查看具體漂移到哪台master主機。
(可以通過 systemctl status keepalived 查看服務狀態,具體問題具體分析)
通過虛擬IP技術 keepalived,可以實現多台主機之間的高可用。用戶只需要訪問虛擬IP即可,而無需知道是具體是哪台主機做出的響應。
三、安裝和配置haproxy
1. 安裝haproxy(3台主機都要操作)
在安裝haproxy之前,三台K8S master主機執行K8S集群搭建的 1到8步驟。這些步驟參考https://www.cnblogs.com/Fengyinyong/p/14682770.html
haproxy實現了負載均衡的作用,當通過虛擬IP訪問K8S集群時,會訪問到漂移到的具體K8S master 主機,再由該主機上的haproxy 將請求 負載均衡到三台K8S master主機。三台K8S master主機都要安裝haproxy。
可以理解為,keepalived 負載實現高可用,只要由一台能工作,就可以通過虛擬IP訪問到。haproxy負責實現負載均衡。
yum install -y haproxy
2.配置 haproxy(3台主機都要操作)
打開 /etc/haproxy/haproxy.cfg ,並替換成如下內容:
# /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 *:16443 # 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 k8s-master01 172.20.111.73:6443 check # ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT}
server k8s-master02 172.20.111.80:6443 check
server k8s-master03 172.20.111.86:6443 check
APISERVER_DEST_PORT
這個值同上面的keepalived健康檢查腳本里面的值一樣,我這里使用16443;
${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT}
其實就是你的k8s主節點的配置
3.啟動,並設置開啟自啟動。
systemctl start haproxy
systemctl enable haproxy
此時用 systemctl status haproxy
查看狀態,會發現haproxy是啟動的,但是收不到任何服務。那是因為我們完整搭建K8S集群。
如下所示:
四 配置網絡,搭建集群
這一步驟,不再贅述,這里只說不同點。參考 K8S單點集群搭建 https://www.cnblogs.com/Fengyinyong/p/14682770.html
1、不同點一:集群初始化
第一次和第二次初始化,采用的是虛擬IP+haproxy設置的16443端口。只在master01上執行。
第一次初始化
kubeadm init --control-plane-endpoint "172.20.111.22:16443" \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.20.0 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16 \
--upload-certs | tee kubeadm-init.log \
第二次初始化
kubeadm init --control-plane-endpoint "172.20.111.22:16443" \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.20.0 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-bind-port=6443 \
--ignore-preflight-errors=all \
--upload-certs | tee kubeadm-init.log
2、不同點二:master和node的加入集群指令
執行完初始化后,會輸出兩個加入集群的指令,一個是用於node集群加入的,一個是用於master集群加入的。其他 master 和 node 分別執行對應的指令
3、不同點三:三個k8s master都要執行默認指令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
第一個主master 在初始化的時候執行,其他master 在執行加入集群命令后 執行。
4、不同點四:指令token過期
master加入集群的指令token只有兩個小時有效。失效后,需要重新生成。可參考官網 https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/#steps-for-the-first-control-plane-node