從零開始搭建高可用的k8s集群
一、環境準備
使用Hyper-V虛擬機功能搭建三台Centos虛擬機系統,配置好靜態IP,分別為k8s-node1(192.168.0.8),k8s-node2(192.168.0.9),k8s-node3(192.168.0.10)。系統安裝成功後配置root遠程登錄功能,以便使用ssh客戶端工具鏈接。
初始化系統設置:
◉分配固定IP :設置虛擬機固定IP的方式比較多,本方案採用設置虛擬的MAC地址為靜態ID,然後在路由器中為MAC分配固定IP。
◉開啟SSH遠程登錄:運行命令” yum install openssh-server “安裝ssh服務端工具,安裝完成後運行命令” systemctl enable sshd.service “設置開啟自啟動, 運行命令” vim /etc/ssh/sshd_config “編輯配置文件,設置如下:
◉修改IPV6為IPV4:centos默認使用ipv6的方式,我們需要修改為ipv4模式來實現ssh客戶端的遠程連接,具體方法是 cd到 /etc/sysconfig/network-scripts目錄下,vim 編輯 ifcfg-eth1 文件,如圖,設置IPV6INIT=no,ONBOOT=yes。
◉安裝docker環境:完成以上步驟後,重啟電腦即可使用ssh工具連接,複製命令” curl –sSL https://get.daocloud.io/docker | sh ” 安裝dockers環境。
◉設置docker開機自啟:運行命令” systemctl enable docker ” 將docker加入開機啟動項。
◉配置docker鏡像加速器:國內從 DockerHub 拉取鏡像有時會遇到困難,此時可以配置鏡像加速器。Docker 官方和國內很多雲服務商都提供了國內加速器服務,此處以配置阿里雲鏡像加速器為例,登錄//cr.console.aliyun.com/,選擇容器鏡像服務-鏡像工具-鏡像加速器,如圖所示,通過在/etc/docker/daemon.json文件中配置registry-mirrors屬性來實現該功能:
◉設置防火牆規則:設置防火牆規則的目的是為了確保集群中的機器能夠相互通信,本次集群直接使用命令” systemctl disable firewalld “關閉防火牆。
◉設置 /proc/sys/net/bridge目錄下bridge-nf-call-iptables和bridge-nf-call-ip6tables文件的內容為1,確保的 Linux 節點的 iptables 正確查看橋接流量。
◉關閉Linux系統的交換分區:為了保證kubelet的正常運行,必須禁用swap交換分區。window平台上稱為虛擬內存。在物理內存不夠用時,操作系統會從物理內存中把部分暫時不被使用的數據轉移到交換分區,從而為當前運行的程序留出足夠的物理內存。運行命令” free -m “結果證明已經開啟了交換分區,修改/etc/fstab文件,注釋掉加載swap分區的這行記錄,重啟Linux系統即可。
二、安裝K8S集群
完成以上步驟後,就可以進行k8s組件的安裝了,我們需要三個必須的組件kubeadm、kubelet 和 kubectl,把他們安裝到每台集群的機器上。其中kubeadm是引導我們創建集群的命令;kubelet 是集群中的所有機器上運行的組件,並執行諸如啟動 pod 和容器之類的操作;kubectl是與集群對話的命令行工具。讀者請注意,kubeadm不會為你安裝或管理kubelet和kubectl,
因此你需要確保它們與control plane之間版本的匹配,如果不這樣做,則存在版本偏差的風險,這可能導致意外的錯誤行為。
安裝步驟:
1、配置k8s下載地址信息(配置為阿里雲鏡像,國外鏡像很難下載成功),運行如下命令。
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [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 //mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl EOF
2、運行如下命令安裝三個組件。
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
3、設置kubelet的開機自啟動:啟動後kubelet會每隔幾秒啟動一次來探測kubeadm的命令。
systemctl enable kubelet && systemctl start kubelet
4、提前準備k8s集群必須的組件:在後續的kubeadm init命令中,他需要下載一些必須鏡像,這些鏡像可以通過 ” kubeadm config images list “命令來查看,如圖:
但是這些鏡像默認是從國外源,在國內無法下載,因此有必要在此之前先使用國內源下載好這些鏡像,此處使用阿里雲鏡像地址下載:
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.6 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.6 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.6 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6
根據上面的命令把鏡像都下載完成後,進行鏡像複製,調用 ” docker tag oldimages newimages “命令複製出滿足kubeadm init的標準鏡像,代碼如下:
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.6 k8s.gcr.io/kube-apiserver:v1.23.6 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.6 k8s.gcr.io/kube-proxy:v1.23.6 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6 k8s.gcr.io/kube-controller-manager:v1.23.6 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.6 k8s.gcr.io/kube-scheduler:v1.23.6 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6 k8s.gcr.io/coredns/coredns:v1.8.6 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0 k8s.gcr.io/etcd:3.5.1-0 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 k8s.gcr.io/pause:3.6
執行完成所有複製命令後,docker images查看鏡像,發現需要的鏡像已準備好,列表如下:
5、使用kubeadm來引導我們創建集群。首先運行 ” kubeadm init [arg]”命令,會進行一系列預檢查以確保機器已準備好運行 Kubernetes。這些預檢查會顯示警告並在錯誤時退出(遇到錯誤時需要根據具體輸出日誌解決錯誤)。然後下載並安裝集群控制平面組件。 kubeadm init 包含一些指定參數,其參數說明下:
--apiserver-advertise-address string 設置 apiserver 綁定的 IP. --apiserver-bind-port int32 設置apiserver 監聽的端口. (默認 6443) --control-plane-endpoint string 設置控制平面的端點(matser控制節點的IP或域名) --apiserver-cert-extra-sans strings api證書中指定額外的Subject Alternative Names (SANs) 可以是IP 也可以是DNS名稱。 證書是和SAN綁定的。 --cert-dir string 證書存放的目錄 (默認 "/etc/kubernetes/pki") --certificate-key string kubeadm-cert secret 中 用於加密 control-plane 證書的key --config string kubeadm 配置文件的路徑. --cri-socket string CRI socket 文件路徑,如果為空 kubeadm 將自動發現相關的socket文件; 只有當機器中存在多個 CRI socket 或者 存在非標準 CRI socket 時才指定. --dry-run 測試,並不真正執行;輸出運行後的結果. --feature-gates string 指定啟用哪些額外的feature 使用 key=value 對的形式。 --help -h 幫助文檔 --ignore-preflight-errors strings 忽略前置檢查錯誤,被忽略的錯誤將被顯示為警告. 例子: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks. --image-repository string 選擇拉取 control plane images 的鏡像repo (default "k8s.gcr.io") ,國內一般無法直接從k8s.gcr.io獲取,需要改為國內的代理地址 --kubernetes-version string 選擇K8S版本. (default "stable-1") --node-name string 指定node的名稱,默認使用 node 的 hostname. --pod-network-cidr string 指定 pod 的網絡, control plane 會自動將 網絡發佈到其他節點的node,讓其上啟動的容器使用此網絡 --service-cidr string 指定service 的IP 範圍. (default "10.96.0.0/12"),不能與機器的IP段有重疊 --service-dns-domain string 指定 service 的 dns 後綴, e.g. "myorg.internal". (default "cluster.local") --skip-certificate-key-print 不打印 control-plane 用於加密證書的key. --skip-phases strings 跳過指定的階段(phase) --skip-token-print 不打印 kubeadm init 生成的 default bootstrap token --token string 指定 node 和control plane 之間,簡歷雙向認證的token ,格式為 [a-z0-9]{6}\.[a-z0-9]{16} - e.g. abcdef.0123456789abcdef --token-ttl duration token 自動刪除的時間間隔。 (e.g. 1s, 2m, 3h). 如果設置為 '0', token 永不過期 (default 24h0m0s) --upload-certs 上傳 control-plane 證書到 kubeadm-certs Secret.
本方案我們使用如下命令參數來初始化主控節點:
kubeadm init \ --apiserver-advertise-address=192.168.0.10 \ --control-plane-endpoint=192.168.0.10 \ --service-cidr=10.96.0.0/16 \ --pod-network-cidr=192.168.0.0/16
執行以上命令,init 預檢查到我的機器CUP和內存不滿足性能要求,提示如下:此時需要關閉虛擬機,重新調整CPU核心數和內存大小。
繼續運行命令,發現提示 ” It seems like the kubelet isn’t running or healthy. “,的錯誤,表示kubelet未能正常運行,通過查看kubelet的運行日誌發現報錯如下:
意思是因為kubelet cgroup驅動程序「systemd」與docker cgroup驅動程序「cgroupfs」不同,所以我們需要調整為相同。調整方式為修改docker cgroup的驅動程序為systemd(官方推薦用systemd),編輯/etc/docker/daemon.json文件,修改或增加 “exec-opts”:[“native.cgroupdriver=systemd”] 代碼:
{ "registry-mirrors": ["//yyipnm7g.mirror.aliyuncs.com"], "exec-opts":["native.cgroupdriver=systemd"] }
重啟機器再次運行init命令(如果運行失敗,提示某些端口被佔用和某些文件已經存在,需要使用” kubeadm reset “重置後再運行)後,這可能會需要幾分鐘來完成組件的安裝,安裝成功後應該看到類似如下的輸出:
屏幕輸出中提示:
◉你的Kubernetes控制飛機已成功初始化。
◉要開始使用群集,您需要以普通用戶身份運行以下操作:
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
或者如果你是root用戶,可以運行:
export KUBECONFIG=/etc/kubernetes/admin.conf
◉您應該在集群上部署一個pod網絡,使用下列選項之一運行kubectl apply -f [podnetwork].yaml:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
選項提供了一個地址,這個地址包含了很多的網絡插件,如圖:
此處本人使用Calico插件,點擊選項可能無法訪問網址,無法下載其對應的yaml文件。使用如下命令下載yaml文件:
curl https://docs.projectcalico.org/manifests/calico.yaml -O
如果無法直接在Linux中下載,可以直接訪問//docs.projectcalico.org/manifests/calico.yaml下載後上傳到主機。然後再使用命令:
kubectl apply -f calico.yaml
創建POD網絡,如圖所示,表示POD網絡創建完成:
等待一段時間使用 ” kubectl get nodes “查看節點狀態,節點將由NotReady–>Ready,如圖:
◉通過在每個節點上複製證書頒發機構和服務帳戶密鑰,然後以root用戶身份運行以下操作,可以加入任意數量的控制平面節點:
kubeadm join 192.168.0.10:6443 --token zh274u.866t6kyo6cpxv40f \ --discovery-token-ca-cert-hash sha256:c87e21c58a669984cd9ae2bd46ba34976584d88948b2445a378b9b6b734641c8 \ --control-plane
◉通過root用戶身份在每個節點上運行以下操作,可以加入任意數量的工作節點:
kubeadm join 192.168.0.10:6443 --token zh274u.866t6kyo6cpxv40f \ --discovery-token-ca-cert-hash sha256:c87e21c58a669984cd9ae2bd46ba34976584d88948b2445a378b9b6b734641c8
根據這些提示完成提示操作後,集群環境就搭建完成了,init成功後的這些提示建議保存,方便後續增加主節點和工作節點。最終查看集群狀態結果如下:
三、在集群中部署應用
待續。。