MinIO部署准备
部署概述
本实验结合Kubernetes进行MinIO部署,实现MinIO于Kubernetes的融合。
minio官方支持通过简单的快速部署,以便于进行基础测试:
curl https://raw.githubusercontent.com/minio/docs/master/source/extra/examples/minio-dev.yaml -O
kubectl apply -f minio-dev.yaml
参考官方: 快速部署MinIO 。
本实验基于生产环境,部署一套可用于生产环境的多租户Minio。
MinIO官方推荐使用minio-operator部署多租户的minio系统。
每个 MinIO Tenant 代表 Kubernetes 集群中的一个独立的 MinIO Object Store。
部署架构
官方最佳实践推荐的架构如下:
前期规划
Kubernetes 安装
本实验不涉及 Kubernetes 部署, Kubernetes 部署参考 Kubernetes_v1.30.3高可用部署架构二 。
已完成部署的Kubernetes集群的规划及相关信息如下:
集群VIP: 172.24.10.100
相关域名均能正常解析,可通过hosts解析相关域名至 VPI 。
helm 安装
生产环境下的 minio 官方建议使用 helm 部署,因此需要提前在 Kubernetes 中部署 helm 工具。
参考: Kubernetes集群管理-Helm部署及使用 。
MinIO Operator 组件
Minio Operator 介绍
部署 minio 之前,需要完成 minio operator 的部署,本实验使用最新稳定 Operator 版本 6.0.2。
MinIO Operator 会安装一个 Custom Resource Definition ( CRD )来支持将 MinIO 租户描述为 Kubernetes object 。
MinIO Operator 存在于它独立的命名空间中,并在其中创建 Kubernetes 资源,这些资源包括 pod 、 svc 、 replicasets 和 deployments 。
默认情况下,Operator pods 使用 MinIO CRD 监视对象的所有命名空间,并自动管理这些资源。
当使用 Operator 创建租户时,该租户必须拥有自己的命名空间,在该命名空间中,Operator 生成租户配置所需的 pod 。
每个Tenant pod运行三个容器:
- MinIO 容器运行所有标准 MinIO 功能的容器,相当于裸机上的基本 MinIO 安装。这个容器在提供的挂载点(pv)中存储和检索object。
- InitContainer,仅在启动 pod 期间存在,用于管理启动期间的配置secret,启动完成后,此容器终止。
- Sidecar container 用于初始化MinIO租,sidecar 检索并验证每个租户的配置,并在 pod 中创建必要的本地资源。
在Operator 6.0.0 开始, Sidecar 有自己的 image 和释放周期,与 MinIO Operator 的其他部分分开。
MinIO Operator 将租户的环境变量存储在sidecar中,允许 Operator 在不需要滚动重启的情况下更新变量。
租户使 pvc 与存储对象的持久卷进行通信。
提示:
1:官方也支持 kubectl -k 和 kubectl --kustomize 部署,可以参考:Deploy the MinIO Operator 。本实验有限采用helm安装,也可参考: Deploy Operator With Helm 。
2:但若使用 Helm chart安装 Operator ,则必须使用 Helm 来管理该安装过程。不要使用kubectl krew、Kustomize或类似的方法来更新或管理 MinIO Operator 的安装。
Kubernetes TLS 证书
MinIO Operator 自动生成 TLS 证书签名请求( CSR )并使用 Kubernetes certificates.k8s.io TLS 证书管理 API创建签名的 TLS 证书。
因此 MinIO Operator要求 Kubernetes kube-controller-manager 配置包括以下配置设置:
- --cluster-signing-key-file :指定用于签署集群范围证书的 PEM 编码的 RSA 或 ECDSA 私钥。
- --cluster-signing-cert-file :指定用于颁发集群范围证书的 PEM 编码的 x.509 证书颁发机构证书。
如果 Kubernetes 集群未配置为相应生成的 CSR ,则 Operator 无法完成初始化。
默认情况下,Kubernetes 已完成如上自动挡配置,可通过下方式检查当前 Kubernetes 集群是否配置了 TLS 证书。
kubectl get pod kube-controller-manager-$CLUSTERNAME-control-plane -n kube-system -o yaml
提示:MinIO Operator 使用指定的证书颁发机构( CA )为所有 MinIO 租户 pod 自动生成 TLS 证书。Kubernetes 集群外部的客户端必须信任 Kubernetes 集群 CA 才能连接到 MinIO Operator 或 MinIO 租户。
不能信任 Kubernetes 集群 CA 的客户端可以尝试禁用连接 MinIO Operator 或 MinIO Tenant 的 TLS 验证。
也可以生成由已知且受信任的 CA 签署的 x.509 TLS 证书,并将这些证书传递给 MinIO 租户。
添加repo
使用 helm 添加 minio chart repo。
[root@master01 ~]# mkdir ten-minio
[root@master01 ~]# cd ten-minio
[root@master01 ten-minio]# helm repo add minio-operator https://operator.min.io
[root@master01 ten-minio]# helm repo update
[root@master01 ten-minio]# helm search repo minio-operator
NAME CHART VERSION APP VERSION DESCRIPTION
minio-operator/minio-operator 4.3.7 v4.3.7 A Helm chart for MinIO Operator
minio-operator/operator 6.0.3 v6.0.3 A Helm chart for MinIO Operator
minio-operator/tenant 6.0.3 v6.0.3 A Helm chart for MinIO Operator
提示:国内可以使用 helm repo add minio-operator https://operator.minio.org.cn
进行添加。
minio-operator/minio-operator是一个旧版本的 operator ,不需要安装。
安装 operator
运行 helm install 命令安装 operator 。
以下命令指定并创建了一个专用 minio-operator 命名空间进行安装。
[root@master01 ten-minio]# helm show values minio-operator/operator > operator-values.yaml #可选,导出默认chart values
[root@master01 ten-minio]# cat operator-values.yaml
[root@master01 ten-minio]# helm install \
--namespace minio-operator \
--create-namespace \
operator minio-operator/operator
验证 operator
验证 operator 安装情况。
[root@master01 ten-minio]# kubectl get all -n minio-operator #查看安装后的资源
NAME READY STATUS RESTARTS AGE
pod/minio-operator-95fd896dc-cdt84 1/1 Running 0 2m6s
pod/minio-operator-95fd896dc-rfjsr 1/1 Running 0 2m6s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/operator ClusterIP 10.20.194.160 <none> 4221/TCP 2m7s
service/sts ClusterIP 10.20.24.158 <none> 4223/TCP 2m7s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/minio-operator 2/2 2 2 2m7s
NAME DESIRED CURRENT READY AGE
replicaset.apps/minio-operator-95fd896dc 2 2 2 2m7s
持久卷
MinIO 要求专用于给对象存储的驱动器或卷的访问,本实验使用本地盘 /dev/nvme0n2 ,该磁盘独立用于部署minio。
提示:该专属磁盘用于部署minio分布式存储,其他任何进程、软件、脚本等都不得执行任何操作,也不得对MinIO放置在其上的对象或文件执行操作,否则可能带来数据破坏的风险。
MinIO 可以使用任何支持 ReadWriteOnce 访问模式的 Kubernetes PV。
MinIO 的一致性保证要求独占存储访问,而 ReadWriteOnce 正是提供这种支持。
此外,MinIO 建议为 PVC StorageClass 设置 Retain 回收策略,同时建议在配置storage class、CSI或者基于PV的存储的时候,将卷格式化为 XFS 以确保最佳性能。
MinIO可以使用任何支持ReadWriteOnce访问模式的Kubernetes Persistent Volume (PV)。
MinIO的一致性保证需要ReadWriteOnce提供的独占存储访问,在部署租户之前,持久卷必须已经存在。
此外,MinIO建议为PVC StorageClass设置Retain的回收策略,在最佳实践下,配置StorageClass、CSI或PV底层的其他提供程序,建议将卷格式化为XFS,以确保最佳性能。
对于节点具有直接连接存储的Kubernetes集群,MinIO强烈建议使用DirectPV CSI驱动程序。
DirectPV提供了一个分布式持久卷管理器,它可以发现、格式化、挂载、调度和监视Kubernetes节点上的驱动器,DirectPV解决了手动配置和监控本地持久卷的限制。
详细 DirectPV 使用见: 002.DirectPV介绍及安装 和 003.DirectPV存储管理 。
本实验已完成directpv的安装,相关信息如下:
[root@master01 ten-minio]# kubectl -n directpv get all
NAME READY STATUS RESTARTS AGE
pod/controller-79f6b96bf8-t9c4l 3/3 Running 0 25m
pod/controller-79f6b96bf8-vrb2q 3/3 Running 0 25m
pod/controller-79f6b96bf8-x76gj 3/3 Running 0 25m
pod/node-server-4tj7p 4/4 Running 0 25m
pod/node-server-67c7b 4/4 Running 0 25m
pod/node-server-cjhd5 4/4 Running 0 25m
pod/node-server-k6ks2 4/4 Running 0 25m
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/node-server 4 4 4 4 4 <none> 25m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 3/3 3 3 25m
NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-79f6b96bf8 3 3 3 25m
[root@master01 ten-minio]# kubectl -n directpv get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
directpv-min-io directpv-min-io Delete WaitForFirstConsumer true 26m
创建租户namespace
创建模拟多租户的命名空间。
[root@master01 ten-minio]# vim minio-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: minio-ns01
labels:
name: minio-ns01
[root@master01 ten-minio]# kubectl apply -f minio-ns.yaml
MinIO Helm部署
helm概述
Helm是一个自动将应用程序部署到Kubernetes集群的工具,参考:053.Kubernetes集群管理-Helm部署及使用 。
Helm charts是一组定义部署细节的YAML文件、模板和其他需要的文件。
如下过程使用Helm Chart来部署由MinIO Operator管理的租户。
这个过程需要Kubernetes集群有一个有效的Operator部署,不能使用MinIO Operator租户chart来部署独立于Operator的租户。
提示:MinIO Operator 租户 Chart与社区管理的MinIO chart不同。
社区 Helm Chart 由社区建立、维护和支持。
MinIO不保证支持任何给定的错误、特性请求或引用该chart的更新带来的问题。
Operator 租户 Chart 由 MinIO 正式维护和支持,MinIO 强烈建议在生产环境中使用 Operator 和 tenant 的官方 Helm Chart 。
先决条件
安装一个带 Helm 的 MinIO tenant ,需要满足以下要求:
- 可用的Kubernetes集群;
- 与 Kubernetes 集群匹配的kubectl CLI工具;
- Hlem 3.8 或更高版本;
- yq 4.18.1 或更高版本;
- 已安装 MinIO Operator。
此安装必须具备Kubernetes集群访问管理权限。
Helm Charts部署MinIO Tenant
如下使用官方的 MinIO Tenant chart进行部署 MinIO 租户,与本地chart安装相比,此方法支持简化的安装路径。
如下的步骤是使用Helm根据官方的MinIO Tenant chart部署MinIO租户。
更多chart配置参考:MinIO Server Config Guide 。
验证MinIO Operator
添加repo参考: 添加repo
配置helm
配置相关helm vaule 。
[root@master01 ten-minio]# curl -sLo tenant-values.yaml https://raw.githubusercontent.com/minio/operator/master/helm/tenant/values.yaml
提示:如果使用 Helm 部署 MinIO tenant ,则必须使用 Helm 来管理或升级该部署。不要使用kubectl krew、Kustomize或类似的方法来管理或升级 MinIO tenant 。
2:也可使用 helm 命令导出 minio chart 的默认 values.yaml 。
[root@master01 ten-minio]# helm show values minio-operator/tenant > tenant-values.yaml
配置租户拓扑
pool[0]前缀控制部署在租户中的所有pod的服务器数量、每个服务器的卷数量和存储类。
配置说明:
[root@master01 ten-minio]# vim tenant-values.yaml
tenant:
name: tenant-01
pools:
- servers: 4
volumesPerServer: 4
name: pool-0
size: 2Gi #受限于实验磁盘空间,调整为2Gi
storageClassName: directpv-min-io #指定使用directpv创建的sc
配置亲和/或反亲和
Tenant Chart 支持以下 Kubernetes Selector、亲和性和反亲和性配置:
- 节点选择器 (tenant.nodeSelector)
- 节点/Pod 亲和性或反亲和性 (spec.pools[n].affinity)
MinIO 建议为租户配置 Pod 反亲和性,以确保 Kubernetes 调度程序不会将多个 Pod 部署到同一台工作节点上。
如果需要将 Pod 部署到特定的工作节点上,可将这些节点的标签或筛选器传递给 nodeSelector 或 affinity 字段,以限制调度程序将 Pod 部署到这些节点上。
[root@master01 ten-minio]# kubectl label nodes worker0{1,2,3,4} tenant-minio=enabled #根据部署规划给节点打标签
tenant:
pools:
- servers: 4
name: pool-0
size: 2Gi #受限于实验磁盘空间,调整为2Gi
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: tenant-minio
operator: In
values:
- enabled
配置TLS证书
MinIO租户CRD提供以下字段,使用相应字段配置租户TLS网络加密:
提前创建证书。
[root@master01 ten-minio]# ll *com*
-rw-r--r-- 1 root root 3.9K Aug 24 06:19 api.linuxsb.com.crt
-rw-r--r-- 1 root root 1.7K Aug 24 06:19 api.linuxsb.com.key
-rw-r--r-- 1 root root 3.9K Aug 24 05:36 minio.linuxsb.com.crt
-rw-r--r-- 1 root root 1.7K Aug 24 05:36 minio.linuxsb.com.key
[root@master01 ten-minio]# kubectl -n minio-ns01 create secret tls minio-webui-tls --cert=minio.linuxsb.com.crt --key=minio.linuxsb.com.key
[root@master01 ten-minio]# kubectl -n minio-ns01 create secret tls minio-api-tls --cert=api.linuxsb.com.crt --key=api.linuxsb.com.key
[root@master01 ten-minio]# kubectl -n minio-ns01 describe secrets minio-webui-tls
[root@master01 ten-minio]# kubectl -n minio-ns01 describe secrets minio-api-tls
关闭 cert-manager 自动证书。
certificate:
externalCaCertSecret: [ ]
externalCertSecret: [ ]
requestAutoCert: false
certConfig: { }
配置环境变量
可以使用tenant.configuration设置MinIO Server环境变量。
本设置可以设置minio相关用户和密码,本实验保持默认minio/minio123 。
配置ingress
配置ingress规则,将集群内minio对外暴露。
ingress:
api:
enabled: true
ingressClassName: "nginx"
labels: { }
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
tls:
- hosts:
- 'api.linuxsb.com'
secretName: minio-api-tls
host: api.linuxsb.com
path: /
pathType: Prefix
console:
enabled: true
ingressClassName: "nginx"
labels: { }
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
tls:
- hosts:
- 'minio.linuxsb.com'
secretName: minio-webui-tls
host: minio.linuxsb.com
path: /
pathType: Prefix
完整values.yaml如下:
tenant:
name: tenant-01
image:
repository: quay.io/minio/minio
tag: RELEASE.2024-08-17T01-24-54Z
pullPolicy: IfNotPresent
imagePullSecret: { }
scheduler: { }
configuration:
name: myminio-env-configuration
configSecret:
name: myminio-env-configuration
accessKey: minio
secretKey: minio123
pools:
- servers: 4
name: pool-0
volumesPerServer: 4
size: 2Gi
storageClassName: directpv-min-io
storageAnnotations: { }
annotations: { }
labels: { }
tolerations: [ ]
nodeSelector: { }
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: tenant-minio
operator: In
values:
- enabled
resources: { }
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: "OnRootMismatch"
runAsNonRoot: true
containerSecurityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
topologySpreadConstraints: [ ]
mountPath: /export
subPath: /data
metrics:
enabled: false
port: 9000
protocol: http
certificate:
externalCaCertSecret: [ ]
externalCertSecret: [ ]
requestAutoCert: false
certConfig: { }
features:
bucketDNS: false
domains: { }
enableSFTP: false
buckets: [ ]
users: [ ]
podManagementPolicy: Parallel
liveness: { }
readiness: { }
startup: { }
lifecycle: { }
exposeServices: { }
serviceAccountName: ""
prometheusOperator: false
logging: { }
serviceMetadata: { }
env: [ ]
priorityClassName: ""
additionalVolumes: [ ]
additionalVolumeMounts: [ ]
ingress:
api:
enabled: true
ingressClassName: "nginx"
labels: { }
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
tls:
- hosts:
- 'api.linuxsb.com'
secretName: minio-api-tls
host: api.linuxsb.com
path: /
pathType: Prefix
console:
enabled: true
ingressClassName: "nginx"
labels: { }
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
tls:
- hosts:
- 'minio.linuxsb.com'
secretName: minio-webui-tls
host: minio.linuxsb.com
path: /
pathType: Prefix
正式部署
使用配置好的values.yaml进行部署。
[root@master01 ten-minio]# helm install \
--namespace minio-ns01 \
--create-namespace \
--values tenant-values.yaml tenant-01 minio-operator/tenant
确认验证
确认相关部署成功。
- 部署情况验证
查看minio。
[root@master01 ten-minio]# kubectl get all -n minio-ns01 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/tenant-01-pool-0-0 2/2 Running 0 6m6s 10.10.5.9 worker01 <none> <none>
pod/tenant-01-pool-0-1 2/2 Running 0 6m6s 10.10.30.65 worker02 <none> <none>
pod/tenant-01-pool-0-2 2/2 Running 0 6m6s 10.10.196.79 worker04 <none> <none>
pod/tenant-01-pool-0-3 2/2 Running 0 6m5s 10.10.19.79 worker03 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/minio ClusterIP 10.20.208.139 <none> 80/TCP 6m7s v1.min.io/tenant=tenant-01
service/tenant-01-console ClusterIP 10.20.114.138 <none> 9090/TCP 6m7s v1.min.io/tenant=tenant-01
service/tenant-01-hl ClusterIP None <none> 9000/TCP 6m7s v1.min.io/tenant=tenant-01
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/tenant-01-pool-0 4/4 6m6s minio,sidecar quay.io/minio/minio:RELEASE.2024-08-17T01-24-54Z,quay.io/minio/operator-sidecar:v6.0.2
[root@master01 ten-minio]# kubectl -n minio-ns01 get ingress -o wide
NAME CLASS HOSTS ADDRESS PORTS AGE
tenant-01 nginx api.linuxsb.com 172.24.10.11 80, 443 6m31s
tenant-01-console nginx minio.linuxsb.com 172.24.10.11 80, 443 6m31s
查看directpv。
[root@master01 ten-minio]# kubectl -n minio-ns01 get pvc
[root@master01 ten-minio]# kubectl directpv list drives
- 浏览器验证
使用浏览器访问 https://minio.linuxsb.com ,默认minio账号密码: minio / minio123 。
- MC验证
MinIO Client mc命令行工具提供了ls、cat、cp、mirror和diff等命令,支持文件系统和Amazon s3兼容的云存储服务。
mc命令行工具是为与AWS S3 API兼容而构建的,并在MinIO和AWS S3上测试了预期的功能和行为。
安装mc:
[root@master01 minio]# curl https://dl.min.io/client/mc/release/linux-amd64/mc \
--create-dirs \
-o /usr/local/bin/mc
[root@master01 minio]# chmod +x /usr/local/bin/mc
[root@master01 minio]# mc --help
连接minio:
使用mc alias set命令将Amazon s3兼容的服务添加到mc配置中,将alias替换为要关联到S3服务的名称。
mc命令通常需要alias作为参数来标识要对哪个S3服务执行,如果省略ACCESS_KEY和SECRET_KEY,执行命令时会提示在CLI中输入这些值。
[root@master01 minio]# mc alias set myminio https://api.linuxsb.com minio minio123
Added `myminio` successfully.
[root@master01 minio]# mc admin info myminio
部署参考: K8S中使用helm安装MinIO书 。