k8s高可用涉及到ip填寫的相關配置和一些坑
etcd就不說了,奇數個副本,可以壞(n-1)/2個,但是不可能同時壞那麼多,這裡不討論etcd單獨不單獨跑。推薦個文件 https://github.com/etcd-io/etcd/tree/master/Documentation/op-guide
先說說k8s元件,kubelet和kube-proxy啥的肯定寫LB或者VIP:HA_port,如官方的圖

scheduler和controller連線的apiserver地址我看網上有寫127的也有寫LB或者VIP:HA_port的,剛看到官方文件說兩種都行 https://kubernetes.io/zh/docs/admin/high-availability/#%E8%BF%9B%E8%A1%8Cmaster%E9%80%89%E4%B8%BE%E7%9A%84%E7%BB%84%E4%BB%B6
官方文件這說得基本有疑問的都寫清楚了,前期scheduler和controller不支援ha,後來增加了選舉功能,他倆連apiserver的ip寫127.0.0.1和負載均衡器都可以
apiserver這塊介紹比較少,但是可以根據kubeadm部署的推理一些猜測
https://kubernetes.io/docs/setup/independent/high-availability/apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: stable apiServer: certSANs: - "LOAD_BALANCER_DNS" controlPlaneEndpoint: "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT"
controlPlaneEndpoint
:應匹配負載均衡器的地址或DNS和埠
而這個 controlPlaneEndpoint
實際上最終會取ip(注意不帶埠)寫到kube-apiserver的選項 --advertise-address
作為值。
預設情況下 --advertise-address
不配置將會和 --bind-address
一樣。它的作用就是宣告,在etcd啟動後kube-apiserver初次起來後會建立一個svc名叫 kubernetes
,而這個svc的endpoints就是選項 --advertise-address
的ip,port則是apiserver的 --secure-port
。假設使用者配置的 --secure-port
為6443,所以一般雲上SLB的話那這個宣告可以填寫LB的ip,然後預設的kubernetes的endpoints是<SLB_IP>:6443。
截止到現在似乎都沒有啥坑,但是這幾天寫生產環境的部署方案的時候,因為考慮到多網絡卡,而kubeadm部署的預設很多元件是bind 0.0.0.0的會導致所有網絡卡的ip的請求都會監聽。於是我 --bind-address
寫網絡卡ip例如三臺分別是172.16.1.2、3、4,HA用的keepalived+haproxy,vip是5。因為master上6443被apiserver監聽了,所以haproxy是另一個埠我是用的8443。
而坑就是宣告,我仿照官方意見 --advertise-address
寫了VIP(帶不了埠,否則報錯)。啟動了apiserver後預設宣告kubernetes的ep是VIP:6443,發現後面例如flannel的pod要請求apiserver的時候走它根本不通。因為apiserver是bind的網絡卡ip,而haproxy是bind 0.0.0.0:8443,沒有任何程序是bind vip:6443,所以請求走vip:6443是不通的。於是我patch了ep改為了8443。但是後面發現只要一重啟kube-apiserver就宣告的ep的port就成了6443。之前apiserver是bind 0.0.0.0是沒問題的,所以如果是多網絡卡還用的VIP這種ha下,宣告還是寫node自己的網絡卡ip或者不寫,雖然叢集內pod訪問apiserver走的是svc的負載均衡,但是你要是不想負載在svc那就花錢上LB宣告LB的ip唄。
寫node的網絡卡ip後,apiserver存活期間會去更新ep的ttl,只要apiserver 宕了它的ep會因為沒有重新整理ttl而被自動剔除。這個想法是issue裡看到別人提到的想法,也就是現在的工作原理。
[root@k8s-m3 ~]# systemctl stop kube-apiserver [root@k8s-m3 ~]# kubectl get ep NAMEENDPOINTSAGE kubernetes172.16.1.3:6443,172.16.1.4:644324h [root@k8s-m3 ~]# kubectl get ep NAMEENDPOINTSAGE kubernetes172.16.1.3:6443,172.16.1.4:644324h [root@k8s-m3 ~]# kubectl get ep NAMEENDPOINTSAGE kubernetes172.16.1.3:6443,172.16.1.4:644324h [root@k8s-m3 ~]# systemctl restart kube-apiserver [root@k8s-m3 ~]# kubectl get ep NAMEENDPOINTSAGE kubernetes172.16.1.10:6443,172.16.1.3:6443,172.16.1.4:644324h