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 ...
随机推荐
- 【开源】EDUCN网站
EDUCN https://scrc.rth1.link/ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q ...
- GDAL创建JPG或PNG格式图像
目录 1. 概述 2. 实现 1. 概述 根据GDAL文档,JPG/PNG格式支持读取和批量写入,但不支持实时更新.也就是不支持Create()方法,但是支持CreateCopy()方法.也可能是由于 ...
- 日常Bug排查-集群逐步失去响应
前言 日常Bug排查系列都是一些简单Bug排查.笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_ Bug现场 最近碰到一个产线问题,表现为某个应用集群所有的节点全部下线了.导致上游调用全部 ...
- 当物联网遇上云原生:K8s向边缘计算渗透中
摘要:K8s正在向边缘计算渗透,它为边缘侧的应用部署提供了便利性,在一定程度上转变了边缘应用与硬件之间的关系,将两者的耦合度降低. 本文分享自华为云社区<云原生在物联网中的应用[拜托了,物联网! ...
- 让数据库无惧灾难,华为云GaussDB同城双集群高可用方案正式发布!
摘要:在华为全联接2021期间,华为云GaussDB(for openGauss)正式推出重大内核新特性--同城双集群高可用方案,提供金融级高可用服务,支持RPO=0 .RTO<60s的同城双集 ...
- 基于CREATE TYPE语法自定义新数据类型
摘要:介绍CREATE TYPE语法可以在数据库中定义一种新的数据类型. 本文分享自华为云社区<GaussDB(DWS)数据类型之自定义数据类型(复合类型)>,作者: 清道夫. CREAT ...
- Dom4j 保存XML HL7-V3
dom4j selectNodes 取不到值 因为XML带有命名空间 HL7 Dom4j 保存XML String xmlPath = "D:\\BS004.xml"; Strin ...
- git clone克隆速度慢的解决办法
平常我们经常会遇到github的访问或者clone项目很慢甚至于无法访问,那么这个时候我们经常做的事情是修改hosts会比较多一些或者使用github的镜像站. 一.更改hosts文件的方式 常用的在 ...
- PS CJ34预算转借
一.CJ34,输入发出预算和接收预算的WBS 二.调用BAPI "-----------------------------------------@斌将军----------------- ...
- Codeforces Round #731 (Div. 3) A~G 解题记录
比赛链接:Here 1547A. Shortest Path with Obstacle 3个点 \(A,B,F\) ,前提 \(F\) 点为不可经过点,问 \(A\to B\) 最短路径长度 A题没 ...