基於 MinIO 對象存儲保障 Rancher 數據

作者簡介

謝澤欽,SUSE Rancher 技術支持工程師,負責訂閱客戶的維護與售後技術支持服務,提供相關技術解決方案。擁有 CKA、CKS 官方認證,多年雲計算領域經驗,經歷了從 OpenStack 到 Kubernetes 的技術變革,對底層操作系統、KVM 虛擬化和 Docker 容器等相關雲原生技術擁有豐富的實踐經驗。

前言

Rancher 是一個企業級的 Kubernetes 容器管理平臺,它簡化了使用 Kubernetes 的流程,提供了完整的軟件堆棧,適用於使用容器的團隊。Rancher 解決了跨任何基礎架構管理多個 Kubernetes 集羣的運營和安全挑戰,同時爲 DevOps 團隊提供了運行容器化工作負載的集成工具。

下圖是 Rancher 官方提供的架構圖:

Architecture

從圖中可知 Rancher 的數據是存儲在 etcd 中。

etcd 同時也是 Kubernetes 的關鍵組件,Kubernetes 集羣通過 etcd 存儲了集羣的整個狀態:包括集羣、節點、運行中的工作負載、以及所有 Kubernetes 資源對象的元數據和狀態信息。

在 Rancher 和 Kubernetes 集羣上,每時每刻都有大量的數據讀寫,如何保障 etcd 中的數據成爲了我們需要解決的問題。

本文將介紹如何通過 MinIO 對象存儲的能力,來分別保障 Rancher 和 下游 Kubernetes 的數據。

先決條件

MinIO 快速部署

MinIO 介紹

MinIO 是開源的高性能對象存儲系統,基於 Golang 實現,提供與 Amazon S3 兼容的 API 接口。

MinIO 優點

MinIO 部署

  1. 一鍵生成 ssl 自簽名證書腳本,將下面腳本保存到create-cert.sh文件中。
#!/bin/bash -e

help ()
{
    echo  ' ================================================================ '
    echo  ' --ssl-domain: 生成ssl證書需要的主域名,如不指定則默認爲www.rancher.local,如果是ip訪問服務,則可忽略;'
    echo  ' --ssl-trusted-ip: 一般ssl證書只信任域名的訪問請求,有時候需要使用ip去訪問server,那麼需要給ssl證書添加擴展IP,多個IP用逗號隔開;'
    echo  ' --ssl-trusted-domain: 如果想多個域名訪問,則添加擴展域名(SSL_TRUSTED_DOMAIN),多個擴展域名用逗號隔開;'
    echo  ' --ssl-size: ssl加密位數,默認2048;'
    echo  ' --ssl-cn: 國家代碼(2個字母的代號),默認CN;'
    echo  ' 使用示例:'
    echo  ' ./create_self-signed-cert.sh --ssl-domain=www.test.com --ssl-trusted-domain=www.test2.com \ '
    echo  ' --ssl-trusted-ip=1.1.1.1,2.2.2.2,3.3.3.3 --ssl-size=2048 --ssl-date=3650'
    echo  ' ================================================================'
}

case "$1" in
    -h|--help) help; exit;;
esac

if [[ $1 == '' ]];then
    help;
    exit;
fi

CMDOPTS="$*"
for OPTS in $CMDOPTS;
do
    key=$(echo ${OPTS} | awk -F"=" '{print $1}' )
    value=$(echo ${OPTS} | awk -F"=" '{print $2}' )
    case "$key" in
        --ssl-domain) SSL_DOMAIN=$value ;;
        --ssl-trusted-ip) SSL_TRUSTED_IP=$value ;;
        --ssl-trusted-domain) SSL_TRUSTED_DOMAIN=$value ;;
        --ssl-size) SSL_SIZE=$value ;;
        --ssl-date) SSL_DATE=$value ;;
        --ca-date) CA_DATE=$value ;;
        --ssl-cn) CN=$value ;;
    esac
done

# CA相關配置
CA_DATE=${CA_DATE:-3650}
CA_KEY=${CA_KEY:-cakey.pem}
CA_CERT=${CA_CERT:-cacerts.pem}
CA_DOMAIN=cattle-ca

# ssl相關配置
SSL_CONFIG=${SSL_CONFIG:-$PWD/openssl.cnf}
SSL_DOMAIN=${SSL_DOMAIN:-'www.rancher.local'}
SSL_DATE=${SSL_DATE:-3650}
SSL_SIZE=${SSL_SIZE:-2048}

## 國家代碼(2個字母的代號),默認CN;
CN=${CN:-CN}

