http://www.lishuai.fun/2021/12/31/k8s-pv-s3/#/%E8%A6%81%E6%B1%82

我们可以通过csi使用s3为kubernetes提供pv存储,当我们申请pvc时,会自动在s3上创建bucket。这里我们还使用minio作为s3使用。

注: 不建议生产环境使用

要求

kubernetes集群需要满足以下几个条件:

  • Kubernetes 1.16+(CSI v1.0.0兼容性)
  • Kubernetes必须允许特权容器
  • Docker守护程序必须允许共享挂载(systemd标志MountFlags=shared

安装

首先创建一个secrets用来提供minio的凭据

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Secret
metadata:
name: csi-driver-s3-secret
namespace: kube-system
stringData:
accessKeyID: "xxxxx"
secretAccessKey: "xxxxxx"
#s3地址,如果是aws需要设置为https://s3.<region>.amazonaws.com
endpoint: https://minio.lishuai.fun
#如果不在S3上,请将其设置为“”
region: ""

接下来安装csi驱动

provisioner.yaml

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-provisioner-sa
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: external-provisioner-runner
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-provisioner-role
subjects:
- kind: ServiceAccount
name: csi-provisioner-sa
namespace: kube-system
roleRef:
kind: ClusterRole
name: external-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Service
apiVersion: v1
metadata:
name: csi-provisioner-s3
namespace: kube-system
labels:
app: csi-provisioner-s3
spec:
selector:
app: csi-provisioner-s3
ports:
- name: dummy
port: 12345
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: csi-provisioner-s3
namespace: kube-system
spec:
serviceName: "csi-provisioner-s3"
replicas: 1
selector:
matchLabels:
app: csi-provisioner-s3
template:
metadata:
labels:
app: csi-provisioner-s3
spec:
serviceAccount: csi-provisioner-sa
containers:
- name: csi-provisioner
image: quay.io/k8scsi/csi-provisioner:v2.1.0
args:
- "--csi-address=$(ADDRESS)"
- "--v=4"
env:
- name: ADDRESS
value: /var/lib/kubelet/plugins/s3.csi.metal-stack.io/csi.sock
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /var/lib/kubelet/plugins/s3.csi.metal-stack.io
- name: csi-driver-s3
image: misterli/csi-driver-s3:v0.3.4
args:
- "--endpoint=$(CSI_ENDPOINT)"
- "--nodeid=$(NODE_ID)"
- "--v=4"
env:
- name: CSI_ENDPOINT
value: unix:///var/lib/kubelet/plugins/s3.csi.metal-stack.io/csi.sock
- name: NODE_ID
valueFrom:
fieldRef:
fieldPath: spec.nodeName
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /var/lib/kubelet/plugins/s3.csi.metal-stack.io
volumes:
- name: socket-dir
emptyDir: {}

attacher.yaml

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-attacher-sa
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: external-attacher-runner
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattachments"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattachments/status"]
verbs: ["get", "list", "watch", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-attacher-role
subjects:
- kind: ServiceAccount
name: csi-attacher-sa
namespace: kube-system
roleRef:
kind: ClusterRole
name: external-attacher-runner
apiGroup: rbac.authorization.k8s.io
---
# needed for StatefulSet
kind: Service
apiVersion: v1
metadata:
name: csi-attacher-s3
namespace: kube-system
labels:
app: csi-attacher-s3
spec:
selector:
app: csi-attacher-s3
ports:
- name: dummy
port: 12345
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: csi-attacher-s3
namespace: kube-system
spec:
serviceName: "csi-attacher-s3"
replicas: 1
selector:
matchLabels:
app: csi-attacher-s3
template:
metadata:
labels:
app: csi-attacher-s3
spec:
serviceAccount: csi-attacher-sa
containers:
- name: csi-attacher
image: quay.io/k8scsi/csi-attacher:v3.1.0
args:
- "--v=4"
- "--csi-address=$(ADDRESS)"
env:
- name: ADDRESS
value: /var/lib/kubelet/plugins/s3.csi.metal-stack.io/csi.sock
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: socket-dir
mountPath: /var/lib/kubelet/plugins/s3.csi.metal-stack.io
volumes:
- name: socket-dir
hostPath:
path: /var/lib/kubelet/plugins/s3.csi.metal-stack.io
type: DirectoryOrCreate

csi-driver-s3.yaml

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-driver-s3
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-driver-s3
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "update"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattachments"]
verbs: ["get", "list", "watch", "update"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-driver-s3
subjects:
- kind: ServiceAccount
name: csi-driver-s3
namespace: kube-system
roleRef:
kind: ClusterRole
name: csi-driver-s3
apiGroup: rbac.authorization.k8s.io
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: csi-driver-s3
namespace: kube-system
spec:
selector:
matchLabels:
app: csi-driver-s3
template:
metadata:
labels:
app: csi-driver-s3
spec:
serviceAccount: csi-driver-s3
hostNetwork: true
containers:
- name: driver-registrar
image: quay.io/k8scsi/csi-node-driver-registrar:v2.1.0
args:
- "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)"
- "--v=4"
- "--csi-address=$(ADDRESS)"
env:
- name: ADDRESS
value: /csi/csi.sock
- name: DRIVER_REG_SOCK_PATH
value: /var/lib/kubelet/plugins/s3.csi.metal-stack.io/csi.sock
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- name: plugin-dir
mountPath: /csi
- name: registration-dir
mountPath: /registration/
- name: csi-driver-s3
securityContext:
runAsUser: 0
privileged: true
capabilities:
add: ["SYS_ADMIN"]
allowPrivilegeEscalation: true
image: misterli/csi-driver-s3:v0.3.4
args:
- "--endpoint=$(CSI_ENDPOINT)"
- "--nodeid=$(NODE_ID)"
- "--v=4"
env:
- name: CSI_ENDPOINT
value: unix:///csi/csi.sock
- name: NODE_ID
valueFrom:
fieldRef:
fieldPath: spec.nodeName
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: plugin-dir
mountPath: /csi
- name: pods-mount-dir
mountPath: /var/lib/kubelet/pods
mountPropagation: "Bidirectional"
- name: plugins-mount-dir
mountPath: /var/lib/kubelet/plugins
mountPropagation: "Bidirectional"
- name: fuse-device
mountPath: /dev/fuse
volumes:
- name: registration-dir
hostPath:
path: /var/lib/kubelet/plugins_registry/
type: DirectoryOrCreate
- name: plugin-dir
hostPath:
path: /var/lib/kubelet/plugins/s3.csi.metal-stack.io
type: DirectoryOrCreate
- name: pods-mount-dir
hostPath:
path: /var/lib/kubelet/pods
type: Directory
- name: plugins-mount-dir
hostPath:
path: /var/lib/kubelet/plugins
type: Directory
- name: fuse-device
hostPath:
path: /dev/fuse

psp.yaml

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp-s3
spec:
allowPrivilegeEscalation: true
fsGroup:
rule: RunAsAny
privileged: true
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
hostNetwork: true
allowedHostPaths: []
allowedCapabilities:
- "SYS_ADMIN"
volumes:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: psp-s3-role
namespace: kube-system
rules:
- apiGroups:
- policy
resources:
- podsecuritypolicies
resourceNames:
- psp-s3
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: psp-rolebinding-s3
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: psp-s3-role
subjects:
- apiGroup: ""
kind: ServiceAccount
name: csi-attacher-sa
- apiGroup: ""
kind: ServiceAccount
name: csi-driver-s3
- apiGroup: ""
kind: ServiceAccount
name: csi-provisioner-sa
- apiGroup: ""
kind: ServiceAccount
name: csi-resizer-sa

接下来创建storageclass

storageclass.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: csi-driver-s3
provisioner: s3.csi.metal-stack.io
parameters:
# specify which mounter to use
# currently only s3fs is supported
mounter: s3fs
csi.storage.k8s.io/provisioner-secret-name: csi-driver-s3-secret
csi.storage.k8s.io/provisioner-secret-namespace: kube-system
csi.storage.k8s.io/controller-publish-secret-name: csi-driver-s3-secret
csi.storage.k8s.io/controller-publish-secret-namespace: kube-system
csi.storage.k8s.io/node-stage-secret-name: csi-driver-s3-secret
csi.storage.k8s.io/node-stage-secret-namespace: kube-system
csi.storage.k8s.io/node-publish-secret-name: csi-driver-s3-secret
csi.storage.k8s.io/node-publish-secret-namespace: kube-system

mounter有以下几种配置参数:

S3不是真正的文件系统,因此这里有一些限制要考虑。根据所使用的安装程序,您将具有不同级别的POSIX兼容性。另外,取决于您使用的是哪个S3存储后端,并不总是可以保证一致性

可以将驱动程序配置为使用以下安装程序之一来安装存储桶:

可以将安装程序设置为存储类中的参数。如果愿意,还可以为每个安装程序创建多个存储类。

根据您的使用情况,所有安装程序都有不同的优点和缺点。以下是一些可以帮助您选择贴片机的特征:

rclone

  • 几乎完全兼容POSIX(取决于缓存模式)
  • 可以使用任何S3客户端正常查看文件

s3fs

  • POSIX的较大子集
  • 可以使用任何S3客户端正常查看文件
  • 不支持追加或随机写入

goofys

  • POSIX兼容性弱
  • 表现第一
  • 可以使用任何S3客户端正常查看文件
  • 不支持追加或随机写入

s3backer(实验性)

  • 表示存储在S3上的块设备
  • 允许使用真实的文件系统
  • 其他S3客户端无法读取文件
  • 支持附件
  • 支持上传前压缩(此驱动程序尚未实现)
  • 支持上传前加密(此驱动程序尚未实现)

s3backer目前处于试验阶段,因为在Kubernetes节点或CSI Pod意外关闭的情况下,卷损坏可能很快发生。s3backer二进制文件未与普通docker映像捆绑在一起,以使其尽可能小。使用<version>-fullimage标签测试s3backer

使用

我们创建一个pvc并创建一个pod绑定这个pvc

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
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-s3-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-s3
---
apiVersion: v1
kind: Pod
metadata:
name: csi-s3-test-nginx
namespace: default
spec:
containers:
- name: csi-s3-test-nginx
image: nginx
volumeMounts:
- mountPath: /var/lib/www/html
name: webroot
volumes:
- name: webroot
persistentVolumeClaim:
claimName: csi-s3-pvc
readOnly: false

我们创建后查看pvc已经是bound状态了

1
2
3
[root@master-01 sample]# kubectl get pvc 
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
csi-driver-s3-pvc Bound pvc-db7ab3e1-e3f4-4b4f-9877-c82051e60063 5Gi RWO csi-driver-s3 6s

并且我们在minio上也可以看到这个bucket

我们进入pod内的/var/lib/www/html目录下创建一个文件

1
2
3
4
5
[root@master-01 sample]# kubectl exec -it csi-driver-s3-test-nginx  -- bash 
root@csi-driver-s3-test-nginx:/# cd /var/lib/www/html/
root@csi-driver-s3-test-nginx:/var/lib/www/html# touch `date +"%Y-%m-%d"`.txt
root@csi-driver-s3-test-nginx:/var/lib/www/html# ls
2021-01-07.txt

此时我们也可以在minio的相应的bucket下看到该文件

[转帖]使用s3(minio)为kubernetes提供pv存储的更多相关文章

  1. glusterfs+heketi为k8s提供共享存储

    背景 近来在研究k8s,学习到pv.pvc .storageclass的时候,自己捣腾的时候使用nfs手工提供pv的方式,看到官方文档大量文档都是使用storageclass来定义一个后端存储服务, ...

  2. Kubernetes 学习(十)Kubernetes 容器持久化存储

    0. 前言 最近在学习张磊老师的 深入剖析Kubernetes 系列课程,最近学到了 Kubernetes 容器持久化存储部分 现对这一部分的相关学习和体会做一下整理,内容参考 深入剖析Kuberne ...

  3. 最佳实践:Pulsar 为批流处理提供融合存储

    非常荣幸有机会和大家分享一下 Apache Pulsar 怎样为批流处理提供融合的存储.希望今天的分享对做大数据处理的同学能有帮助和启发. 这次分享,主要分为四个部分: 介绍与其他消息系统相比, Ap ...

  4. Kubernetes K8S之存储ConfigMap详解

    K8S之存储ConfigMap概述与说明,并详解常用ConfigMap示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS ...

  5. Kubernetes K8S之存储Volume详解

    K8S之存储Volume概述与说明,并详解常用Volume示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...

  6. Kubernetes之持久化存储

    转载自 https://blog.csdn.net/dkfajsldfsdfsd/article/details/81319735 ConfigMap.Secret.emptyDir.hostPath ...

  7. 011.Kubernetes使用共享存储持久化数据

    本次实验是以前面的实验为基础,使用的是模拟使用kubernetes集群部署一个企业版的wordpress为实例进行研究学习,主要的过程如下: 1.mysql deployment部署, wordpre ...

  8. Kubernetes 持久化数据存储 StorageClass

    文章链接 PV 和 PVC 模式要先创建好 PV,然后再定义好 PVC 进行一对一的绑定.那么如果遇到大集群,也一一的创建吗?这样来说维护成本很高,工作量大.这个时候就有了 Kubernetes 提供 ...

  9. 【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南

    Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是: 个别对象的失效,不会溢出为更大级别的系统失效. 便于实现"强一致性& ...

  10. Kubernetes 静态PV使用

    Kubernetes  静态PV使用 Kubernetes支持持久卷的存储插件:https://kubernetes.io/docs/concepts/storage/persistent-volum ...

随机推荐

  1. Java 注解的实现原理

    注解的本质 在 java.lang.annotation.Annotation 接口中有这样的描述: The common interface extended by all annotation i ...

  2. ActiveMQ RCE CVE-2023-46604分析

    一.漏洞触发点 org.apache.activemq.openwire.v12包下BaseDataStreamMarshaller类的createThrowable方法. package org.a ...

  3. Mybatis源码3 CachingExecutor, 二级缓存,缓存的实现

    Mybatis CachingExecutor, 二级缓存,缓存的实现 一丶二级缓存概述 上一章节,我们知道mybaits在构造SqlSession的时候,需要让SqlSession持有一个执行器,如 ...

  4. 微信小程序常用代码

    在微信小程序中,可以使用 wx.showToast.wx.showLoading 和 wx.showModal 等方法来显示不同类型的提示框 wx.showToast:用于显示一条浮动的提示框,一般用 ...

  5. 关于GO语言,这篇文章讲的很明白

    摘要:本文从Go的语法,类型系统,编码风格,语言工具,编码工具和使用案例等几方面对Go语言进行了学习和探讨. Go语言发布之后,很多公司特别是云厂商也开始用Go语言重构产品的基础架构,而且很多企业都是 ...

  6. 不信谣不传谣,亲自动手验证ModelBox推理是否真的“高性能”

    摘要:"高性能推理"是ModelBox宣传的主要特性之一,不信谣不传谣的我决定通过原生API和ModelBox实现相同案例进行对比,看一下ModelBox推理是否真的"高 ...

  7. 火山引擎DataLeap如何解决SLA治理难题(二):申报签署流程与复盘详解

    申报签署流程详解 火山引擎DataLeap SLA保障的前提是先达成SLA协议.在SLA保障平台中,以申报单签署的形式达成SLA协议.平台核心特点是优化了SLA达成的流程,先通过"系统卡点计 ...

  8. BitSail issue 持续更新中,快来挑战,赢取千元礼品!

      背景介绍 近期,BitSail 社区发布了 Contributor 激励计划第一期,包含众多 issue,吸引了很多热衷开源的小伙伴的加入,详情可查看https://mp.weixin.qq.co ...

  9. 火山引擎 DataLeap 下 Notebook 系列文章二:技术路线解析

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在 Jupyter 的生态下,除了 Notebook 本身,火山引擎 DataLeap 研发团队还注意到了很多其他 ...

  10. Axure 标记元件

    快照:可以用来表示控件的截图功能 箭头:有了连线,基本很少用它 便签:相关于便利贴,写些说明.备注, 标记:标记好数字,对应数字的标记做解释说明