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. 【开源】EDUCN网站

    EDUCN https://scrc.rth1.link/ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q ...

  2. GDAL创建JPG或PNG格式图像

    目录 1. 概述 2. 实现 1. 概述 根据GDAL文档,JPG/PNG格式支持读取和批量写入,但不支持实时更新.也就是不支持Create()方法,但是支持CreateCopy()方法.也可能是由于 ...

  3. 日常Bug排查-集群逐步失去响应

    前言 日常Bug排查系列都是一些简单Bug排查.笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_ Bug现场 最近碰到一个产线问题,表现为某个应用集群所有的节点全部下线了.导致上游调用全部 ...

  4. 当物联网遇上云原生:K8s向边缘计算渗透中

    摘要:K8s正在向边缘计算渗透,它为边缘侧的应用部署提供了便利性,在一定程度上转变了边缘应用与硬件之间的关系,将两者的耦合度降低. 本文分享自华为云社区<云原生在物联网中的应用[拜托了,物联网! ...

  5. 让数据库无惧灾难,华为云GaussDB同城双集群高可用方案正式发布!

    摘要:在华为全联接2021期间,华为云GaussDB(for openGauss)正式推出重大内核新特性--同城双集群高可用方案,提供金融级高可用服务,支持RPO=0 .RTO<60s的同城双集 ...

  6. 基于CREATE TYPE语法自定义新数据类型

    摘要:介绍CREATE TYPE语法可以在数据库中定义一种新的数据类型. 本文分享自华为云社区<GaussDB(DWS)数据类型之自定义数据类型(复合类型)>,作者: 清道夫. CREAT ...

  7. Dom4j 保存XML HL7-V3

    dom4j selectNodes 取不到值 因为XML带有命名空间 HL7 Dom4j 保存XML String xmlPath = "D:\\BS004.xml"; Strin ...

  8. git clone克隆速度慢的解决办法

    平常我们经常会遇到github的访问或者clone项目很慢甚至于无法访问,那么这个时候我们经常做的事情是修改hosts会比较多一些或者使用github的镜像站. 一.更改hosts文件的方式 常用的在 ...

  9. PS CJ34预算转借

    一.CJ34,输入发出预算和接收预算的WBS 二.调用BAPI "-----------------------------------------@斌将军----------------- ...

  10. Codeforces Round #731 (Div. 3) A~G 解题记录

    比赛链接:Here 1547A. Shortest Path with Obstacle 3个点 \(A,B,F\) ,前提 \(F\) 点为不可经过点,问 \(A\to B\) 最短路径长度 A题没 ...