基于 MinIO 对象存储保障 Rancher 数据
Posted RancherLabs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于 MinIO 对象存储保障 Rancher 数据相关的知识,希望对你有一定的参考价值。
作者简介
谢泽钦,SUSE Rancher 技术支持工程师,负责订阅客户的维护与售后技术支持服务,提供相关技术解决方案。拥有 CKA、CKS 官方认证,多年云计算领域经验,经历了从 OpenStack 到 Kubernetes 的技术变革,对底层操作系统、KVM 虚拟化和 Docker 容器等相关云原生技术拥有丰富的实践经验。
前言
Rancher 是一个企业级的 Kubernetes 容器管理平台,它简化了使用 Kubernetes 的流程,提供了完整的软件堆栈,适用于使用容器的团队。Rancher 解决了跨任何基础架构管理多个 Kubernetes 集群的运营和安全挑战,同时为 DevOps 团队提供了运行容器化工作负载的集成工具。
下图是 Rancher 官方提供的架构图:
从图中可知 Rancher 的数据是存储在 etcd 中。
etcd 同时也是 Kubernetes 的关键组件,Kubernetes 集群通过 etcd 存储了集群的整个状态:包括集群、节点、运行中的工作负载、以及所有 Kubernetes 资源对象的元数据和状态信息。
在 Rancher 和 Kubernetes 集群上,每时每刻都有大量的数据读写,如何保障 etcd 中的数据成为了我们需要解决的问题。
本文将介绍如何通过 MinIO 对象存储的能力,来分别保障 Rancher 和 下游 Kubernetes 的数据。
先决条件
- Rancher:2.6.6
- k8s:v1.23.7
MinIO 快速部署
MinIO 介绍
MinIO 是开源的高性能对象存储系统,基于 Golang 实现,提供与 Amazon S3 兼容的 API 接口。
MinIO优点
- 云原生:符合一切云原生云的架构和构建过程,并且包含最新的云计算技术和概念。其中包括支持 Kubernetes 、微服和多租户的的容器技术,让对象存储对于 Kubernetes 更加友好。
- 高性能:在标准硬件上,读/写速度上高达183 GB / 秒 和 171 GB / 秒,拥有更高的吞吐量和更低的延迟。
- 可扩展:扩展从单个群集开始,该群集可以与其他 MinIO 群集联合以创建全局名称空间, 并在需要时可以跨越多个不同的数据中心。
- 易操作:部署简单,简化了使用对象存储的流程,支持多种平台运行。
MinIO 部署
- 一键生成 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 的域名。
- 创建minio文件夹。
mkdir -p /minio/data
mkdir -p /minio/certs/CAs
- 将创建的证书复制到证书的目录下。
cp tls.crt /minio/certs/public.crt
cp tls.key /minio/certs/private.key
cp cacerts.pem /minio/certs/CAs/cacerts.pem
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_ROOT_USER
:设置管理员用户。 -
MINIO_ROOT_PASSWORD
:管理员用户密码。 -
--console-address
:MinIO管理平台地址,当检测到有证书时,自动配置为https。 -
--address
:实际数据传输的地址。 -
--certs-dir
:设置证书目录,默认是$HOME/.minio/certs
这个目录,这里指定成我们挂载的目录。注意证书和秘钥的名字一定要是public.crt
和private.key
。如果有自签名CA证书,则需要放到该路径下的CAs
目录。
MinIO 使用
- 访问 MinIO。
浏览器访问 https://minio.zerchin.xyz
。
用户名和密码是上一步的MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
中的账号密码。
- 创建 Bucket,命名为 backup。
- 创建访问用户。
通过 MinIO 备份和恢复 Rancher 管理的下游 K8s 集群
Rancher 管理的下游 K8s 集群有两种保存快照的方式,一种是直接将下游集群 etcd 快照备份文件保存在本地存储,另一种是将下游集群 etcd 快照备份文件保存在本地,同时拷贝到远端的 S3 存储上,这里我们选择第二种方式来将 Rancher 管理的下游 K8s 的快照保存在 MinIO 对象存储。
etcd 快照备份
- 编辑下游集群,在 Etcd备份存储 下,选择 s3。
参数说明:
-
S3 Bucket Name
:S3的桶名称。 -
S3 Folder
:桶下的文件夹。不填写则直接在桶的根目录下存储数据。 -
S3 Region Endpoint
:指定S3端点URL地址,这里对应前面--address
暴露的地址 -
Access Key
:S3的accessKey -
Secret Key
:S3的secretKey -
自定义 CA 证书
:自定义证书认证,用于连接 S3 端点。
点击保存,等待集群进行更新。
-
创建下游集群快照。
集群更新完毕后,我们进入集群,在Snapshots下,点击 立即创建快照 按钮,就会自动帮我们创建 etcd 快照,并保存到远程 MinIO 存储上。
- 验证快照是否存储在 MinIO 中。
可以看到,对应的快照文件已经存储在 backup 桶 - k8s-etcd 目录 下面了,etcd 快照备份成功。
etcd 快照恢复
- 基于快照恢复 k8s 集群。
选择对应的 etcd 快照文件,点击Restore进行恢复,支持三种恢复方式,分别是:
- 仅恢复 etcd 数据。
- 同时恢复 k8s 版本和 etcd 数据。
- 同时恢复集群配置、k8s 版本和 etcd 数据。
左上角出现还原快照说明集群正在恢复中,等待下游集群恢复正常即可。
通过 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 部署
-
安装 Rancher Backup。
首先进入到 local 集群中(即 rancher 所在的集群),在 应用&应用市场 - Charts 导航栏下,点击 Rancher Backups 应用开始安装。
- 点击安装,这里安装的是 2.1.2 版本。
- 这里选择安装到
System
项目,然后点击下一步
- 选择默认存储位置,先选择无默认存储位置,点击安装按钮后,开始安装。
- 等待几分钟,等 rancher backup 的 pod 启动。(取决于拉取镜像的速度)
创建第一个 Backup
- 创建一个 secret,选择 Opaque 类型。
- 命名为
minio-cerd
,新增两条数据,分别为accessKey
和secretKey
,并保存。
- 在 Rancher 备份 - Backups 导航栏下,点击右侧的创建按钮,创建第一个 Backup。
- 存储位置选择使用 Amazon S3 兼容的对象存储服务。
参数说明:
-
凭证密文
:选择刚刚创建的minio密文。 -
存储桶名称
:S3 的桶名称。 -
文件夹
:桶下的文件夹。不填写则直接在桶的根目录下存储数据。 -
端点
:指定 S3 端点URL地址,这里对应前面--address
暴露的地址 -
端点 CA
:自签名证书需要添加 CA 证书,这里要先用 base64 编码后再填写进来。
- 保存后,会自动发起 rancher 备份请求,同时将备份数据文件保存到 S3 存储上,当显示 Completed 时说明已经备份成功。(记录其中的备份文件名,恢复的时候会用到)
- 登录 MinIO,查看备份文件已经保存进来了。
基于 Backup 恢复 Rancher
这里要注意的是,在恢复数据过程中无需在新集群上安装 Rancher。如果将 Rancher 恢复到已安装 Rancher 的新集群之上,可能会导致问题。
-
安装 RKE 集群。
需要安装与当前 Rancher 集群相同版本,安装方法可以参考 Rancher 官方文档,这里已经准备好了一个 RKE 集群,就不再赘述。
-
添加 Rancher-Backup 对应的 Helm repo。
helm repo add rancher-charts https://charts.rancher.io
helm repo update
- 安装 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
- 查看 rancher-backup pod 状态是否就绪。
# kubectl -n cattle-resources-system get pods
NAME READY STATUS RESTARTS AGE
rancher-backup-74779d9dfd-vjdth 1/1 Running 0 27s
- 编写
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
- 编写 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
- 查看 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
- 接下来用 Helm 安装 Rancher。
使用与第一个集群上使用的相同版本的 Helm 来安装 Rancher。
helm install rancher rancher-stable/rancher -n cattle-system --set xxx --set xxx
-
切换 Rancher 前端负载均衡 /DNS 解析到新的 Rancher 节点上。
-
登录 Rancher UI 界面,访问正常,说明恢复成功。
以上是关于基于 MinIO 对象存储保障 Rancher 数据的主要内容,如果未能解决你的问题,请参考以下文章