一文讀懂如何部署具有外部數據庫的高可用 K3s

介紹

您是否在以高可用模式部署 Kubernetes 並配置遠程備份數據庫時遇到了困難?本文將爲您介紹如何在具有外部數據庫 Postgres 的 HA 配置中部署 K3s。

K3s(https://k3s.io/)是用於物聯網和邊緣計算的認證 Kubernetes 發行版。我將它部署在 IBM Z 大型機中的虛擬機上。我沒有選擇 etcd,而是使用了 Postgres 作爲 K3s 集羣的存儲方案。我以非 HA 模式部署了 Postgres。想了解如何在 HA 模式下部署 Postgres 的信息,請參閱官方文檔:https://www.postgresql.org/docs/13/high-availability.html

Postgres 和 K3s 集羣之間的通信是 SSL 安全的。我在 K3s server 前面的第 4 層使用了 Nginx 進行負載均衡。我們以後可能需要添加新的服務器節點或關閉服務器。因此,如果不使用 K3s Server IP 而是使用負載均衡器,我們就能避免這類麻煩,還可以實現 HA。請注意,Nginx 負載均衡器也可能成爲單一故障點。有關在 HA 模式下部署 Nginx,請參閱文檔:https://www.nginx.com/products/nginx/high-availability/

HA 配置

下圖描述了我在 HA 模式下部署具有兩個節點的 K3s 集羣的方式。即使一臺 Server 出現故障,另一臺 Server 仍然可以訪問,而且負載均衡器能將所有請求路由到可訪問的 Server。由於 K3s 的所有組件都是無狀態的,即使 Server 出現故障,我們也不會丟失任何信息。所有信息都存儲在 Postgres 中,並且必須是 HA。

具有負載均衡器和數據庫的 K3s HA 模式

環境

在開始之前,你需要以下環境:

操作系統 - SLE15SP2 虛擬機 - 5 VCPU - 2 RAM - 8 GB 磁盤 - 30 GB Arch - s390x

以下是我使用的各個虛擬機的 IP 地址,你可以隨時在本文查閱這些 IP 地址代表的含義:

K3s Server 1 - 10.161.129.54K3s Server 2 - 10.161.129.154K3s Agent - 10.161.129.196Postgres - 10.161.129.212Nginx - 10.161.129.118

我在大型機 (s390x) 虛擬機中部署,你也可以在其他任何架構上使用相同的命令。現在,我們來看看安裝 Postgres 和 K3s 集羣的命令。

安裝 Postgres

我在其中一臺虛擬機上安裝了 postgres10。我們將該虛擬機命名爲 Postgres。你可以複製粘貼以下命令來安裝 Postgres。爲了安全起見,請確保 Postgres 數據庫和 K3s 集羣之間存在相互 TLS 通信。我使用了自簽名證書來識別使用 OpenSSL 創建的 Postgres。

Postgres 虛擬機

zypper -n in postgresql10 postgresql10-server
systemctl start postgresql
sudo -u postgres psql
create database K3s;
create user K3s with encrypted password 'K3s';
grant all privileges on database K3s to K3s;
exit;

我們將使用 K3s 數據庫來存儲集羣信息。我們使用 K3s 用戶來爲 K3s 集羣進行 Postgres 數據庫身份驗證。

openssl req -new -x509 -days 365 -nodes -text -out /var/lib/pgsql/data/postgres.crt   -keyout /var/lib/pgsql/data/postgres.key -subj "/CN=postgres.rancher.rke2" -addext "subjectAlt
chmod 0600 /var/lib/pgsql/data/postgres.key
chown postgres:postgres /var/lib/pgsql/data/postgres.key
scp /var/lib/pgsql/data/postgres.crt sles@10.161.129.54:
scp /var/lib/pgsql/data/postgres.crt sles@10.161.129.154:
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections onlyf
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
hostssl all             all             0.0.0.0/0               md5 clientcert=verify-full

該文件的內容表明,localhost 連接無需密碼或 SSL 通信即可連接到數據庫。但是,Postgres 的所有其他連接則必須通過 SSL 客戶端驗證(K3s Server 是 Postgres 的客戶端)和密碼驗證才能進行通信。

在進一步設置 Postgres 數據庫之前,我們先創建標識 K3s 集羣的證書並將證書複製到 Postgres 虛擬機,以便 Postgres 驗證 K3s Server。

K3s Server 1 虛擬機

openssl req -new -x509 -days 365 -nodes -text -out K3s.crt -keyout K3s.key -subj "/CN=K3s" -addext "subjectAlt
chmod 0600 K3s.key
scp /home/sles/K3s.crt sles@10.161.129.212:
scp /home/sles/K3s.crt /home/sles/K3s.key sles@10.161.129.154:

接下來,我們繼續看 Postgres 虛擬機。

Postgres 虛擬機

mv /home/sles/K3s.crt /var/lib/pgsql/data/
listen_addresses = '*'
ssl = on
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
#ssl_prefer_server_ciphers = on
#ssl_ecdh_curve = 'prime256v1'
#ssl_dh_params_file = ''
ssl_cert_file = '/var/lib/pgsql/data/postgres.crt'
ssl_key_file = '/var/lib/pgsql/data/postgres.key'
ssl_ca_file = '/var/lib/pgsql/data/K3s.crt'

listen_addresses:設置爲 * 或 Postgres 服務器的 IP。這樣能確保 Postgres 服務器能偵聽節點的 IP 地址。

ssl:打開 SSL 來僅使用安全的方式進行通信。

ssl_cert_file ssl_key_file:標識 Postgres 數據庫的證書。我已經在文章開頭創建了證書,現在只需要將它們指向證書位置即可。

ssl_ca_file:這是一個 CA(證書頒發機構)證書,用於識別 Postgres 的客戶端。在我們的示例中,K3s 是客戶端。因此,我爲 K3s 創建了一個自簽名證書,並將 ssl_ca_file 指向 K3s 集羣的自簽名公共證書。

systemctl restart postgresql

我們已成功部署了 Postgres 數據庫,現在我們轉到 K3s 虛擬機並在那裏安裝 K3s。

K3s Server 1 虛擬機

curl -sfL https://get.k3s.io | sh -s - server --datastore-endpoint="postgres://K3s:K3s@postgres.rancher.rke2:5432/K3s" --datastore-cafile="/home/sles/postgres.crt" --token=K3s --datastore-certfile="/home/sles/K3s.crt" --datastore-keyfile="/home/sles/K3s.key" --tls-san=10.161.129.118

--datastore-endpoint:Postgres 的格式是 postgres://username:password@hostname:port/database-name。在這個示例中,我創建了一個 K3s 角色,密碼是 K3s,數據庫名稱也是 K3s。我使用了 postgres.rancher.rke 作爲 hostname,因爲證書是使用 CN 值作爲名稱創建的。

--datastore-cafile:設爲 Postgres 的公鑰證書,以便 K3s 使用該證書驗證 Postgres。在自簽名證書中,公共證書充當 CA,可以進行自我驗證。

--datastore-certfile:這是標識 K3s 集羣的公共證書。

--datastore-keyfile:屬於 K3s 集羣的私鑰。

--token:將創建一個 Secret 密碼,以便其他服務器或 Agent 連接到此 K3s 集羣。

--tls-san:負載均衡器的 IP 地址。

10.161.129.212  postgres.rancher.rke2

其中 10.161.129.212 是 Postgres 服務器的 IP 地址。

export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get pods -A

你應該會看到所有處於 running 狀態的 pod。如果沒有,你可以運行:

journalctl -xe

這能讓你查看安裝 K3s Server 時發生的錯誤。

K3s Server 2 虛擬機

curl -sfL https://get.k3s.io | sh -s - server --datastore-endpoint="postgres://K3s:K3s@postgres.rancher.rke2:5432/K3s" --datastore-cafile="/home/sles/postgres.crt" --token=K3s --datastore-certfile="/home/sles/K3s.crt" --datastore-keyfile="/home/sles/K3s.key" --tls-san=10.161.129.118
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get pods -A

結果應與以下內容類似:

NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE
kube-system   svclb-traefik-55frd                       2/2     Running   0          11m
kube-system   svclb-traefik-x59vc                       2/2     Running   0          2m43s
kube-system   local-path-provisioner-6c79684f77-55tkc   1/1     Running   0          107s
kube-system   coredns-d76bd69b-5n8s7                    1/1     Running   0          107s
kube-system   traefik-df4ff85d6-88phx                   1/1     Running   0          107s
kube-system   metrics-server-7cd5fcb6b7-x7t2r           1/1     Running   0          107s
kubectl get nodes

結果應與以下內容類似:

NAME           STATUS   ROLES                  AGE   VERSION
k3s-server-1   Ready    control-plane,master   14m   v1.23.6+K3s1
k3s-server-2   Ready    control-plane,master   29s   v1.23.6+K3s1

在連接到調度工作負載的 K3s Agent 之前,我們需要在 Server 前面添加一個負載均衡器,以便用戶或 K3s Agent 與其通信。

Nginx 負載均衡器虛擬機

我在網絡堆棧第 4 層的 K3s 集羣 Server 節點前面使用了 Nginx。我們會將端口 6443 的所有請求轉發到負載均衡器,然後再發送其中一臺 K3s Server。Kubernetes API server 會偵聽該端口。

zypper in nginx
load_module /usr/lib64/nginx/modules/ngx_stream_module.so;

worker_processes 4;
worker_rlimit_nofile 40000;


events {
 worker_connections 8192;
}

stream {
 log_format logs '$remote_addr - - [$time_local] $protocol $status $bytes_sent $bytes_received $session_time "$upstream_addr"';

 access_log /var/log/nginx/access.log logs;

 upstream K3s_api_server {
  least_conn;
  server 10.161.129.54:6443 max_fails=fail_timeout=5s;
  server 10.161.129.154:6443 max_fails=fail_timeout=5s;
 }
 server {
  listen 6443;
  proxy_pass K3s_api_server;
 }
}

我們使用 least_conn 算法來決定請求應該發送到哪個 K3s Server。Nginx 將根據該算法將請求路由到具有最少 active 連接的 Server。

nginx -s reload
systemctl reload nginx && systemctl restart nginx

至此,我們已設置了負載均衡器,因此現在任何人都可以與我們的 K3s Server 通信。現在我們添加一個 K3s Agent,Agent 會與這個負載均衡器通信並註冊 Agent。

K3s Agent 虛擬機

--server:負載均衡器 IP 地址。

curl -sfL https://get.k3s.io | sh -s - agent --token=K3s --server https://10.161.129.118:6443

K3s Server 1 虛擬機

kubectl get nodes

結果應與以下內容類似:

NAME           STATUS   ROLES                  AGE    VERSION
k3s-server-1   Ready    control-plane,master   41m    v1.23.6+K3s1
k3s-server-2   Ready    control-plane,master   28m    v1.23.6+K3s1
k3s-agent      Ready    <none>                 105s   v1.23.6+K3s1

我們已經成功安裝了 Postgres、K3s Server 和一個 K3s Agent。你現在擁有了一個具有外部數據庫的 HA K3s 集羣。請注意,只有部署了 Postgres 和 Nginx 時才能實現完全 HA。有關更多信息,你可以查看參考中的鏈接。

參考


**About SUSE Rancher
**

Rancher 是一個開源的企業級 Kubernetes 管理平臺,實現了 Kubernetes 集羣在混合雲 + 本地數據中心的集中部署與管理。Rancher 一向因操作體驗的直觀、極簡備受用戶青睞,被 Forrester 評爲 “2020 年多雲容器開發平臺領導廠商” 以及“2018 年全球容器管理平臺領導廠商”,被 Gartner 評爲“2017 年全球最酷的雲基礎設施供應商”。

目前 Rancher 在全球擁有超過三億的核心鏡像下載量,並擁有包括中國聯通、中國平安、中國人壽、上汽集團、三星、施耐德電氣、西門子、育碧遊戲、LINE、WWK 保險集團、澳電訊公司、德國鐵路、廈門航空、新東方等全球著名企業在內的共 40000 家企業客戶。

2020 年 12 月,SUSE 完成了對 RancherLabs 的收購,Rancher 成爲了 SUSE "創新無處不在 (Innovate Everywhere)" 企業願景的關鍵組成部分。SUSE 和 Rancher 共同爲客戶提供了無與倫比的自由和所向披靡的創新能力,通過混合雲 IT 基礎架構、雲原生轉型和 IT 運維解決方案,簡化、現代化並加速企業數字化轉型,推動創新無處不在。

當前,SUSE 及 Rancher 在中國大陸及港澳臺地區的業務,均由數碩軟件(北京)有限公司承載。SUSE 在國內擁有優秀的研發團隊、技術支持團隊和銷售團隊,將結合 Rancher 領先的雲原生技術,爲中國的企業客戶提供更加及時和可信賴的技術支撐及服務保障。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/I4MoRbgueztHGr7M7Thzcg