k8s集成MinIo

本篇文章分享一下在 k8s怎么集成 minio做存储,并实现 PersistentVolume (PV)PersistentVolumeClaim (PVC)、动态存储卷StorageClass,以及演示让pod使用这些存储卷的完整流程。

一、理论

1、PV概念

PV是对K8S存储资源的抽象,PV一般由运维人员创建和配置,供容器申请使用。

没有PV之前,服务器的磁盘没有分区的概念,有了PV之后,相当于通过PV对服务器的磁盘进行分区。

2、PVC概念

PVC 是Pod对存储资源的一个申请,主要包括存储空间申请、访问模式等。创建PV后,Pod就可以通过PVC向PV申请磁盘空间了。类似于某个应用程序向操作系统的D盘申请1G的使用空间。

PVC 创建成功之后,Pod 就可以以存储卷(Volume)的方式使用 PVC 的存储资源了。Pod 在使用 PVC 时必须与PVC在同一个Namespace下。

3、PV / PVC的关系

PV相当于对磁盘的分区,PVC相当于APP(应用程序)向某个分区申请多少空间。比如说安装WPS程序时,一般会告知我们安装它需要多少存储空间,让你选择在某个磁盘下安装。如果将来某个分区磁盘满了,也不会影响别的分区磁盘的使用。

一旦 PV 与PVC绑定,Pod就可以使用这个 PVC 了。如果在系统中没有满足 PVC 要求的 PV,PVC则一直处于 Pending 状态,直到系统里产生了一个合适的 PV。

4、StorageClass概念

K8S有两种存储资源的供应模式:静态模式和动态模式,资源供应的最终目的就是将适合的PV与PVC绑定:

  • 静态模式:管理员预先创建许多各种各样的PV,等待PVC申请使用。
  • 动态模式:管理员无须预先创建PV,而是通过StorageClass自动完成PV的创建以及与PVC的绑定。

StorageClass就是动态模式,根据PVC的需求动态创建合适的PV资源,从而实现存储卷的按需创建。

一般某个商业性的应用程序,会用到大量的Pod,如果每个Pod都需要使用存储资源,那么就需要人工时不时的去创建PV,这也是个麻烦事儿。解决方法就是使用动态模式:当Pod通过PVC申请存储资源时,直接通过StorageClass去动态的创建对应大小的PV,然后与PVC绑定,所以基本上PV → PVC是一对一的关系。

二、pod数据存储流程

img

三、部署minio

官方文档:MinIO | Code and downloads to create high performance object storage

下载minio

1
2
3
4
5
# 下载服务端
[root@minio opt]# wget https://dl.min.io/server/minio/release/linux-amd64/minio
# 将下载所得minio文件拷贝到指定文件夹并赋权
[root@minio opt]# cp minio /usr/local/bin/
[root@minio opt]# chmod +x /usr/local/bin/minio

为MinIO创建一个存储目录:

1
[root@minio opt]# mkdir /data

启动MinIO,并指定存储目录和访问地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@minio opt]# minio server /data --console-address ":9099"
INFO: Formatting 1st pool, 1 set(s), 1 drives per set.
INFO: WARNING: Host local has more than 0 drives of set. A host failure will result in data becoming unavailable.
MinIO Object Storage Server
Copyright: 2015-2025 MinIO, Inc.
License: GNU AGPLv3 - https://www.gnu.org/licenses/agpl-3.0.html
Version: RELEASE.2025-01-18T00-31-37Z (go1.23.5 linux/amd64)

API: http://10.0.0.12:9000 http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin

WebUI: http://10.0.0.12:9099 http://127.0.0.1:9099
RootUser: minioadmin
RootPass: minioadmin

CLI: https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart
$ mc alias set 'myminio' 'http://10.0.0.12:9000' 'minioadmin' 'minioadmin'

Docs: https://docs.min.io
WARN: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables

其中 /data 是用于存储 MinIO 数据的目录,--console-address ":9099" 是指定 MinIO Web 控制台的监听地址为端口 9099

1.访问

1
2
3
http://10.0.0.12:9099
账号:minioadmin
密码:minioadmin

img

2.配置自启动服务

为简化MinIO配置,我们可将MinIO的配置统一写入一个配置文件,以供启动时调用。配置方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@minio ~]# vim /etc/default/minio
# 指定数据存储目录(注意:这个目录要存在且拥有相对应的权限)
MINIO_VOLUMES="/data"

# 监听端口
MINIO_OPTS="--address :9000 --console-address :9099"

# 老版本使用MINIO_ACCESS_KEY/MINIO_SECRET_KEY,新版本已不建议使用
# Access key (账号)
# MINIO_ACCESS_KEY="minioadmin"
# Secret key (密码)
# MINIO_SECRET_KEY="minioadmin"