SSL_KEY=$SSL_DOMAIN.key
SSL_CSR=$SSL_DOMAIN.csr
SSL_CERT=$SSL_DOMAIN.crt

echo -e "\033[32m ---------------------------- \033[0m"
echo -e "\033[32m       | 生成 SSL Cert |       \033[0m"
echo -e "\033[32m ---------------------------- \033[0m"

if [[ -e ./${CA_KEY} ]]; then
    echo -e "\033[32m ====> 1. 發現已存在CA私鑰,備份"${CA_KEY}"爲"${CA_KEY}"-bak,然後重新創建 \033[0m"
    mv ${CA_KEY} "${CA_KEY}"-bak
    openssl genrsa -out ${CA_KEY} ${SSL_SIZE}
else
    echo -e "\033[32m ====> 1. 生成新的CA私鑰 ${CA_KEY} \033[0m"
    openssl genrsa -out ${CA_KEY} ${SSL_SIZE}
fi

if [[ -e ./${CA_CERT} ]]; then
    echo -e "\033[32m ====> 2. 發現已存在CA證書,先備份"${CA_CERT}"爲"${CA_CERT}"-bak,然後重新創建 \033[0m"
    mv ${CA_CERT} "${CA_CERT}"-bak
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"
else
    echo -e "\033[32m ====> 2. 生成新的CA證書 ${CA_CERT} \033[0m"
    openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}"
fi

echo -e "\033[32m ====> 3. 生成Openssl配置文件 ${SSL_CONFIG} \033[0m"
cat > ${SSL_CONFIG} <<EOM
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
EOM

if [[ -n ${SSL_TRUSTED_IP} || -n ${SSL_TRUSTED_DOMAIN} || -n ${SSL_DOMAIN} ]]; then
    cat >> ${SSL_CONFIG} <<EOM
subjectAltName = @alt_names
[alt_names]
EOM
    IFS=","
    dns=(${SSL_TRUSTED_DOMAIN})
    dns+=(${SSL_DOMAIN})
    for i in "${!dns[@]}"; do
      echo DNS.$((i+1)) = ${dns[$i]} >> ${SSL_CONFIG}
    done

    if [[ -n ${SSL_TRUSTED_IP} ]]; then
        ip=(${SSL_TRUSTED_IP})
        for i in "${!ip[@]}"; do
          echo IP.$((i+1)) = ${ip[$i]} >> ${SSL_CONFIG}
        done
    fi
fi

echo -e "\033[32m ====> 4. 生成服務SSL KEY ${SSL_KEY} \033[0m"
openssl genrsa -out ${SSL_KEY} ${SSL_SIZE}

echo -e "\033[32m ====> 5. 生成服務SSL CSR ${SSL_CSR} \033[0m"
openssl req -sha256 -new -key ${SSL_KEY} -out ${SSL_CSR} -subj "/C=${CN}/CN=${SSL_DOMAIN}" -config ${SSL_CONFIG}

echo -e "\033[32m ====> 6. 生成服務SSL CERT ${SSL_CERT} \033[0m"
openssl x509 -sha256 -req -in ${SSL_CSR} -CA ${CA_CERT} \
    -CAkey ${CA_KEY} -CAcreateserial -out ${SSL_CERT} \
    -days ${SSL_DATE} -extensions v3_req \
    -extfile ${SSL_CONFIG}

echo -e "\033[32m ====> 7. 證書製作完成 \033[0m"
echo
echo -e "\033[32m ====> 8. 以YAML格式輸出結果 \033[0m"
echo "----------------------------------------------------------"
echo "ca_key: |"
cat $CA_KEY | sed 's/^/  /'
echo
echo "ca_cert: |"
cat $CA_CERT | sed 's/^/  /'
echo
echo "ssl_key: |"
cat $SSL_KEY | sed 's/^/  /'
echo
echo "ssl_csr: |"
cat $SSL_CSR | sed 's/^/  /'
echo
echo "ssl_cert: |"
cat $SSL_CERT | sed 's/^/  /'
echo

echo -e "\033[32m ====> 9. 附加CA證書到Cert文件 \033[0m"
cat ${CA_CERT} >> ${SSL_CERT}
echo "ssl_cert: |"
cat $SSL_CERT | sed 's/^/  /'
echo

echo -e "\033[32m ====> 10. 重命名服務證書 \033[0m"
echo "cp ${SSL_DOMAIN}.key tls.key"
cp ${SSL_DOMAIN}.key tls.key
echo "cp ${SSL_DOMAIN}.crt tls.crt"
cp ${SSL_DOMAIN}.crt tls.crt

