從零開始搭建高可用的k8s叢集

我若安好,便是晴天發表於2022-04-30

一、環境準備

  使用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 官方和國內很多雲服務商都提供了國內加速器服務,此處以配置阿里雲映象加速器為例,登入https://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 https://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": ["https://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中下載,可以直接訪問https://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成功後的這些提示建議儲存,方便後續增加主節點和工作節點。最終檢視叢集狀態結果如下:

三、在叢集中部署應用

待續。。

 

相關文章