# 新版本使用;指定默认的用户名和密码,其中用户名必须大于3个字母,否则不能启动
MINIO_ROOT_USER="minioadmin"
MINIO_ROOT_PASSWORD="minioadmin666"

# 区域值,标准格式是“国家-区域-编号”,
MINIO_REGION="cn-north-1"

# 域名
# MINIO_DOMAIN=minio.your_domain.com

3.编写服务文件

创建minio.service服务文件,并写入配置信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[root@minio ~]# vim /usr/lib/systemd/system/minio.service
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
WorkingDirectory=/usr/local/

ProtectProc=invisible

# 指向3.1节中的配置文件
#EnvironmentFile=/etc/default/minio
EnvironmentFile=-/etc/default/minio

ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES

# Let systemd restart this service always
Restart=always

# Specifies the maximum (1M) file descriptor number that can be opened by this process
LimitNOFILE=1048576

# Specifies the maximum number of threads this process can create
TasksMax=infinity

# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no
SuccessExitStatus=0

[Install]
WantedBy=multi-user.target
Alias=minio.service

使服务生效

通过systemctl将服务生效并启动服务。

1
2
3
4
5
6
7
8
9
10
11
# 重新加载服务配置文件,使服务生效
systemctl daemon-reload

# 将服务设置为开机启动
systemctl enable minio

# 服务立即启动
systemctl start minio

# 查看minio服务当前状态
systemctl status minio

重新登录

1
2
3
http://10.0.0.12:9099
账号:minioadmin
密码:minioadmin666

如果起不来可以查看日志排查

1
[root@minio ~]# journalctl -u minio -f 

四、minio集成k8s

MinIO控制台提供了一个图形用户界面(GUI),用于与MinIO租户进行交互。默认情况下,MinIO操作员为每个租户安装和配置控制台。

参考地址:https://github.com/yandex-cloud/k8s-csi-s3

下载资源包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@master231 kubernetes]# pwd 
/opt/k8s-csi-s3-0.35.5/deploy/kubernetes

[root@master231 kubernetes]# tree ./
./
├── attacher.yaml
├── csi-s3.yaml
├── examples
│ ├── pod.yaml
│ ├── pvc-manual.yaml
│ ├── pvc.yaml
│ ├── secret.yaml
│ └── storageclass.yaml
└── provisioner.yaml

1 directory, 8 files

部署driver

1
2
3
4
cd deploy/kubernetes
kubectl create -f provisioner.yaml
kubectl create -f driver.yaml
kubectl create -f csi-s3.yaml

查看

img

创建存储类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@master231 examples]# vim storageclass.yaml 
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: csi-s3
provisioner: ru.yandex.s3.csi
parameters:
mounter: geesefs
# you can set mount options here, for example limit memory cache size (recommended)
options: "--memory-limit 1000 --dir-mode 0777 --file-mode 0666"
# to use an existing bucket, specify it here:
#bucket: some-existing-bucket
csi.storage.k8s.io/provisioner-secret-name: csi-s3-secret
csi.storage.k8s.io/provisioner-secret-namespace: kube-system
csi.storage.k8s.io/controller-publish-secret-name: csi-s3-secret
csi.storage.k8s.io/controller-publish-secret-namespace: kube-system
csi.storage.k8s.io/node-stage-secret-name: csi-s3-secret
csi.storage.k8s.io/node-stage-secret-namespace: kube-system
csi.storage.k8s.io/node-publish-secret-name: csi-s3-secret
csi.storage.k8s.io/node-publish-secret-namespace: kube-system

[root@master231 examples]# kubectl apply -f storageclass.yaml

1.模拟生成环境测试

创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@master231 examples]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-s3-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-s3

[root@master231 examples]# kubectl apply -f pvc.yaml

创建pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@master231 examples]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
name: csi-s3-test-nginx
namespace: default
spec:
containers:
- name: csi-s3-test-nginx
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html/s3
name: webroot
volumes:
- name: webroot
persistentVolumeClaim:
claimName: csi-s3-pvc
readOnly: false

创建secret

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master231 examples]# cat secret.yaml 
apiVersion: v1
kind: Secret
metadata:
namespace: kube-system
name: csi-s3-secret
stringData:
accessKeyID: minioadmin
secretAccessKey: minioadmin666
#填写minio api接口地址
endpoint: http://10.0.0.12:9000
# For AWS set it to AWS region
#region: ""

检查pv,pvc,sc,pod状态

img

写入数据

img

minio web界面查看是否写入成功

img


k8s集成MinIo
http://example.com/2025/04/18/k8s集成MinIo/
作者
淡黄的cherry
发布于
2025年4月18日
许可协议