Kubernetes 高可用叢集
(一)統一環境配置
1、節點配置
主機名 | IP | 角色 | 系統 | CPU/記憶體 | 磁碟 |
---|---|---|---|---|---|
kubernetes-master-01 | 192.168.141.150 | Master | Ubuntu Server 18.04 | 2核2G | 20G |
kubernetes-master-02 | 192.168.141.151 | Master | Ubuntu Server 18.04 | 2核2G | 20G |
kubernetes-master-03 | 192.168.141.152 | Master | Ubuntu Server 18.04 | 2核2G | 20G |
kubernetes-node-01 | 192.168.141.160 | Node | Ubuntu Server 18.04 | 2核4G | 20G |
kubernetes-node-02 | 192.168.141.161 | Node | Ubuntu Server 18.04 | 2核4G | 20G |
kubernetes-node-03 | 192.168.141.162 | Node | Ubuntu Server 18.04 | 2核4G | 20G |
Kubernetes VIP | 192.168.141.200 | - | - | - | - |
2、對作業系統的配置
特別注意:以下步驟請在製作 VMware 映象時一併完成,避免逐檯安裝的痛苦
關閉交換空間
swapoff -a
避免開機啟動交換空間
# 註釋 swap 開頭的行 vi /etc/fstab
關閉防火牆
ufw disable
配置 DNS
# 取消 DNS 行註釋,並增加 DNS 配置如:114.114.114.114,修改後重啟下計算機
vi /etc/systemd/resolved.conf
安裝 Docker
# 更新軟體源 sudo apt-get update # 安裝所需依賴 sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common # 安裝 GPG 證書 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - # 新增軟體源資訊 sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" # 再次更新軟體源 sudo apt-get -y update # 安裝 Docker CE 版 sudo apt-get -y install docker-ce
配置 Docker 加速器
特別注意:國內映象加速器可能會很卡,請替換成你自己阿里雲映象加速器,地址如:
https://yourself.mirror.aliyuncs.com
,在阿里雲控制檯的容器映象服務 -> 映象加速器選單中可以找到
在/etc/docker/daemon.json
中寫入如下內容(如果檔案不存在請新建該檔案)
{
"registry-mirrors": [
"https://registry.docker-cn.com"
]
}
安裝 kubeadm,kubelet,kubectl
# 安裝系統工具
apt-get update && apt-get install -y apt-transport-https
# 安裝 GPG 證書
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
# 寫入軟體源;注意:我們用系統代號為 bionic,但目前阿里雲不支援,所以沿用 16.04 的 xenial
cat << EOF >/etc/apt/sources.list.d/kubernetes.list
> deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
> EOF
# 安裝
apt-get update && apt-get install -y kubelet kubeadm kubectl
同步時間
設定時區
dpkg-reconfigure tzdata
選擇Asia(亞洲)
選擇Shanghai(上海)
時間同步
# 安裝 ntpdate
apt-get install ntpdate
# 設定系統時間與網路時間同步(cn.pool.ntp.org 位於中國的公共 NTP 伺服器)
ntpdate cn.pool.ntp.org
# 將系統時間寫入硬體時間
hwclock --systohc
確認時間
date
# 輸出如下(自行對照與系統時間是否一致)
Sun Jun 2 22:02:35 CST 2019
配置 IPVS
# 安裝系統工具
apt-get install -y ipset ipvsadm
# 配置並載入 IPVS 模組
mkdir -p /etc/sysconfig/modules/
vi /etc/sysconfig/modules/ipvs.modules
# 輸入如下內容
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
# 執行指令碼,注意:如果重啟則需要重新執行該指令碼
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 執行指令碼輸出如下
ip_vs_sh 16384 0
ip_vs_wrr 16384 0
ip_vs_rr 16384 0
ip_vs 147456 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack_ipv4 16384 3
nf_defrag_ipv4 16384 1 nf_conntrack_ipv4
nf_conntrack 131072 8 xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4,nf_nat,ipt_MASQUERADE,nf_nat_ipv4,nf_conntrack_netlink,ip_vs
libcrc32c 16384 4 nf_conntrack,nf_nat,raid456,ip_vs
配置核心引數
# 配置引數
vi /etc/sysctl.d/k8s.conf
# 輸入如下內容
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
vm.swappiness=0
# 應用引數
sysctl --system
# 應用引數輸出如下(找到 Applying /etc/sysctl.d/k8s.conf 開頭的日誌)
* Applying /etc/sysctl.d/10-console-messages.conf ...
kernel.printk = 4 4 1 7
* Applying /etc/sysctl.d/10-ipv6-privacy.conf ...
* Applying /etc/sysctl.d/10-kernel-hardening.conf ...
kernel.kptr_restrict = 1
* Applying /etc/sysctl.d/10-link-restrictions.conf ...
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/10-lxd-inotify.conf ...
fs.inotify.max_user_instances = 1024
* Applying /etc/sysctl.d/10-magic-sysrq.conf ...
kernel.sysrq = 176
* Applying /etc/sysctl.d/10-network-security.conf ...
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
* Applying /etc/sysctl.d/10-ptrace.conf ...
kernel.yama.ptrace_scope = 1
* Applying /etc/sysctl.d/10-zeropage.conf ...
vm.mmap_min_addr = 65536
* Applying /usr/lib/sysctl.d/50-default.conf ...
net.ipv4.conf.all.promote_secondaries = 1
net.core.default_qdisc = fq_codel
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.d/k8s.conf ...
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
* Applying /etc/sysctl.conf ...
修改 cloud.cfg
vi /etc/cloud/cloud.cfg
# 該配置預設為 false,修改為 true 即可
preserve_hostname: true
(二)單獨節點配置
特別注意:為 Master 和 Node 節點單獨配置對應的IP和主機名
1、配置 IP
編輯vi /etc/netplan/50-cloud-init.yaml
配置檔案,修改內容如下
network:
ethernets:
ens33:
# 我的 Master 是 150 - 152,Node 是 160 - 162
addresses: [192.168.141.150/24]
gateway4: 192.168.141.2
nameservers:
addresses: [192.168.141.2]
version: 2
使用netplan apply
命令讓配置生效
2、配置主機名
# 修改主機名
hostnamectl set-hostname kubernetes-master-01
# 配置 hosts
cat >> /etc/hosts << EOF
192.168.141.150 kubernetes-master-01
EOF
(三)安裝 HAProxy + Keepalived
1、概述
Kubernetes Master 節點執行元件如下:
- kube-apiserver:提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API 註冊和發現等機制
- kube-scheduler:負責資源的排程,按照預定的排程策略將 Pod 排程到相應的機器上
- kube-controller-manager:負責維護叢集的狀態,比如故障檢測、自動擴充套件、滾動更新等
- etcd:CoreOS 基於 Raft 開發的分散式 key-value 儲存,可用於服務發現、共享配置以及一致性保障(如資料庫選主、分散式鎖等)
kube-scheduler
和kube-controller-manager
可以以叢集模式執行,通過 leader 選舉產生一個工作程序,其它程序處於阻塞模式。
kube-apiserver
可以執行多個例項,但對其它元件需要提供統一的訪問地址,本章節部署 Kubernetes 高可用叢集實際就是利用 HAProxy + Keepalived 配置該元件
配置的思路就是利用 HAProxy + Keepalived 實現kube-apiserver
虛擬 IP 訪問從而實現高可用和負載均衡,拆解如下:
- Keepalived 提供
kube-apiserver
對外服務的虛擬 IP(VIP) - HAProxy 監聽 Keepalived VIP
- 執行 Keepalived 和 HAProxy 的節點稱為 LB(負載均衡) 節點
- Keepalived 是一主多備執行模式,故至少需要兩個 LB 節點
- Keepalived 在執行過程中週期檢查本機的 HAProxy 程序狀態,如果檢測到 HAProxy 程序異常,則觸發重新選主的過程,VIP 將飄移到新選出來的主節點,從而實現 VIP 的高可用
- 所有元件(如 kubeclt、apiserver、controller-manager、scheduler 等)都通過 VIP +HAProxy 監聽的 6444 埠訪問
kube-apiserver
服務(注意:kube-apiserver
預設埠為 6443,為了避免衝突我們將 HAProxy 埠設定為 6444,其它元件都是通過該埠統一請求 apiserver)
2、建立 HAProxy 啟動指令碼
該步驟在
kubernetes-master-01
執行
mkdir -p /usr/local/kubernetes/lb
vi /usr/local/kubernetes/lb/start-haproxy.sh
# 輸入內容如下
#!/bin/bash
# 修改為你自己的 Master 地址
MasterIP1=192.168.141.150
MasterIP2=192.168.141.151
MasterIP3=192.168.141.152
# 這是 kube-apiserver 預設埠,不用修改
MasterPort=6443
# 容器將 HAProxy 的 6444 埠暴露出去
docker run -d --restart=always --name HAProxy-K8S -p 6444:6444 \
-e MasterIP1=$MasterIP1 \
-e MasterIP2=$MasterIP2 \
-e MasterIP3=$MasterIP3 \
-e MasterPort=$MasterPort \
wise2c/haproxy-k8s
# 設定許可權
chmod +x start-haproxy.sh
3、建立 Keepalived 啟動指令碼
該步驟在
kubernetes-master-01
執行
mkdir -p /usr/local/kubernetes/lb
vi /usr/local/kubernetes/lb/start-keepalived.sh
# 輸入內容如下
#!/bin/bash
# 修改為你自己的虛擬 IP 地址
VIRTUAL_IP=192.168.141.200
# 虛擬網絡卡裝置名
INTERFACE=ens33
# 虛擬網絡卡的子網掩碼
NETMASK_BIT=24
# HAProxy 暴露埠,內部指向 kube-apiserver 的 6443 埠
CHECK_PORT=6444
# 路由識別符號
RID=10
# 虛擬路由識別符號
VRID=160
# IPV4 多播地址,預設 224.0.0.18
MCAST_GROUP=224.0.0.18
docker run -itd --restart=always --name=Keepalived-K8S \
--net=host --cap-add=NET_ADMIN \
-e VIRTUAL_IP=$VIRTUAL_IP \
-e INTERFACE=$INTERFACE \
-e CHECK_PORT=$CHECK_PORT \
-e RID=$RID \
-e VRID=$VRID \
-e NETMASK_BIT=$NETMASK_BIT \
-e MCAST_GROUP=$MCAST_GROUP \
wise2c/keepalived-k8s
# 設定許可權
chmod +x start-keepalived.sh
4、複製指令碼到其它 Master 地址
分別在kubernetes-master-02
和kubernetes-master-03
執行建立工作目錄命令
mkdir -p /usr/local/kubernetes/lb
將kubernetes-master-01
中的指令碼拷貝至其它 Master
scp start-haproxy.sh start-keepalived.sh 192.168.141.151:/usr/local/kubernetes/lb
scp start-haproxy.sh start-keepalived.sh 192.168.141.152:/usr/local/kubernetes/lb
分別在 3 個 Master 中啟動容器(執行指令碼)
sh /usr/local/kubernetes/lb/start-haproxy.sh && sh /usr/local/kubernetes/lb/start-keepalived.sh
5、驗證是否成功
檢視容器
docker ps
# 輸出如下
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f50df479ecae wise2c/keepalived-k8s "/usr/bin/keepalived…" About an hour ago Up About an hour Keepalived-K8S
75066a7ed2fb wise2c/haproxy-k8s "/docker-entrypoint.…" About an hour ago Up About an hour 0.0.0.0:6444->6444/tcp HAProxy-K8S
檢視網絡卡繫結的虛擬 IP
ip a | grep ens33
# 輸出如下
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 192.168.141.151/24 brd 192.168.141.255 scope global ens33
inet 192.168.141.200/24 scope global secondary ens33
特別注意:Keepalived 會對 HAProxy 監聽的 6444 埠進行檢測,如果檢測失敗即認定本機 HAProxy 程序異常,會將 VIP 漂移到其他節點,所以無論本機 Keepalived 容器異常或 HAProxy 容器異常都會導致 VIP 漂移到其他節點
(四)部署 Kubernetes 叢集
1、初始化 Master
- 建立工作目錄並匯出配置檔案
# 建立工作目錄
mkdir -p /usr/local/kubernetes/cluster
# 匯出配置檔案到工作目錄
kubeadm config print init-defaults --kubeconfig ClusterConfiguration > kubeadm.yml
- 修改配置檔案
apiVersion: kubeadm.k8s.io/v1beta1
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
# 修改為主節點 IP
advertiseAddress: 192.168.141.150
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: kubernetes-master
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
# 配置 Keepalived 地址和 HAProxy 埠
controlPlaneEndpoint: "192.168.141.200:6444"
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
# 國內不能訪問 Google,修改為阿里雲
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
# 修改版本號
kubernetesVersion: v1.14.2
networking:
dnsDomain: cluster.local
# 配置成 Calico 的預設網段
podSubnet: "192.168.0.0/16"
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
# 開啟 IPVS 模式
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
- kubeadm 初始化
# kubeadm 初始化
kubeadm init --config=kubeadm.yml --experimental-upload-certs | tee kubeadm-init.log
# 配置 kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 驗證是否成功
kubectl get node
- 安裝網路外掛
# 安裝 Calico
kubectl apply -f https://docs.projectcalico.org/v3.7/manifests/calico.yaml
# 驗證安裝是否成功
watch kubectl get pods --all-namespaces
3、加入 Master 節點
從kubeadm-init.log
中獲取命令,分別將kubernetes-master-02
和kubernetes-master-03
加入 Master
# 以下為示例命令
kubeadm join 192.168.141.200:6444 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:56d53268517c132ae81c868ce99c44be797148fb2923e59b49d73c99782ff21f \
--experimental-control-plane --certificate-key c4d1525b6cce4b69c11c18919328c826f92e660e040a46f5159431d5ff0545bd
4、加入 Node 節點
從kubeadm-init.log
中獲取命令,分別將kubernetes-node-01
至kubernetes-node-03
加入 Node
# 以下為示例命令
kubeadm join 192.168.141.200:6444 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:56d53268517c132ae81c868ce99c44be797148fb2923e59b49d73c99782ff21f
5、驗證叢集狀態
- 檢視 Node
kubectl get nodes -o wide
- 檢視 Pod
kubectl -n kube-system get pod -o wide
- 檢視 Service
kubectl -n kube-system get svc
- 驗證 IPVS
檢視 kube-proxy 日誌,server_others.go:176] Using ipvs Proxier.
kubectl -n kube-system logs -f <kube-proxy 容器名>
- 檢視代理規則
ipvsadm -ln
- 檢視生效的配置
kubectl -n kube-system get cm kubeadm-config -oyaml
- 檢視 etcd 叢集
kubectl -n kube-system exec etcd-kubernetes-master-01 -- etcdctl \
--endpoints=https://192.168.141.150:2379 \
--ca-file=/etc/kubernetes/pki/etcd/ca.crt \
--cert-file=/etc/kubernetes/pki/etcd/server.crt \
--key-file=/etc/kubernetes/pki/etcd/server.key cluster-health
# 輸出如下
member 1dfaf07371bb0cb6 is healthy: got healthy result from https://192.168.141.152:2379
member 2da85730b52fbeb2 is healthy: got healthy result from https://192.168.141.150:2379
member 6a3153eb4faaaffa is healthy: got healthy result from https://192.168.141.151:2379
cluster is healthy
5、驗證高可用
特別注意:Keepalived 要求至少 2 個備用節點,故想測試高可用至少需要 1 主 2 從模式驗證,否則可能出現意想不到的問題
對任意一臺 Master 機器執行關機操作
shutdown -h now
在任意一臺 Master 節點上檢視 Node 狀態
kubectl get node
# 輸出如下,除已關機那臺狀態為 NotReady 其餘正常便表示成功
NAME STATUS ROLES AGE VERSION
kubernetes-master-01 NotReady master 18m v1.14.2
kubernetes-master-02 Ready master 17m v1.14.2
kubernetes-master-03 Ready master 16m v1.14.2
檢視 VIP 漂移
ip a |grep ens33
# 輸出如下
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 192.168.141.151/24 brd 192.168.141.255 scope global ens33
inet 192.168.141.200/24 scope global secondary ens33
轉自:有夢想的鹹魚