高可用 kubernetes 集羣部署實踐

前言

Kubernetes(k8s) 憑藉着其優良的架構,靈活的擴展能力,豐富的應用編排模型,成爲了容器編排領域的事實標準。愈來愈多的企業擁抱這一趨勢,選擇 k8s 做爲容器化應用的基礎設施,逐漸將本身的核心服務遷移到 k8s 之上。html

可用性對基礎設施而言相當重要。各大雲計算廠商紛紛推出了高可用、可擴展的 k8s 託管服務,其中比較有表明性的有 Amazon EKSAzure Kubernetes Service (AKS)Google Kubernetes Engine阿里雲容器服務 Kubernetes 版等。node

雖然公有云託管的 k8s 服務百花齊放,但不少企業仍有自建集羣的需求。正是這樣的緣由,促進了一大批出色的 k8s 集羣部署方案的誕生,他們的特色以下表所示。nginx

部署方案 特色
Kubeadm 1. 官方出品的部署工具,提供了 k8s 集羣生命週期管理的領域知識。
2. 旨在成爲更高級別工具的可組合構建塊。
Kubespray 1. 支持在裸機和 AWS、GCE、Azure 等衆多雲平臺上部署 k8s。
2. 基於 Ansible Playbook 定義 k8s 集羣部署任務。
3. 支持大部分流行的 Linux 發行版。
Kops 1. 僅支持在 AWS、GCE 等少數雲平臺上部署 k8s。
2. 創建在狀態同步模型上,用於 dry-run 和自動冪等性。
3. 可以自動生成 Terraform 配置。
Rancher Kubernetes Engine(RKE) 1. 著名的開源企業級容器管理平臺 Rancher 提供的輕量級 k8s 安裝工具。
2. 支持在裸機、虛擬機、公有云上部署和管理 k8s 集羣。

上述方案中,RKE 在易用性和靈活性上佔有優點。本文接下來將介紹如何經過 RKE 部署一套高可用 k8s 集羣,文中使用的 RKE 版本爲v0.2.2git

高可用 k8s 集羣架構

首先須要瞭解高可用 k8s 集羣的架構特色,下圖是官方推薦的高可用集羣架構圖。github

其核心思想是讓 k8s master 節點中的各種組件具有高可用性,消除單點故障。docker

  • kube-apiserver - 對外暴露了 k8s API,是整個集羣的訪問入口。因爲 apiserver 自己無狀態,能夠經過啓動多個實例並結合負載均衡器實現高可用。
  • etcd - 用於存儲 k8s 集羣的網絡配置和對象的狀態信息,是整個集羣的數據中心。能夠經過啓動奇數個 etcd 實例創建一個冗餘的,可靠的數據存儲層。
  • kube-scheduler - 爲新建立的 pod 選擇一個供他們運行的節點。一個集羣只能有一個活躍的 kube-scheduler 實例,能夠同時啓動多個 kube-scheduler 並利用領導者選舉功能實現高可用。
  • kube-controller-manager - 集羣內部的管理控制中心。一個集羣只能有一個活躍的 kube-controller-manager 實例,能夠同時啓動多個 kube-controller-manager 並利用領導者選舉功能實現高可用。

此外,構建集羣的時還須要注意下列問題。api

  • 節點上 k8s 進程的可靠性。須要讓 kubelet、kube-scheduler、kube-controller-manager 等進程在出現故障後能自動重啓。
  • 爲 worker node 中的非 pod 進程預留資源,防止他們將與 pod 爭奪資源致使節點資源短缺。

使用 RKE 構建高可用 k8s 集羣

節點規劃

構建集羣的第一步是將擁有的服務器按節點功能進行劃分,下表展現了筆者環境下的節點規劃狀況。服務器

