1.存储卷管理概念
Kubernetes Volume 是一个目录,这一点与 Docker Volume 类似。当 Volume 被 mount 到 Pod,Pod 中的所有容器都可以访问这个 Volume。Kubernetes Volume 也支持多种 backend 类型,包括 emptyDir、hostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、Ceph 等,完整列表可参考 https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes Volume 的生命周期独立于容器,Pod 中的容器可能被销毁和重建,但 Volume 会被保留。 本质上,Kubernetes Volume 是一个目录,这一点与 Docker Volume 类似。当 Volume 被 mount 到 Pod,Pod 中的所有容器都可以访问这个 Volume。Kubernetes Volume 也支持多种 backend 类型,包括 emptyDir、hostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、Ceph 等,完整列表可参考 https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes
2 经常使用的卷类型
本地卷: hostPath,emptyDir 网络卷: nfs,ceph(cephfs,rbd),glusterfs 公有云: aws,azure k8s资源: downwardAPI,configmap,secret
2.1 临时存储emptyDir
emptyDir Volume 对于容器来说是持久的,对于 Pod 则不是。当 Pod 从节点删除时,Volume 的内容也会被删除。但如果只是容器被销毁而 Pod 还在,则 Volume 不受影响。也就是说:emptyDir Volume 的生命周期与 Pod 一致。 Pod中的所有容器都可以共享Volume,它们可以指定各自的mount路径。
我们通过例子来实践 emptyDir,配置文件如下
apiVersion: v1
kind: Pod
metadata:
name: emtydirpod
spec:
containers:
- name: write
image: centos
command: ["bash","-c","for i in {1..100}; do echo $i >> /data/hello; sleep 10; done"]
volumeMounts:
- name: data
mountPath: /data
- name: read
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
验证
root@k8s-master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
emtydirpod 2/2 Running 0 68s
[root@k8s-master01 ~]# kubectl logs emtydirpod read
1
2
3
4
5
6
7
在对应的node上查看挂载的目录
/var/lib/kubelet/pods/6767307c-b6b6-48a7-81ad-10610a666cc6/volumes/kubernetes.io~empty-dir/data
2.2 节点存储hostPath
hostPath Volume 的作用是将 Docker Host 文件系统中已经存在的目录 mount 给 Pod 的容器。大部分应用都不会使用 hostPath Volume,因为这实际上增加了 Pod 与节点的耦合,限制了 Pod 的使用。不过那些需要访问 Kubernetes 或 Docker 内部数据(配置文件和二进制库)的应用则需要使用 hostPath。 应用场景: 日志采集agent,监控agent
hostPath参数说明:
参数 | 解释 |
---|---|
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息 |
Directory | 在给定路径上必须存在的目录 |
FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权 |
File | 在给定路径上必须存在的文件 |
Socket | 在给定路径上必须存在的 UNIX 套接字 |
CharDevice | 在给定路径上必须存在的字符设备 |
BlockDevice | 在给定路径上必须存在的块设备 |
实例展示用法
首先要在所有的node节点建立对应的目录,或者通过DirectoryOrCreate 自动创建.
[root@k8s-master01 ~]# cat hostPathmount.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpathtest
spec:
volumes:
- name: html
hostPath:
path: /html
type: DirectoryOrCreate
containers:
- name: nginx
image: nginx:1.15
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
[root@k8s-master01 ~]# kubectl apply -f hostPathmount.yaml
pod/hostpathtest created
[root@k8s-master01 ~]#
测试
root@hostpathtest:/usr/share/nginx/html# cat index.html
hhh
dddd
[root@k8s-master01 /]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpathtest 1/1 Running 0 3m30s 10.244.2.88 k8s-node02 <none> <none>
查看pod所在的节点对应/html
[root@k8s-node02 html]# cat index.html
hhh
dddd
[root@k8s-node02 html]# pwd
/html
通过hostpath创建的目录 不会因为pod的消失而消失.
3 网络卷挂载使用
3.1 NFS存储卷
1.搭建nfs服务
yum install nfs-utils -y rpcbind
mkdir /data/k8s-volume -p
chmod 755 /data/k8s-volume
vim /etc/exports
/data/k8s-volume *(rw,no_root_squash,sync)
#存储目录,*允许所有人连接,rw读写权限,sync文件同时写入硬盘及内存,no_root_squash 使用者root用户自动修改为普通用户
systemctl start rpcbind
systemctl restart nfs
systemctl status nfs
[root@k8s-node01 ~]# cat /var/lib/nfs/etab
/data/k8s-volume *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,no_root_squash,no_all_squash)
#检查nfs挂载目录是否正常
[root@k8s-node01 ~]# showmount -e localhost
Export list for localhost:
/data/k8s-volume *
要在所有的node上都安装客户端软件
yum install -y nfs-utils rpcbind
[root@所有节点 ~]# mkdir -p /data1/k8s/
[root@所有节点 ~]# mount -t nfs 192.168.10.72:/data/k8s-volume /data1/k8s
查看挂载情况
[root@k8s-node02 k8s]# df -h |grep data1
192.168.10.72:/data/k8s-volume 27G 11G 17G 39% /data1/k8s
[root@k8s-master01 ~]# cat nfs_volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-volume-pod
labels:
app: redis
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
name: redisport
volumeMounts:
- name: redisdata
mountPath: /data
volumes:
- name: redisdata
nfs:
server: 192.168.10.72
path: /data/k8s-volume
readOnly: false
创建pod挂载nfs
[root@k8s-master01 ~]# kubectl apply -f nfs_volume.yaml
pod/nfs-volume-pod created
[root@k8s-master01 ~]# kubectl logs nfs-volume-pod
1:C 11 Apr 2021 12:14:37.364 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 11 Apr 2021 12:14:37.364 # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 11 Apr 2021 12:14:37.364 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 11 Apr 2021 12:14:37.365 * monotonic clock: POSIX clock_gettime
1:M 11 Apr 2021 12:14:37.365 * Running mode=standalone, port=6379.
1:M 11 Apr 2021 12:14:37.365 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 11 Apr 2021 12:14:37.365 # Server initialized
1:M 11 Apr 2021 12:14:37.366 * Ready to accept connections
[root@k8s-master01 ~]# kubectl exec -it nfs-volume-pod redis-cli
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
127.0.0.1:6379> set key hello
OK
127.0.0.1:6379> get key
"hello"
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> exit
查看nfs挂载目录 redis数据已保存
[root@k8s-node01 ~]# ll /data/k8s-volume/dump.rdb
-rw-r--r-- 1 polkitd ssh_keys 108 4月 11 20:17 /data/k8s-volume/dump.rdb
删除pod,重新创建,查看redis数据
[root@k8s-master01 ~]# kubectl delete -f nfs_volume.yaml
pod "nfs-volume-pod" deleted
[root@k8s-master01 ~]# kubectl apply -f nfs_volume.yaml
pod/nfs-volume-pod created
[root@k8s-master01 ~]# kubectl exec -it nfs-volume-pod redis-cli
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
127.0.0.1:6379> get key
"hello"
127.0.0.1:6379>
通过以上操作,数据没有同pod一起被删除.
3.2 RBD存储卷
4 持久存储卷(pv,pvc)
4.1 持久存储卷概念
PV 的全称是:PersistentVolume(持久化卷),是对底层的共享存储的一种抽象,PV 由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如 Ceph、GlusterFS、NFS 等,都是通过插件机制完成与共享存储的对接。
PVC 的全称是:PersistentVolumeClaim(持久化卷声明),PVC 是用户存储的一种声明,PVC 和 Pod 比较类似,Pod 消耗的是节点,PVC 消耗的是 PV 资源,Pod 可以请求 CPU 和内存,而 PVC 可以请求特定的存储空间和访问模式。对于真正使用存储的用户不需要关心底层的存储实现细节,只需要直接使用 PVC 即可。
但是通过PVC请求一定的存储空间也很有可能不足以满足对于存储设备的各种需求,而且不同的应用程序对于存储性能的要求也能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes又为我们引入了一个新的资源对象: StorageClass,通过StorageClass的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据StorageClass的描述就可以非常直观的知道各种存储资源特性了,这样就可以根据应用的特性去申请合适的存储资源了
静态 pv
集群管理员创建一些 PV。它们带有可供群集用户使用的实际存储的细节。它们存在于Kubernetes API 中,可用于消费
动态pv
当管理员创建的静态 PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试动态地为 PVC创建卷。此配置基于StorageClasses:PVC 必须请求
[存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为””可以有效地禁用其动态配置要启用基于存储级别的动态存储配置,集群管理员需要启用 API server上的DefaultStorageClass[准入控制器]。例如,通过确保DefaultStorageClass位于API server组件的—admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作
4.2 PV和PVC的生命周期
1.资源供应 (Provisioning)
Kubernetes支持两种资源的供应模式:静态模式(Staic)和动态模式(Dynamic)。资源供应的结果就是创建好的PV。
静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置
动态模式:集群管理员无须手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种 “类型(Class)”。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及PVC的绑定。PVC可以声明Class为””,说明该PVC禁止使用动态模式
2.资源绑定 (Binding)
在用户定义好PVC后,系统将根据PVC对存储资源的请求 (存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将该PV与用户定义的PVC进行绑定,然后用户的应用就可以使用这个PVC了。如果系统中没有满足PVC要求的PV,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合要求的PV。PV一旦绑定在某个PVC上,就被这个PVC独占,不能再与其他PVC进行绑定了。在这种情况下,当PVC申请的存储空间比PV的少时,整个PV的空间都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在PVC找到合适的StorageClass后,将会自动创建PV并完成PVC的绑定
3.资源使用 (Using)
Pod 使用volume的定义,将PVC挂载到容器内的某个路径进行使用。volume的类型为persistentVoulumeClaim,在容器应用挂载了一个PVC后,就能被持续独占使用。不过,多个Pod可以挂载同一个PVC,应用程序需要考虑多个实例共同访问一块存储空间的问题
4.资源释放 (Releasing)
当用户对存储资源使用哪个完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为已释放,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还留在存储设备上,只有在清除之后该PV才能继续使用
5.资源回收 (Reclaiming)
对于PV,管理员可以设定回收策略(Reclaim Policy)用于设置与之绑定的PVC释放资源之后,对于遗留数据如何处理。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。
4.3 pv的创建
PV容量(capacity):设定当前PV的容量,单位为Gi、Mi 访问模式:PersistentVolume可以以资源提供者支持的任何方式挂载到主机上。每个PV的访问模式都将被设置为该卷支持的特定模式。
ReadWriteOnce——该卷可以被单个节点以读/写模式挂载
ReadOnlyMany——该卷可以被多个节点以只读模式挂载
ReadWriteMany——该卷可以被多个节点以读/写模式挂载
在命令行中,访问模式缩写为:
RWO - ReadWriteOnce
ROX - ReadOnlyMany
RWX - ReadWriteMany
persistentVolumeReclaimPolicy(回收策略)
Retain(保留)——管理员手动回收
Recycle(回收)——基本擦除(rm -rf /thevolume/*),目前仅NFS和hostPath支持此操作。
Delete(删除)——关联的存储资产(例如 AWS EBS、GCE PD、Azure Disk 和OpenStack Cinder 卷)将被删除
StorageClass的名称(storageClassName):当前PV所属的StorageClass的名称;pvc与pv绑定时根据此name值匹配
卷可以处于以下的某种状态:
Available(可用)——一块空闲资源还没有被任何声明绑定
Bound(已绑定)——卷已经被声明绑定
Released(已释放)——声明被删除,但是资源还未被集群重新声明
Failed(失败)——该卷的自动回收失败命令行会显示绑定到 PV 的 PVC 的名称
[root@k8s-master01 ~]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv00001 #pv名称
spec:
capacity: #存储能力,一个pv对象都要指定一个存储能力,目前仅支持存储空间的设置
storage: 5Gi #存储空间
accessModes:
- ReadWriteMany #存储空间
persistentVolumeReclaimPolicy: Recycle #Recycle(回收)
nfs:
path: /data/k8s-volume/pv00001
server: 192.168.10.72
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv00002
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /data/k8s-volume/pv00002
server: 192.168.10.72
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv00003
spec:
capacity:
storage: 6Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /data/k8s-volume/pv00003
server: 192.168.10.72
创建 pv
kubectl apply -f pv.yaml
查看创建的pv
[root@k8s-master01 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv00001 5Gi RWX Recycle Available 2m27s
pv00002 3Gi RWX Recycle Available 2m49s
pv00003 6Gi RWX Recycle Available 4m10s
4.4 pvc的创建
[root@k8s-master01 ~]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
[root@k8s-master01 ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/pvc-nfs created
[root@k8s-master01 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv00001 5Gi RWX Recycle Bound (已绑定在pvc上) default/pvc-nfs 18m
pv00002 3Gi RWX Recycle Available 18m
pv00003 6Gi RWX Recycle Available 20m
[root@k8s-master01 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-nfs Bound pv00001 5Gi RWX 15s
创建一个pvc小于提供的pv的大小的
[root@k8s-master01 ~]# cat pvc1.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc002
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
[root@k8s-master01 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv00001 5Gi RWX Recycle Bound default/pvc-nfs 24m
pv00002 3Gi RWX Recycle Bound default/pvc002 24m
pv00003 6Gi RWX Recycle Available 26m
[root@k8s-master01 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-nfs Bound pv00001 5Gi RWX 6m15s
pvc002 Bound pv00002 3Gi RWX 71s
如上 ,pvc磁盘要求不大于提供的最大的pv磁盘的情况下,会选取接近的pv绑定
pvc也可以使用指定的pv,通过标签选择器
#记得我们需要修改一下名字,名字是不可以重复的
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
labels: #这里将pv设置一个labels
app: nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /data/k8s-volume/pv00002
server: 192.168.10.72
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2-nfs
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
selector: ##pvc匹配标签为app=nfs的pv
matchLabels:
app: nfs
4.5 创建pod使用pvc
[root@k8s-master01 ~]# cat pod-redis-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: pvc-nfs-pod
spec:
containers:
- name: redis
image: redis:lastest
ports:
- containerPort: 6379
name: redisport
volumeMounts:
- mountPath: /data
name: redisdata
volumes:
- name: redisdata
persistentVolumeClaim:
claimName: pvc-nfs
[root@k8s-master01 ~]# kubectl apply -f pod-redis-pvc.yaml
pod/pvc-nfs-pod created
创建使用pvc的pod
[root@k8s-master01 ~]# kubectl exec -it pvc-nfs-pod redis-cli
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
127.0.0.1:6379> SET devopstack yes
OK
127.0.0.1:6379> get devopstack
"yes"
127.0.0.1:6379> BGSAVE
Background saving started
删除pod重建pod 查看key还有没
[root@k8s-master01 ~]# kubectl delete -f pod-redis-pvc.yaml
pod "pvc-nfs-pod" deleted
[root@k8s-master01 ~]# kubectl apply -f pod-redis-pvc.yaml
pod/pvc-nfs-pod created
[root@k8s-master01 ~]# kubectl exec -it pvc-nfs-pod redis-cli
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
127.0.0.1:6379> get devopstack
"yes"
pv pvc具有持久性
数据保存在挂载的pv中了
[root@k8s-node01 pv00001]# ll
总用量 4
-rw-r--r-- 1 polkitd ssh_keys 113 4月 14 15:09 dump.rdb
[root@k8s-node01 pv00001]# pwd
/data/k8s-volume/pv00001
4.6 动态pv(storageclass)的创建
StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端的细节,一方面减轻用户对于存储资源细节的关注,另一方面也减轻了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应。使用基于StorageClass的动态资源供应模式将逐步成为云平台的标准存储配置模式
要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner,这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。
参考文档为
https://github.com/kubernetes-retired/external-storage/tree/master/nfs-client
1.配置nfs-client的Deployment文件,将里面的对应的参数替换成我们自己的nfs配置
wget https://raw.githubusercontent.com/kubernetes-retired/external-storage/master/nfs-client/deploy/deployment.yaml
[root@k8s-master01 storageclass]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 192.168.10.72
- name: NFS_PATH
value: /data/k8s-volume
volumes:
- name: nfs-client-root
nfs:
server: 192.168.10.72
path: /data/k8s-volume
2.创建一个serveraccount,用于将nfs-client-provisioner中的ServiceAccount绑定到一个nfs-client-provisioner-runner的ClusterRole。而该ClusterRole声明了一些权限,其中就包括了对persistentvolumes的增删改查,所以我们就可以利用ServiceAccount来自动创建PV
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- 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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
fuseim.pri/ifs 需要和deployment保持一致
3.声明了一个名为managed-nfs-storage的Storageclass对象
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
archiveOnDelete: "false"
创建
[root@k8s-master01 storageclass]# kubectl apply -f .
storageclass.storage.k8s.io/managed-nfs-storage created
deployment.apps/nfs-client-provisioner created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
查看
[root@k8s-master01 storageclass]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-794b747b95-vdgs4 1/1 Running 0 3m57s
[root@k8s-master01 storageclass]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage fuseim.pri/ifs Delete Immediate false 8m15s
创建pvc验证我们创建的storageclass
[root@k8s-master01 storageclass]# cat storageclass-nfs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-storage-pvc
spec:
storageClassName: "managed-nfs-storage"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
创建动态的pvc
[root@k8s-master01 storageclass]# kubectl apply -f storageclass-nfs.yaml
persistentvolumeclaim/test-storage-pvc created
查看自动创建的pv
[root@k8s-master01 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-bceac085-3d11-425f-a0b5-a1a9bd8a1fb0 1Gi RWX Delete Bound default/test-storage-pvc managed-nfs-storage 9m7s
查看我们创建的pvc
[root@k8s-master01 storageclass]#
[root@k8s-master01 storageclass]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-storage-pvc Bound pvc-bceac085-3d11-425f-a0b5-a1a9bd8a1fb0 1Gi RWX managed-nfs-storage 10s
如上我们已经成功创建了动态的pvc
通过使用pod测试我们创建的动态的pvc,storageclass主要代替pv的工作,当pvc申请资源的时候,自动创建对应的[pv资源.
[root@k8s-master01 storageclass]# cat pod-redis-pvc-storageclass.yaml
apiVersion: v1
kind: Pod
metadata:
name: storage-nfs-pod
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
name: redisport
volumeMounts:
- mountPath: /data
name: redisdata
volumes:
- name: redisdata
persistentVolumeClaim:
claimName: test-storage-pvc
执行
[root@k8s-master01 storageclass]# kubectl apply -f pod-redis-pvc-storageclass.yaml
pod/storage-nfs-pod created
测试
[root@k8s-master01 storageclass]# # kubectl exec -it storage-nfs-pod redis-cli
[root@k8s-master01 storageclass]# kubectl exec -it storage-nfs-pod redis-cli
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
127.0.0.1:6379> SET storage yes
OK
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379>
[root@k8s-master01 storageclass]# kubectl delete -f storageclass-nfs.yaml
persistentvolumeclaim "test-storage-pvc" deleted
[root@k8s-node01 default-test-storage-pvc-pvc-bceac085-3d11-425f-a0b5-a1a9bd8a1fb0]# ll
总用量 4
-rw-r--r-- 1 polkitd ssh_keys 114 4月 15 21:00 dump.rdb
[root@k8s-node01 default-test-storage-pvc-pvc-bceac085-3d11-425f-a0b5-a1a9bd8a1fb0]# pwd
/data/k8s-volume/default-test-storage-pvc-pvc-bceac085-3d11-425f-a0b5-a1a9bd8a1fb0
[root@k8s-master01 storageclass]# kubectl apply -f pod-redis-pvc-storageclass.yaml
pod/storage-nfs-pod created
[root@k8s-master01 storageclass]# kubectl exec -it storage-nfs-pod redis-cli
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
127.0.0.1:6379> GET storage
"yes"
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