本实验结合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_v1.30.3高可用部署架构二 。
已完成部署的Kubernetes集群的规划及相关信息如下:
主机 | IP | 磁盘 | 备注 |
---|---|---|---|
master01 | 172.24.10.11 | —— | master节点 |
master02 | 172.24.10.12 | —— | master节点 |
master03 | 172.24.10.13 | —— | master节点 |
worker01 | 172.24.10.14 | /dev/nvme0n2 | worker节点+ MinIO 节点 |
worker02 | 172.24.10.15 | /dev/nvme0n2 | worker节点+ MinIO 节点 |
worker03 | 172.24.10.16 | /dev/nvme0n2 | worker节点+ MinIO 节点 |
worker04 | 172.24.10.17 | /dev/nvme0n2 | worker节点+ MinIO 节点 |
集群VIP: 172.24.10.100
相关域名均能正常解析,可通过hosts解析相关域名至 VPI 。
生产环境下的 minio 官方建议使用 helm 部署,因此需要提前在 Kubernetes 中部署 helm 工具。
参考: Kubernetes集群管理-Helm部署及使用 。
部署 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运行三个容器:
在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 的安装。
MinIO Operator 自动生成 TLS 证书签名请求( CSR )并使用 Kubernetes certificates.k8s.io TLS 证书管理 API创建签名的 TLS 证书。
因此 MinIO Operator要求 Kubernetes kube-controller-manager 配置包括以下配置设置:
如果 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 租户。
使用 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 ,不需要安装。
运行 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 安装情况。
[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
创建模拟多租户的命名空间。
[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
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集群访问管理权限。
如下使用官方的 MinIO Tenant chart进行部署 MinIO 租户,与本地chart安装相比,此方法支持简化的安装路径。
如下的步骤是使用Helm根据官方的MinIO Tenant chart部署MinIO租户。
更多chart配置参考:MinIO Server Config Guide 。
添加repo参考: 添加repo
配置相关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的服务器数量、每个服务器的卷数量和存储类。
配置说明:
配置项 | 描述 |
---|---|
servers | 要在服务器池中部署的MinIO pod的数量 |
volumesPerServer | 要附加到每个MinIO pod(服务器)的持久卷的数量,Operator 为租户生成 volumesPerServer x servers 数量的 PVC |
storageClassName | 要与生成的PVC相关联的Kubernetes存储类,如果没有匹配指定值的存储类存在,或者指定的存储类不能满足请求的pvc个数或存储容量,则可能导致租户启动失败 |
size | 为每个生成的PVC请求的存储量 |
[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、亲和性和反亲和性配置:
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
MinIO租户CRD提供以下字段,使用相应字段配置租户TLS网络加密:
配置 | 描述 |
---|---|
tenant.certificate.requestAutoCert | 启用或禁用 MinIO 自动生成 TLS 证书。 如果省略,默认为 true 或 enabled 。 |
tenant.certificate.certConfig | 自定义自动 TLS 的行为(如果启用)。 |
tenant.certificate.externalCertSecret | 通过服务器名称指示( SNI )为多个主机名启用TLS。 指定一个或多个 kubernetes.io/tls 或 cert-manager 的 Kubernetes secret |
tenant.certificate.externalCACertSecret | 启用对未知、第三方或内部 CA ( Certificate authority )签名的客户端TLS证书进行验证。 指定一个或多个 kubernetes.io/tls 的 Kubernetes secret,其中包含特定机构的 CA 证书的完整链。 |
提前创建证书。
[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环境变量。
表头 | 表头 |
---|---|
tenant.configuration | 指定一个Kubernetes opaque secret,其数据负载config.env包含想要设置的每个MinIO环境变量。 |
config.env数据负载必须是一个base64编码的字符串,可以创建一个本地文件,设置环境变量,然后使用cat LOCALFILE | base64来创建有效负载。 |
本设置可以设置minio相关用户和密码,本实验保持默认minio/minio123 。
配置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
确认相关部署成功。
[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
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书 。