多master(高可用)介紹
假設(shè)現(xiàn)在有3個node節(jié)點(diǎn)和3個master節(jié)點(diǎn),node1到底是連到master1還是連到master2還是master3,需要有人來分配,這個中間人就是load balancer,load balancer起到兩個作用,一是負(fù)載。二是檢查master狀態(tài),如果master1異常,就會使node連到master2上,如果master1正常,則正常提供服務(wù)。由于節(jié)點(diǎn)之間互相訪問是通過IP連接,這里也是一樣的,只不過是通過VIP(虛擬ip)連接。
高可用集群使用技術(shù)介紹
keepalived:檢查master狀態(tài),是否正常運(yùn)行;配置虛擬IP。
haproxy:負(fù)載均衡服務(wù)器,起到負(fù)載作用。
master具體組件:apiserver, controller-manager, scheduler。
高可用集群架構(gòu)圖
搭建高可用k8s集群步驟
前提條件:
①固定四臺主機(jī)IP,參考文章固定虛擬機(jī)IP
②可連外網(wǎng)
主機(jī) | IP |
---|---|
master1 | 192.168.2.200 |
master2 | 192.168.2.201 |
master3 | 192.168.2.204 |
node1 | 192.168.2.202 |
虛擬IP | 192.168.2.203 |
我們以3臺master,1臺node為例,首先準(zhǔn)備好4臺服務(wù)器,分別在四臺服務(wù)器上做操作。
1. 準(zhǔn)備環(huán)境-系統(tǒng)初始化
# 關(guān)閉防火墻
systemctl disable firewalld #永久關(guān)閉,移除開機(jī)自啟項(xiàng),以后開機(jī)不會啟動
systemctl stop firewalld #臨時關(guān)閉,立刻關(guān)閉
# 關(guān)閉selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 修改selinux配置文件為關(guān)閉狀態(tài),以后開機(jī)不會啟動
setenforce 0 #臨時關(guān)閉,立刻關(guān)閉
# 關(guān)閉swap分區(qū)
sed -ri 's/.*swap.*/#&/' /etc/fstab # 修改swap配置文件為關(guān)閉狀態(tài),以后開機(jī)不會啟動
swapoff -a #臨時關(guān)閉,立刻關(guān)閉
# 根據(jù)規(guī)劃設(shè)置主機(jī)名
hostnamectl set-hostname <hostname>
bash # 刷新
# 在master中添加hosts,每一個master都要執(zhí)行
cat >> /etc/hosts << EOF
192.168.2.203 k8s-vip
192.168.2.200 master1
192.168.2.201 master2
192.168.2.204 master3
192.168.2.202 node1
EOF
# 將橋接的 IPv4 流量傳遞到 iptables 的鏈
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
cat >> /etc/sysctl.conf<<EOF
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-iptables=1
net.ipv4.neigh.default.gc_thresh1=4096
net.ipv4.neigh.default.gc_thresh2=6144
net.ipv4.neigh.default.gc_thresh3=8192
EOF
#加載
modprobe br_netfilter
sysctl -p
sysctl --system # 生效
--------------------------------
# 時間同步
yum -y install ntpdate
ntpdate time.windows.com
如果執(zhí)行過程中出錯,參考這篇文章,錯誤匯總
2. 所有master節(jié)點(diǎn)部署keepalived+haproxy
2.1 安裝keepalived
# 安裝相關(guān)依賴
yum install -y conntrack-tools libseccomp libtool-ltdl
# 安裝keepalived
yum install -y keepalived
2.2 配置master節(jié)點(diǎn)
- master1節(jié)點(diǎn)配置:
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
router_id k8s
}
vrrp_script check_haproxy {
script "killall -0 haproxy" # 檢測haproxy是否存在
interval 3
weight -2
fall 10
rise 2
}
vrrp_instance VI_1 {
state MASTER # 主節(jié)點(diǎn)
interface ens33 # ens33 為網(wǎng)卡名稱,可以使用ifconfig查看自己的網(wǎng)卡名稱
virtual_router_id 51
priority 250 # 權(quán)重,keepalived的master節(jié)點(diǎn)必須大于keepalived的backup節(jié)點(diǎn)
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab # 密鑰,master和backup密鑰必須一致
}
virtual_ipaddress {
192.168.2.203 # 虛擬ip
}
track_script {
check_haproxy
}
}
EOF
- master2、master3節(jié)點(diǎn)配置
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
router_id k8s
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 3
weight -2
fall 10
rise 2
}
vrrp_instance VI_1 {
state BACKUP # 從節(jié)點(diǎn)
interface ens33 # ens33 為網(wǎng)卡名稱
virtual_router_id 51
priority 200 # 必須小于MASTER權(quán)重
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab # 密鑰,于MASTER一致
}
virtual_ipaddress {
192.168.2.203 # 虛擬ip
}
track_script {
check_haproxy
}
}
EOF
- 啟動和檢查
三臺master節(jié)點(diǎn)都執(zhí)行
# 啟動keepalived
systemctl start keepalived.service
# 設(shè)置開機(jī)啟動
systemctl enable keepalived.service
# 查看啟動狀態(tài)
systemctl status keepalived.service
啟動后查看master的網(wǎng)卡信息。由于虛擬IP配到了master1上,執(zhí)行后,master1節(jié)點(diǎn)上會多出一個IP,即為虛擬IP;master2和master3上沒有,掛上master1后才會出現(xiàn)。
ip a s ens33
2.3 部署haproxy
- 在3個master節(jié)點(diǎn)安裝 haproxy
# 安裝haproxy
yum install -y haproxy
- 配置
3臺master節(jié)點(diǎn)的配置均相同,配置中聲明了后端代理的3個master節(jié)點(diǎn)服務(wù)器,指定了haproxy運(yùn)行的端口為16443等,因此16443端口為集群的入口
cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# 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 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
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#---------------------------------------------------------------------
frontend kubernetes-apiserver
mode tcp
bind *:16443 #默認(rèn)監(jiān)聽端口16443
option tcplog
default_backend kubernetes-apiserver
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiserver
mode tcp
balance roundrobin
server master01.k8s.io 192.168.2.200:6443 check # 修改IP
server master02.k8s.io 192.168.2.201:6443 check # 修改IP
server master03.k8s.io 192.168.2.204:6443 check # 修改IP
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
bind *:1080
stats auth admin:awesomePassword
stats refresh 5s
stats realm HAProxy\ Statistics
stats uri /admin?stats
EOF
- 啟動和檢查
3臺master都啟動
# 啟動 haproxy
systemctl start haproxy
# 設(shè)置開啟自啟
systemctl enable haproxy
# 查看啟動狀態(tài)
systemctl status haproxy
啟動后,檢查端口,查看對應(yīng)的端口是否包含 16443
netstat -tunlp | grep haproxy
如果執(zhí)行過程中出錯,參考這篇文章,錯誤匯總
3. 所有節(jié)點(diǎn)安裝Docker/kubeadm/kubelet
所有節(jié)點(diǎn)安裝Docker/kubeadm/kubelet ,Kubernetes默認(rèn)CRI(容器運(yùn)行時)為Docker,因此先安裝Docker。
- 安裝之前確保沒有其他dockers版本,如果有,需要刪除干凈后再安裝,卸載方式可以參考這篇文章卸載docker。
- 安裝Docker,所有master+node都要安裝
# 下載docker的yum源
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
# 安裝docker,找上一步的yum源去安裝
yum -y install docker-ce-18.06.1.ce-3.el7
# 開機(jī)自啟動并且啟動docker
systemctl enable docker && systemctl start docker
# 查看docker狀態(tài)
systemctl status docker
# 查看docker版本
docker --version
# 設(shè)置docker拉取鏡像的加速器
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
# 重啟docker
systemctl daemon-reload
systemctl restart docker
- 添加阿里云yum源,所有節(jié)點(diǎn)(master+node)
cat >/etc/yum.repos.d/docker.repo<<EOF
[docker-ce-edge]
name=Docker CE Edge - \$basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/\$basearch/edge
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
EOF
# 重啟docker
systemctl restart docker
- 添加kubernetes軟件源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
- 安裝kubeadm,kubectl,kubelet
由于版本更新頻繁,這里指定版本號部署:
# 安裝kubelet、kubeadm、kubectl,同時指定版本
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
# 啟動并設(shè)置開機(jī)啟動
systemctl start kubelet
systemctl enable kubelet
4. 部署Kubernetes Master
4.1 創(chuàng)建kubreadm配置文件
在具有vip的master上進(jìn)行初始化操作,這里為master1
# 創(chuàng)建文件夾
mkdir /usr/local/kubernetes/manifests -p
# 到manifests目錄
cd /usr/local/kubernetes/manifests/
# 新建yaml文件
vim kubeadm-config.yaml
下面內(nèi)容修改IP 后復(fù)制進(jìn)去
apiVersion: kubeadm.k8s.io/v1beta2 # 集群主版本,根據(jù)集群版本號決定
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.2.200 #本機(jī)ip
bindPort: 6443 #apiserver集群端口號
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master1 #本機(jī)hostname
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
certSANs:
- k8s-master1
- k8s-master2
- k8s-master3
- 192.168.2.200 # master1 ip
- 192.168.2.201 # master2 ip
- 192.168.2.204 # master3 ip
- 192.168.2.203 # 虛擬vip keepalive出來的ip
- 127.0.0.1
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 2m0s # 注冊時間2分鐘
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes # 集群名字
controlPlaneEndpoint: "192.168.2.203:16443" # 虛擬ip + haproxy綁定的端口號
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.18.0 # 集群版本,需要與kubeadm版本一致
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16 # pod 內(nèi)網(wǎng)ip網(wǎng)段
serviceSubnet: 10.96.0.0/12 # svc 內(nèi)網(wǎng)ip網(wǎng)段
scheduler: {}
這里補(bǔ)充一個自動生成kubeadm-config.yaml
文件的命令,生成模板后需要修改。kubeadm config print init-defaults > kubeadm-config.yaml
.
4.2 在master1節(jié)點(diǎn)執(zhí)行
kubeadm init --config kubeadm-config.yaml
執(zhí)行完成后,就會在拉取鏡像【需要等待…】
初始化節(jié)點(diǎn)
如果上面的yaml文件已經(jīng)執(zhí)行過一次,再次執(zhí)行就會報錯,這時,就需要將集群初始化后才能執(zhí)行。
步驟:
# 1. 還原由 kubeadm init 或 kubeadm join 所做的更改
kubeadm reset -f
# 2. 刪除相關(guān)文件
rm -rf /etc/kubernetes/*
rm -rf /var/lib/etcd/*
然后再次執(zhí)行yaml文件即可。
按照執(zhí)行出的結(jié)果提示配置環(huán)境變量,使用kubectl工具
# 執(zhí)行下方命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 查看節(jié)點(diǎn)
kubectl get nodes
# 查看集群健康狀態(tài)
kubectl get cs
# 查看pod
kubectl get pods -n kube-system
由于沒有安裝網(wǎng)絡(luò)插件,所以會有pending狀態(tài),無妨,繼續(xù)往下執(zhí)行就好了。
按照提示保存以下內(nèi)容,一會要使用
kubeadm join k8s-vip:16443 --token ivcq40.a1bb605g6df4xhdw \
--discovery-token-ca-cert-hash sha256:b65dcb57a2934439562ae138f552942600296edc04cdefb7da93031cf23c9a08 \
--control-plane
–control-plane : 只有在添加master節(jié)點(diǎn)的時候才有
5. 安裝集群網(wǎng)絡(luò)
從官方地址獲取到flannel的yaml,在master1上執(zhí)行
# 創(chuàng)建文件夾
mkdir flannel
cd flannel
# 下載yaml文件
wget -c https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
安裝flannel網(wǎng)絡(luò),執(zhí)行完apply之后需要等待一會,pending狀態(tài)才會變成running。
kubectl apply -f kube-flannel.yml
檢查,都已經(jīng)running,且master已經(jīng)ready。
kubectl get pods -n kube-system
6. master節(jié)點(diǎn)加入Kubernetes集群
6.1 復(fù)制密鑰及相關(guān)文件
從master1復(fù)制密鑰及相關(guān)文件到master2、master3
# master1中執(zhí)行,修改IP,分別改為master2/3的IP執(zhí)行2遍
ssh root@192.168.2.201 mkdir -p /etc/kubernetes/pki/etcd # 修改IP;master2\master3的IP,用master1連接master2\master3;輸入密碼
# 復(fù)制相應(yīng)的文件到master2/master3
scp /etc/kubernetes/admin.conf root@192.168.2.201:/etc/kubernetes
scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@192.168.2.201:/etc/kubernetes/pki
scp /etc/kubernetes/pki/etcd/ca.* root@192.168.2.201:/etc/kubernetes/pki/etcd
6.2 master2和master3加入到集群
在master2、master3上執(zhí)行在master1上init后輸出的join命令,需要帶上參數(shù)–control-plane表示把master控制節(jié)點(diǎn)加入集群。
# master2&master上依次執(zhí)行
kubeadm join k8s-vip:16443 --token ivcq40.a1bb605g6df4xhdw \
--discovery-token-ca-cert-hash sha256:b65dcb57a2934439562ae138f552942600296edc04cdefb7da93031cf23c9a08 \
--control-plane
按照提示執(zhí)行輸出的3行命令
在master1上檢查狀態(tài)
kubectl get nodes
kubectl get pods --all-namespaces
7. node節(jié)點(diǎn)加入Kubernetes集群
向集群添加新節(jié)點(diǎn),執(zhí)行在kubeadm init輸出的kubeadm join命令,不加參數(shù)–control-plane
# 在node1上執(zhí)行
kubeadm join k8s-vip:16443 --token ivcq40.a1bb605g6df4xhdw \
--discovery-token-ca-cert-hash sha256:b65dcb57a2934439562ae138f552942600296edc04cdefb7da93031cf23c9a08
提示:
#token是有時間期限的,如果過期了,執(zhí)行如下命令獲取后再執(zhí)行。 kubectl create token --print-join-command #補(bǔ)充一個生成certificate-key的命令 kubeadm init phase upload-certs --upload-certs
報錯解決,沒有錯誤繼續(xù)往下
執(zhí)行命令后,報錯no such host,如下:
這時候,需要將node1節(jié)點(diǎn)里的hosts表里的內(nèi)容保持與master節(jié)點(diǎn)一致,再次執(zhí)行就可以了。
集群網(wǎng)絡(luò)重新安裝,因?yàn)樘砑恿诵碌膎ode節(jié)點(diǎn)
# 在master1節(jié)點(diǎn)上執(zhí)行
kubectl apply -f flannel/kube-flannel.yml
檢查狀態(tài)
kubectl get nodes
kubectl get pods --all-namespaces
8. 測試kubernetes集群
在Kubernetes集群中創(chuàng)建一個pod,驗(yàn)證是否正常運(yùn)行:
# 創(chuàng)建nginx deployment
kubectl create deployment nginx --image=nginx
# 暴露端口
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort
# 查看狀態(tài)
kubectl get pod,svc
然后通過任何一個master或node節(jié)點(diǎn)或者虛擬IP加上端口號,都能夠訪問nginx頁面;如果想要通過域名訪問服務(wù),可以參考這篇文章。注意一定要在master節(jié)點(diǎn)上添加污點(diǎn)容忍,不然無法通過虛擬IP 對應(yīng)域名進(jìn)行訪問。這里要用第二種方式部署ingress-controller。文章來源:http://www.zghlxwxcb.cn/news/detail-414915.html
9. 模擬
我們現(xiàn)在有3個master節(jié)點(diǎn),1個node節(jié)點(diǎn),經(jīng)過上述測試,發(fā)現(xiàn)集群可以正常訪問nginx服務(wù),因?yàn)槿_master在正常運(yùn)行,我們現(xiàn)在模擬掛掉一臺master,讓另外2臺master正常運(yùn)行,看一下會有什么效果:文章來源地址http://www.zghlxwxcb.cn/news/detail-414915.html
- 首先,先查看集群是否正常,執(zhí)行
kubectl get nodes
命令,發(fā)現(xiàn)各個節(jié)點(diǎn)都處于ready狀態(tài) - 我們現(xiàn)在把master3這臺服務(wù)器關(guān)掉,再看集群狀態(tài),關(guān)掉一會之后,發(fā)現(xiàn)master3節(jié)點(diǎn)狀態(tài)變成了NotReady。
我們再使用其他節(jié)點(diǎn)的IP加上端口號訪問nginx試一下,發(fā)現(xiàn)可以正常訪問;如果使用master3節(jié)點(diǎn)的IP加端口號就無法訪問nginx,是因?yàn)閙aster3服務(wù)器已經(jīng)關(guān)閉。 - 到現(xiàn)在為止,我們有2臺正在運(yùn)行的master,現(xiàn)在我們再關(guān)閉一臺master,把master2也關(guān)掉,只留一臺master,試一下會怎么樣?
關(guān)閉前的狀態(tài):
關(guān)閉后再次執(zhí)行kubectl get nodes
命令,發(fā)現(xiàn)報錯了,顯示無法連接到服務(wù)器。
雖然這時候在訪問nginx還是可以正常訪問,但是此時的集群已經(jīng)壞掉了。
所以,如果有3個master節(jié)點(diǎn),必須要保證2個正常運(yùn)行;如果有5個master,必須保證3個正常運(yùn)行。假設(shè)有N個master節(jié)點(diǎn),必須保證有(N+1)/2個節(jié)點(diǎn)正常運(yùn)行,才能保證集群正常。
到了這里,關(guān)于【云原生】搭建k8s高可用集群—更新于2023.04的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!