執行如下命令生成證書,具體用法請參考 Rancher 生成自簽名證書文檔。

chmod +x create-cert.sh
./create-tls.sh --ssl-domain=minio.zerchin.xyz --ssl-size=2048 --ssl-date=3650

其中--ssl-domain爲改爲訪問 minio 的域名。

  1. 創建 minio 文件夾。
mkdir -p /minio/data
mkdir -p /minio/certs/CAs
  1. 將創建的證書複製到證書的目錄下。
cp tls.crt /minio/certs/public.crt
cp tls.key /minio/certs/private.key
cp cacerts.pem /minio/certs/CAs/cacerts.pem
  1. docker run 命令啓動 MinIO。

minio 支持單機部署和集羣部署,這裏使用單機部署的方式。

docker run -itd --net host --name minio --restart unless-stopped -v /minio/data:/data -v /minio/certs:/certs -e MINIO_ROOT_USER=admin -e MINIO_ROOT_PASSWORD=Rancher123 minio/minio server /data --console-address minio.zerchin.xyz:443 --address minio.zerchin.xyz:9000 --certs-dir /certs

參數說明:

MinIO 使用

  1. 訪問 MinIO。

瀏覽器訪問 https://minio.zerchin.xyz

用戶名和密碼是上一步的MINIO_ROOT_USERMINIO_ROOT_PASSWORD中的賬號密碼。

minio-login

  1. 創建 Bucket,命名爲 backup。

minio-create-bucket-1

minio-create-bucket-2

minio-create-bucket-3

  1. 創建訪問用戶。

minio-create-user-1

minio-create-user-2

minio-create-user-3

通過 MinIO 備份和恢復 Rancher 管理的下游 K8s 集羣

Rancher 管理的下游 K8s 集羣有兩種保存快照的方式,一種是直接將下游集羣 etcd 快照備份文件保存在本地存儲,另一種是將下游集羣 etcd 快照備份文件保存在本地,同時拷貝到遠端的 S3 存儲上,這裏我們選擇第二種方式來將 Rancher 管理的下游 K8s 的快照保存在 MinIO 對象存儲。

etcd 快照備份

  1. 編輯下游集羣,在 Etcd 備份存儲 下,選擇 s3。

rancher-k8s-etcd-1

參數說明:

點擊保存,等待集羣進行更新。

  1. 創建下游集羣快照。

    集羣更新完畢後,我們進入集羣,在 Snapshots 下,點擊 立即創建快照 按鈕,就會自動幫我們創建 etcd 快照,並保存到遠程 MinIO 存儲上。

rancher-k8s-etcd-2

  1. 驗證快照是否存儲在 MinIO 中。

rancher-k8s-etcd-minio-1

可以看到,對應的快照文件已經存儲在 backup 桶 - k8s-etcd 目錄 下面了,etcd 快照備份成功。

etcd 快照恢復

  1. 基於快照恢復 k8s 集羣。

rancher-k8s-etcd-restore-1

rancher-k8s-etcd-restore-2

選擇對應的 etcd 快照文件,點擊 Restore 進行恢復,支持三種恢復方式,分別是:

rancher-k8s-etcd-restore-3

左上角出現還原快照說明集羣正在恢復中,等待下游集羣恢復正常即可。

通過 MinIO 備份和恢復 Rancher

從 Rancher v2.5 開始,rancher-backup operator 用來備份和恢復 Rancher。rancher-backup Helm chart 在這裏。

備份還原 operator 需要安裝在 local 集羣中,並且只對 Rancher 應用進行備份。備份和還原操作只在 local Kubernetes 集羣中進行。

Rancher 版本必須是 v2.5.0 及以上,才能使用這種備份和恢復 Rancher 的方法。

將備份恢復到新的 Rancher 設置時,新設置的版本應與進行備份的版本相同。

Rancher Backup 部署

  1. 安裝 Rancher Backup。

    首先進入到 local 集羣中(即 rancher 所在的集羣),在 應用 & 應用市場 - Charts 導航欄下,點擊 Rancher Backups 應用開始安裝。

install-rancher-backup-1

  1. 點擊安裝,這裏安裝的是 2.1.2 版本。

install-rancher-backup-2

  1. 這裏選擇安裝到System項目,然後點擊下一步

install-rancher-backup-3

  1. 選擇默認存儲位置,先選擇無默認存儲位置,點擊安裝按鈕後,開始安裝。

install-rancher-backup-4

  1. 等待幾分鐘,等 rancher backup 的 pod 啓動。(取決於拉取鏡像的速度)

install-rancher-backup-5