IP 角色
192.168.0.10 部署節點
192.168.0.11 k8s master - api-server, etcd, scheduler, controller-manager
192.168.0.12 k8s master - api-server, etcd, scheduler, controller-manager
192.168.0.13 k8s master - api-server, etcd, scheduler, controller-manager
192.168.0.14 k8s worker - kubelet, kube-proxy
192.168.0.15 k8s worker - kubelet, kube-proxy
192.168.0.16 k8s worker - kubelet, kube-proxy
192.168.0.17 k8s worker - kubelet, kube-proxy

規劃說明:網絡

  1. 單獨選擇了一臺機器192.168.0.10做爲部署節點。若是機器數很少,能夠將部署節點加入到 k8s 集羣中。
  2. 爲了保證可用性,擇了三臺機器部署 k8s master 組件。若是有條件,能夠將 etcd 和 master 中的其餘組件分開部署,這樣能夠根據須要更靈活地控制實例個數。例如,在訪問壓力不大但對數據可靠性要求比較高的狀況下,能夠專門選擇 5 臺機器部署 etcd,另外選擇 3 臺機器部署 master 中的其餘組件。
  3. 剩餘四臺機器做爲 k8s worker 節點。節點個數須要根據實際狀況動態調整。當有 pod 因資源不足一直處於 pending 狀態時,能夠對 worker 進行擴容。當 node 的資源利用率較低時,且此 node 上存在的 pod 都能被從新調度到其餘 node 上運行時,能夠對 worker 進行縮容。

環境準備

在完成節點規劃後,須要進行環境準備工做,主要包含如下內容:架構

  1. 安裝 RKE - 須要在部署節點(192.168.0.10)上安裝 RKE 二進制包,具體安裝方法可參考 download-the-rke-binary
  2. 配置 SSH 免密登陸 - 因爲 RKE 經過 SSH tunnel 安裝部署 k8s 集羣,須要配置 RKE 所在節點到 k8s 各節點的 SSH 免密登陸。若是 RKE 所在節點也須要加入到 k8s 集羣中,須要配置到本機的 SSH 免密登陸。
  3. 安裝 docker - 因爲 RKE 經過 docker 鏡像rancher/hyperkube啓動 k8s 組件,所以須要在 k8s 集羣的各個節點(192.168.0.11 ~ 192.168.0.17 這 7 臺機器)上安裝 docker。
  4. 關閉 swap - k8s 1.8 開始要求關閉系統的 swap,若是不關閉,默認配置下 kubelet 將沒法啓動。這裏須要關閉全部 k8s worker 節點的 swap。

配置 cluster.yml

在完成環境準備後,須要經過 cluster.yml 描述集羣的組成和 k8s 的部署方式。

配置集羣組成

配置文件 cluster.yml 中的 nodes 配置項用於描述集羣的組成。根據節點規劃,對於 k8s master 節點,指定其角色爲controlplaneetcd。對於 k8s worker 節點,指定其角色爲worker

nodes:
  - address: 192.168.0.1
    user: admin
    role:
      - controlplane
      - etcd
  ...
  - address: 192.168.0.7
    user: admin
    role:
      - worker

設置資源預留

K8s 的 worker node 除了運行 pod 類進程外,還會運行不少其餘的重要進程,包括 k8s 管理進程,如 kubelet、dockerd,以及系統進程,如 systemd。這些進程對整個集羣的穩定性相當重要,所以須要爲他們專門預留必定的資源。

筆者環境中的 worker 設置以下:

  • 節點擁有 32 核 CPU,64Gi 內存和 100Gi 存儲。
  • 爲 k8s 管理進程預留了 1 核 CPU,2Gi 內存和 1Gi 存儲。
  • 爲系統進程預留了 1 核 CPU,1Gi 內存和 1Gi 存儲。
  • 爲內存資源設置了 500Mi 的驅逐閾值,爲磁盤資源設置了 10% 的驅逐閾值。

在此場景下,節點可分配的 CPU 資源是 29 核,可分配的內存資源是 60.5Gi,可分配的磁盤資源是 88Gi。對於不可壓縮資源,當 pod 的內存使用總量超過 60.5Gi 或者磁盤使用總量超過 88Gi 時,QoS 較低的 pod 將被優先驅逐。對於可壓縮資源,若是節點上的全部進程都儘量多的使用 CPU,則 pod 類進程加起來不會使用超過 29 核的 CPU 資源。

