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下看到该文件

- glusterfs+heketi为k8s提供共享存储
背景 近来在研究k8s,学习到pv.pvc .storageclass的时候,自己捣腾的时候使用nfs手工提供pv的方式,看到官方文档大量文档都是使用storageclass来定义一个后端存储服务, ...
- Kubernetes 学习(十)Kubernetes 容器持久化存储
0. 前言 最近在学习张磊老师的 深入剖析Kubernetes 系列课程,最近学到了 Kubernetes 容器持久化存储部分 现对这一部分的相关学习和体会做一下整理,内容参考 深入剖析Kuberne ...
- 最佳实践:Pulsar 为批流处理提供融合存储
非常荣幸有机会和大家分享一下 Apache Pulsar 怎样为批流处理提供融合的存储.希望今天的分享对做大数据处理的同学能有帮助和启发. 这次分享,主要分为四个部分: 介绍与其他消息系统相比, Ap ...
- Kubernetes K8S之存储ConfigMap详解
K8S之存储ConfigMap概述与说明,并详解常用ConfigMap示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS ...
- Kubernetes K8S之存储Volume详解
K8S之存储Volume概述与说明,并详解常用Volume示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...
- Kubernetes之持久化存储
转载自 https://blog.csdn.net/dkfajsldfsdfsd/article/details/81319735 ConfigMap.Secret.emptyDir.hostPath ...
- 011.Kubernetes使用共享存储持久化数据
本次实验是以前面的实验为基础,使用的是模拟使用kubernetes集群部署一个企业版的wordpress为实例进行研究学习,主要的过程如下: 1.mysql deployment部署, wordpre ...
- Kubernetes 持久化数据存储 StorageClass
文章链接 PV 和 PVC 模式要先创建好 PV,然后再定义好 PVC 进行一对一的绑定.那么如果遇到大集群,也一一的创建吗?这样来说维护成本很高,工作量大.这个时候就有了 Kubernetes 提供 ...
- 【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南
Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是: 个别对象的失效,不会溢出为更大级别的系统失效. 便于实现"强一致性& ...
- Kubernetes 静态PV使用
Kubernetes 静态PV使用 Kubernetes支持持久卷的存储插件:https://kubernetes.io/docs/concepts/storage/persistent-volum ...
随机推荐
- PB从入坑到放弃(七)PBer们的福音来了
写在前面 也许现在的你需要用PB完成毕业设计.需要维护远古时代的代码,又或者是你呆的公司就是要求要用PB开发项目. 不管你是出于什么原因还在使用PB,不可否认PB在数据窗口非常优秀,熟练使用之后开发数 ...
- API安全技术
自己在日常工作中会涉及到些安全的概念,但是没有成体系,因此最近研读了<API安全技术与实战>一书,在此做些文章记录. API安全是从安全的角度关注API领域的安全问题和这些问题的解决方案, ...
- 华为亮相KubeCon EU 2023 新云原生开源项目Kuasar推动“云上演进”
摘要:协力同行.拥抱开源,解放数字生产力,为社会和行业带来更多价值. 在数字时代,如果说企业是一艘巨大的货船,那么云原生则为企业的每一个业务.每一个应用提供了标准化的集装箱,摆脱笨重的底层桎梏,打造新 ...
- CWE 4.7中的新视图:工业控制系统的安全漏洞类别
摘要:CWE今年的第一个版本在5/1前发布了,做为软件安全的重要分类标准,我们来看下这个版本有那些变化. 本文分享自华为云社区<CWE 4.7中的新视图 -- 工业控制系统的安全漏洞类别> ...
- Python 的 sum():Pythonic 的求和方法
摘要:Python 的内置函数sum()是一种对数值列表求和的有效且Pythonic 的方法.将多个数字相加是许多计算中常见的中间步骤,因此sum()对于 Python 程序员来说是一个非常方便的工具 ...
- JS遍历循环方法性能对比:for/while/for in/for of/map/foreach/every
这周codeReview例会,又遇到map与foreach到底谁问题.单独图方便,我会选择用map一个函数搞定一切.但是从语义的角度来讲,如果只是单纯遍历,还是推荐选择foreach.其实formap ...
- 如何对APP进行安全加固
如何对APP进行安全加固 引言 如今,移动应用市场蓬勃发展,APP数量呈现爆炸性增长.随着5G技术的广泛应用,APP的增长趋势持续增强.然而,由于APP的泛滥,网络攻击者的目标也在逐渐转移,数亿的 ...
- 总结vue3 的一些知识点:Vue.js 安装
Vue.js 安装 1.独立版本 我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入. 下载 Vue.js 2.使用 CDN 方法 以下推荐 ...
- 为提高 SDLC 安全,GitHub 发布新功能|GitHub Universe 2022
GitHub Universe 2022于上周举办.在此次大会上,Github 公布了开源软件状态的最新报告,报告中的统计数据显示,90% 的公司都在使用开源,现在 GitHub 上有9400万用户, ...
- 火山引擎DataTester:AB实验平台未来演进趋势是怎样的?
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 近日,DataFun联合行行AI举办第四届"数据智能创新与实践人工智能大会,火山引擎DataTester ...