創建第一個 Backup

  1. 創建一個 secret,選擇 Opaque 類型。

backup-secret-1

  1. 命名爲 minio-cerd,新增兩條數據,分別爲 accessKeysecretKey ,並保存。

backup-secret-2

backup-secret-3

  1. 在 Rancher 備份 - Backups 導航欄下,點擊右側的創建按鈕,創建第一個 Backup

backup-1

  1. 存儲位置選擇使用 Amazon S3 兼容的對象存儲服務

backup-2

參數說明:

  1. 保存後,會自動發起 rancher 備份請求,同時將備份數據文件保存到 S3 存儲上,當顯示 Completed 時說明已經備份成功。(記錄其中的備份文件名,恢復的時候會用到)

backup-3

  1. 登錄 MinIO,查看備份文件已經保存進來了。

backup-minio-1

基於 Backup 恢復 Rancher

這裏要注意的是,在恢復數據過程中無需在新集羣上安裝 Rancher。如果將 Rancher 恢復到已安裝 Rancher 的新集羣之上,可能會導致問題。

  1. 安裝 RKE 集羣。

    需要安裝與當前 Rancher 集羣相同版本,安裝方法可以參考 Rancher 官方文檔,這裏已經準備好了一個 RKE 集羣,就不再贅述。

  2. 添加 Rancher-Backup 對應的 Helm repo。

helm repo add rancher-charts https://charts.rancher.io
helm repo update
  1. 安裝 rancher-backup  Helm chart,指定相同的 rancher-backup 版本,這裏選擇 2.1.2 版本。
helm install rancher-backup-crd rancher-charts/rancher-backup-crd -n cattle-resources-system --create-namespace --version 2.1.2
helm install rancher-backup rancher-charts/rancher-backup -n cattle-resources-system --version 2.1.2
  1. 查看 rancher-backup pod 狀態是否就緒。
# kubectl -n cattle-resources-system get pods
NAME                              READY   STATUS    RESTARTS   AGE
rancher-backup-74779d9dfd-vjdth   1/1     Running   0          27s
  1. 編寫minio-cerd-secret.yaml文件,配置 MinIO 訪問祕鑰。
apiVersion: v1
kind: Secret
metadata:
  name: minio-cred
  namespace: cattle-resources-system
type: Opaque
data:
  accessKey: <s3 access key base64 編碼>
  secretKey: <s3 secret key base64 編碼>

執行 kubectl 命令添加該 secret。

kubectl create -f minio-cerd-secret.yaml
  1. 編寫 Restore yaml 文件,命名爲restore.yaml
apiVersion: resources.cattle.io/v1
kind: Restore
metadata:
  name: restore-minio
spec:
  backupFilename: minio-backup-da0178a9-bf73-4b4d-a615-863bf7e46689-2022-07-18T17-46-43Z.tar.gz
  prune: false
  storageLocation:
    s3:
      credentialSecretName: minio-cred
      credentialSecretNamespace: cattle-resources-system
      bucketName: backup
      folder: rancher-backup
      endpoint: minio.zerchin.xyz:9000
      endpointCA: |-
        LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURGVENDQWYyZ0F3SUJBZ0lKQUp1Z1pWNVFN
        ...
        ...
        ...
        L2xlRFdzNThVd3FvYWtVc0diQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K

其中參數都跟 Backup 的參數一樣,其中 backupFilename 參數需要指定具體的備份文件名,可以在 Backup 頁面下查看,也可以在 MinIO 頁面下查看。

運行該配置。

kubectl create -f restore.yaml
  1. 查看 Restore 狀態。
kubectl get restore
kubectl logs -n cattle-resources-system --tail 100 -f rancher-backup-xxx-xxx

當 restore crd 狀態變成 Completed 時,說明恢復完成了,如下:

# kubectl get restores.resources.cattle.io 
NAME            BACKUP-SOURCE   BACKUP-FILE                                                                     AGE   STATUS
restore-minio   S3              minio-backup-da0178a9-bf73-4b4d-a615-863bf7e46689-2022-07-18T17-46-43Z.tar.gz   74s   Completed
  1. 接下來用 Helm 安裝 Rancher。

使用與第一個集羣上使用的相同版本的 Helm 來安裝 Rancher。

helm install rancher rancher-stable/rancher -n cattle-system --set xxx --set xxx
  1. 切換 Rancher 前端負載均衡 /DNS 解析到新的 Rancher 節點上。

  2. 登錄 Rancher UI 界面,訪問正常,說明恢復成功。

restore-1

**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/rdvOKws7glVz3RS7yQOoLg