上述資源預留設置在 cluster.yml 中具體形式以下。

services:
  kubelet:
    extra_args:
      cgroups-per-qos: True
      cgroup-driver: cgroupfs
      kube-reserved: cpu=1,memory=2Gi,ephemeral-storage=1Gi
      kube-reserved-cgroup: /runtime.service
      system-reserved: cpu=1,memory=1Gi,ephemeral-storage=1Gi
      system-reserved-cgroup: /system.slice
      enforce-node-allocatable: pods,kube-reserved,system-reserved
      eviction-hard: memory.available<500Mi,nodefs.available<10%

關於資源預留更詳細的內容可參考文章 Reserve Compute Resources for System Daemons

部署 k8s 集羣

當 cluster.yml 文件配置完成後,能夠經過命令rke up完成集羣的部署任務。下圖展現了經過 RKE 部署的 k8s 集羣架構圖。

該架構有以下特色:

  1. 集羣中的各個組件均經過容器方式啓動,而且設置重啓策略爲always。這樣當他們出現故障意外退出後,能被自動拉起。
  2. Master 節點上的 kube-scheduler、kube-controller-manager 直接和本機的 API server 通訊。
  3. Worker 節點上的 nginx-proxy 擁有 API server 的地址列表,負責代理 kubelet、kube-proxy 發往 API server 的請求。
  4. 爲了讓集羣具備災備能力,master 節點上的 etcd-rolling-snapshots 會按期保存 etcd 的快照至本地目錄/opt/rke/etcd-snapshots中。

配置負載均衡器

在完成了集羣部署後,能夠經過 API server 訪問 k8s。因爲環境中啓動了多個 kube-apiserver 實例以實現高可用,須要爲這些實例架設一個負載均衡器。這裏在192.168.0.10上部署了一臺 nginx 實現了負載均衡的功能,nginx.conf 的具體配置以下。

...
stream {
    upstream apiserver {
        server 192.168.0.11:6443 weight=5 max_fails=3 fail_timeout=60s;
        server 192.168.0.12:6443 weight=5 max_fails=3 fail_timeout=60s;
        server 192.168.0.13:6443 weight=5 max_fails=3 fail_timeout=60s;
    }

    server {
        listen 6443;
        proxy_connect_timeout 1s;
        proxy_timeout 10s;
        proxy_pass apiserver;
    }
}
...

這時,經過負載均衡器提供的端口訪問 API server 會出現異常Unable to connect to the server: x509: certificate is valid for xxx, not 192.168.0.10。這裏須要將負載均衡器的 IP 地址或域名加入到 API server 的 PKI 證書中,能夠經過 cluster.yml 中的 authentication 配置項完成此功能。

authentication:
  strategy: x509
  sans:
    - "192.168.0.10"

修改完 cluster.yml 後,運行命令rke cert-rotate

驗證

在完成上述全部步驟後,能夠經過命令kubectl get nodes查看節點狀態。若是全部節點的狀態均爲 Ready,則表示集羣部署成功。

NAME            STATUS    ROLES              AGE    VERSION
192.168.0.11    Ready     controlplane,etcd  1d     v1.13.5
192.168.0.12    Ready     controlplane,etcd  1d     v1.13.5
192.168.0.13    Ready     controlplane,etcd  1d     v1.13.5
192.168.0.14    Ready     worker             1d     v1.13.5
192.168.0.15    Ready     worker             1d     v1.13.5
192.168.0.16    Ready     worker             1d     v1.13.5
192.168.0.17    Ready     worker             1d     v1.13.5

總結

Rancher Kubernetes Engine(RKE)爲用戶屏蔽了建立 k8s 集羣的複雜細節,簡化了部署步驟,下降了構建門檻。對於那些有自建 k8s 集羣需求的企業是一個不錯的選擇。


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索