8.kubernetes存储介绍
[toc]
kubernetes存储概述
简介
容器内部的的存储在生命周期是短暂的,会随着容器环境的销毁而销毁,具有不稳定性。在k8s里将对容器应用所需的存储资源抽象为存储卷(Volume)概念来解决这些问题。
k8s目前支持的Volume类型包括k8s的内部资源对象类型,开源共享存储类型和公有云存储等。
k8s存储分类
- k8s特定的资源对象: - 1 
 2
 3- ConfigMap # 应用配置 
 Secret # 加密数据
 ServiceAccountToken # token数据
- k8s本地存储类型: - emptyDir - 简介- 临时存储,宿主机上会有有一个临时目录,如果POD结束,目录删除
 
- 使用场景- 初始化容器,想要修改主容器内的数据,那么需要在一个POD中,共享初始化容器和主容器的目录
 
 
- 简介
- hostPath - 简介- 永久存储,指定宿主机目录,会存储主容器的数据
 
- 使用场景- MySQL数据目录,gitlab配置文件目录、数据目录、日志目录,jenkins数据目录…
- 保证数据的持久化,存储主容器内的数据目录
 
 
- 简介
 
- 持久化存储(PV)和网络共享存储: - 网络共享存储(不限制磁盘空间)
- CephFS- GlusterFS ===》 GFS 就是NFS的集群版
- NFS
- fastDFS(k8s不支持)
 
- 持久化存储(PV)
- 通过PV划分资源空间,PVC绑定到PV上- PersistentVolumeClaim: 简称PVC,持久化存储的申请空间
 
 
本地存储
EmptyDir
- 启动测试pod - 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- # vim mysql.yaml 
 apiVersion: apps/v1
 kind: Deployment
 metadata:
 name: mysql-dp-test
 spec:
 replicas: 1
 selector:
 matchLabels:
 run: mysql
 template:
 metadata:
 name: mysql-pod
 labels:
 run: mysql
 spec:
 volumes:
 - name: db-data
 emptyDir: {}
 containers:
 - name: mysql-container
 image: mysql:5.7
 imagePullPolicy: IfNotPresent
 env:
 - name: MYSQL_ROOT_PASSWORD
 value: '123'
 volumeMounts:
 - name: db-data
 mountPath: /var/lib/mysql
- 启动pod - 1 
 2
 3
 4
 5
 6
 7
 8- # 应用资源清单 
 kubectl apply -f mysql.yaml
 deployment.apps/mysql-dp-test created
 # 查看pod在哪个node节点
 kubectl get pod -o wide
 NAME READY STATUS RESTARTS AGE IP NODE
 mysql-dp-test-cbd4b6458-svjfs 1/1 Running 0 27m 10.2.1.48 k8s02
- node节点查看数据 - 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- # 在node节点查看容器的ID 
 docker ps
 CONTAINER ID IMAGE COMMAND CREATED
 `872734e99dfb` c20987f18b13 "docker-entrypoint.s…" 23 minutes ago
 # 在node节点查看容器的详细信息
 docker inspect 872734e99dfb
 "Type": "bind",
 "Source": "/var/lib/kubelet/pods/a4cb2b28-aa70-4758-b15e-32e9908048ca/volumes/kubernetes.io~empty-dir/db-data",
 "Destination": "/var/lib/mysql",
 "Mode": "",
 "RW": true,
 "Propagation": "rprivate"
 # 在node节点查看文件目录
 ll /var/lib/kubelet/pods/a4cb2b28-aa70-4758-b15e-32e9908048ca/volumes/kubernetes.io~empty-dir/db-data
 -rw-r----- 1 polkitd input 56 Jun 15 20:04 auto.cnf
 -rw------- 1 polkitd input 1676 Jun 15 20:04 ca-key.pem
 -rw-r--r-- 1 polkitd input 1112 Jun 15 20:04 ca.pem
 -rw-r--r-- 1 polkitd input 1112 Jun 15 20:04 client-cert.pem
 -rw------- 1 polkitd input 1676 Jun 15 20:04 client-key.pem
 -rw-r----- 1 polkitd input 1353 Jun 15 20:05 ib_buffer_pool
 -rw-r----- 1 polkitd input 79691776 Jun 15 20:05 ibdata1
 -rw-r----- 1 polkitd input 50331648 Jun 15 20:05 ib_logfile0
 -rw-r----- 1 polkitd input 50331648 Jun 15 20:04 ib_logfile1
 -rw-r----- 1 polkitd input 12582912 Jun 15 20:05 ibtmp1
 drwxr-x--- 2 polkitd input 4096 Jun 15 20:04 mysql
 drwxr-x--- 2 polkitd input 8192 Jun 15 20:04 performance_schema
 -rw------- 1 polkitd input 1676 Jun 15 20:04 private_key.pem
 -rw-r--r-- 1 polkitd input 452 Jun 15 20:04 public_key.pem
 -rw-r--r-- 1 polkitd input 1112 Jun 15 20:04 server-cert.pem
 -rw------- 1 polkitd input 1680 Jun 15 20:04 server-key.pem
 drwxr-x--- 2 polkitd input 8192 Jun 15 20:04 sys
- 停止pod - 1 
 2- # 停止pod资源 
 kubectl delete -f mysql.yaml
- 查看node节点上的文件目录 - 1 
 2
 3
 4- # 在node节点查看文件目录 
 ll /var/lib/kubelet/pods/a4cb2b28-aa70-4758-b15e-32e9908048ca/volumes/kubernetes.io~empty-dir/db-data
 ls: cannot access /var/lib/kubelet/pods/a4cb2b28-aa70-4758-b15e-32e9908048ca/volumes/kubernetes.io~empty-dir/db-data: No such file or directory
 ## 在宿主机上生成一个临时的目录存储数据,如果POD删除,则目录也会删除
hostPath
简介
警告:HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。
当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。
如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问,则必须要求volumeMounts使用readOnly挂载以使策略生效。
添加磁盘的步骤
| 1 | # 查看磁盘 | 
hostPath语法格式
| 1 | hostPath : HostPathVolumeSource v1 core | 
type类型
| 取值 | 行为 | 
|---|---|
| 空字符串(默认) | 空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | 
| DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。 | 
| Directory | 在给定路径上必须存在的目录。 | 
| FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。 | 
| File | 在给定路径上必须存在的文件。 | 
| Socket | 在给定路径上必须存在的 UNIX 套接字。 | 
| CharDevice | 在给定路径上必须存在的字符设备。 | 
| BlockDevice | 在给定路径上必须存在的块设备。 | 
示例资源清单
| 1 | # cat mysql.yaml | 
持久化存储PV和PVC
PV和PVC概述
PV和PVC介绍
- PV- PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”。
- PV由管理员创建和配置
 
- PVC- PVC则是用户对存储资源的一个“申请”。
- 就像Pod消费Node的资源一样,PVC能够“消费”PV资源
- PVC可以申请特定的存储空间和访问模式
 
PV和PVC的生命周期

PV和PVC需要注意的地方
- 在PV的整个生命周期中,可能会处于4种不同的阶段:- Avaliable(可用) :表示可用状态,还未被任何PVC绑定
- Bound(可绑定) :表示PV已经被PVC绑定
- Released(已释放):PVC被删除,但是资源还未被集群重新声明
- Failed(失败) :表示该PV的自动回收失败
 

重点
- 创建PVC之后,k8s就会去查找满足我们声明要求的PV,比如storageClassName , accessModes 以及容量这些是否满足要求,如果满足要求就将PV和PVC绑定在一起。
- 需要注意的是目前PV和PVC之间是一对一绑定的关系,也就是说一个PV只能被一个PVC绑定。

PV和PVC的使用
部署NFS
| 1 | # 安装nfs-utils | 
| NFS共享参数 | 参数作用 | 
|---|---|
| rw* | 读写权限 | 
| ro | 只读权限 | 
| root_squash | 当NFS客户端以root管理员访问时,映射为NFS服务器的匿名用户(不常用) | 
| no_root_squash | 当NFS客户端以root管理员访问时,映射为NFS服务器的root管理员(不常用) | 
| all_squash | 无论NFS客户端使用什么账户访问,均映射为NFS服务器的匿名用户(常用) | 
| no_all_squash | 无论NFS客户端使用什么账户访问,都不进行压缩 | 
| sync* | 同时将数据写入到内存与硬盘中,保证不丢失数据 | 
| async | 优先将数据保存到内存,然后再写入硬盘;这样效率更高,但可能会丢失数据 | 
| anonuid* | 配置all_squash使用,指定NFS的用户UID,必须存在系统 | 
| anongid* | 配置all_squash使用,指定NFS的用户UID,必须存在系统 | 
PV和PVC的语法
| 1 | # PV资源参数 | 
- 访问模式的作用- 是否数据持久化
- 是否能被其他PVC绑定
 
- 回收策略- 保留(Retain)- 回收策略 Retain 使得用户可以手动回收资源。当 PersistentVolumeClaim 对象被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为”已释放(released)”。
- 由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。 管理员可以手动回收该卷
- 手动回收卷:- 删除 PersistentVolume 对象。与之相关的、位于外部基础设施中的存储资产 (例如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)在 PV 删除之后仍然存在。
- 根据情况,手动清除所关联的存储资产上的数据。
- 手动删除所关联的存储资产。
- 如果你希望重用该存储资产,可以基于存储资产的定义创建新的 PersistentVolume 卷对象。
 
 
- 清除(Recycle)- 如果下层的卷插件支持,回收策略 Recycle 会在卷上执行一些基本的擦除 (rm -rf /thevolume/*)操作,之后允许该卷用于新的 PVC 申领。
- 目前只有NFS和HostPath两种类型的PV支持Recycle策略。
 
- 删除(Delete)- 与PV相连的后端存储完成Volume的删除操作
 
 
- 保留(Retain)
- 存储类别- 具有特定类别的PV只能与请求了该类别的PVC绑定。
- 未指定类型的PV则只能与不请求任何类别的PVC绑定。
 
创建PV资源,划分NFS磁盘空间
- 编写PV创建资源清单 - 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- # 创建pv01 
 vim nfs-pv1.yaml
 apiVersion: v1
 kind: PersistentVolume
 metadata:
 name: pv01
 spec:
 capacity:
 storage: 5Gi
 accessModes:
 - ReadWriteOnce
 persistentVolumeReclaimPolicy: Recycle
 storageClassName: nfs
 nfs:
 path: /data/test1
 server: 172.16.1.31
 # 创建pv02
 vim nfs-pv2.yaml
 apiVersion: v1
 kind: PersistentVolume
 metadata:
 name: pv02
 spec:
 capacity:
 storage: 1Gi
 accessModes:
 - ReadWriteOnce
 persistentVolumeReclaimPolicy: Recycle
 storageClassName: nfs
 nfs:
 path: /data/test2
 server: 172.16.1.31
 # 创建pv03
 vim nfs-pv3.yaml
 apiVersion: v1
 kind: PersistentVolume
 metadata:
 name: pv03
 spec:
 capacity:
 storage: 3Gi
 accessModes:
 - ReadWriteOnce
 persistentVolumeReclaimPolicy: Recycle
 storageClassName: nfs
 nfs:
 path: /data/wp
 server: 172.16.1.31
 # 创建pv04
 vim local-pv4.yaml
 apiVersion: v1
 kind: PersistentVolume
 metadata:
 name: pv04
 spec:
 capacity:
 storage: 10Gi
 accessModes:
 - ReadWriteOnce
 persistentVolumeReclaimPolicy: Recycle
 storageClassName: nfs
 nfs:
 path: /data/local
- 应用资源清单并查看 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13- # 应用资源清单 
 kubectl apply -f nfs-pv1.yaml
 kubectl apply -f nfs-pv2.yaml
 kubectl apply -f nfs-pv3.yaml
 kubectl apply -f local-pv4.yaml
 # 查看资源清单
 kubectl get pv
 NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS
 pv01 5Gi RWO Recycle Available nfs
 pv02 1Gi RWO Recycle Available nfs
 pv03 3Gi RWO Recycle Available nfs
 pv04 10Gi RWO Recycle Available benduchunchu
使用PVC申请资源

- 资源语法 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17- vim pvc01.yaml 
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
 name: pvc01
 spec:
 accessModes:
 - ReadWriteOnce
 resources:
 requests:
 storage: 2Gi
 storageClassName: nfs
 # PVC资源关键参数:
 accessModes: # 访问模式,与PV定义的一样
 resources: # 描述对存储资源的请求,设置需要的存储空间大小
 storageClassName: # 存储类别,与PV的存储类型相匹配
- 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
 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- # 应用资源清单 
 kubectl apply -f pvc01.yaml
 # 查看PV状态
 kubectl get pv
 NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
 pv01 5Gi RWO Recycle Available
 pv02 1Gi RWO Recycle Available
 pv03 3Gi RWO Recycle Bound default/pvc01
 pv04 10Gi RWO Recycle Available
 # 查看PVC资源
 kubectl get pvc
 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
 pvc01 Bound pv03 3Gi RWO nfs 3s
 # 查看指定pv的详细信息
 kubectl describe pv pv03
 Name: pv03
 Labels: <none>
 Annotations: pv.kubernetes.io/bound-by-controller: yes
 Finalizers: [kubernetes.io/pv-protection]
 StorageClass: nfs
 Status: Bound
 Claim: default/pvc01
 Reclaim Policy: Recycle
 Access Modes: RWO
 VolumeMode: Filesystem
 Capacity: 3Gi
 Node Affinity: <none>
 Message:
 Source:
 Type: NFS (an NFS mount that lasts the lifetime of a pod)
 Server: 172.16.1.31
 Path: /data/wp
 ReadOnly: false
 Events: <none>
 # 查看指定pvc的详细信息
 kubectl describe pvc pvc01
 Name: pvc01
 Namespace: default
 StorageClass: nfs
 Status: Bound
 Volume: pv03
 Labels: <none>
 Annotations: pv.kubernetes.io/bind-completed: yes
 pv.kubernetes.io/bound-by-controller: yes
 Finalizers: [kubernetes.io/pvc-protection]
 Capacity: 3Gi
 Access Modes: RWO
 VolumeMode: Filesystem
 Mounted By: <none>
 Events: <none>
 # 编辑pvc02资源清单
 vim pvc02.yaml
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
 name: pvc02
 spec:
 accessModes:
 - ReadWriteOnce
 resources:
 requests:
 storage: 4Gi
 storageClassName: nfs
 # 应用资源清单
 kubectl apply -f pvc02.yaml
 # 查看PV状态
 kubectl get pv
 NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
 pv01 5Gi RWO Recycle Bound default/pvc02
 pv02 1Gi RWO Recycle Available
 pv03 3Gi RWO Recycle Bound default/pvc01
 pv04 10Gi RWO Recycle Available
 # 查看PVC状态
 kubectl get pvc
 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
 pvc01 Bound pv03 3Gi RWO nfs 72m
 pvc02 Bound pv01 5Gi RWO nfs 65s
 # 编辑pvc03资源清单
 vim pvc03.yaml
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
 name: pvc03
 spec:
 accessModes:
 - ReadWriteOnce
 resources:
 requests:
 storage: 8Gi
 storageClassName: bendicunchu
 # 应用资源清单
 kubectl apply -f pvc03.yaml
 # 查看PV状态
 kubectl get pv
 NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
 pv01 5Gi RWO Recycle Bound default/pvc02
 pv02 1Gi RWO Recycle Available
 pv03 3Gi RWO Recycle Bound default/pvc01
 pv04 10Gi RWO Recycle Available
 # 查看PVC状态
 kubectl get pvc
 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
 pvc01 Bound pv03 3Gi RWO nfs 73m
 pvc02 Bound pv01 5Gi RWO nfs 3m
 pvc03 Bound pv04 10Gi RWO bendicunchu 35s 
创建POD使用PVC资源
POD关联PVC的方式
- PVC关联PV:- accessModes
- storageClassName
- storage: 2Gi
 
- POD关联PVC:- 通过PVC名字
 
| 1 | # 查看PVC状态 | 
示例:mysql-deployment绑定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- vim mysql.yaml 
 apiVersion: apps/v1
 kind: Deployment
 metadata:
 name: mysql-dp-pvc
 spec:
 replicas: 1
 selector:
 matchLabels:
 run: mysql
 template:
 metadata:
 name: mysql-pod
 labels:
 run: mysql
 spec:
 volumes:
 - name: nfs-pvc
 persistentVolumeClaim:
 claimName: pvc02
 containers:
 - name: mysql-container
 image: mysql:5.7
 imagePullPolicy: IfNotPresent
 env:
 - name: MYSQL_ROOT_PASSWORD
 value: '123'
 volumeMounts:
 - name: nfs-pvc
 mountPath: /var/lib/mysql
- 应用资源清单 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15- # 应用资源清单 
 kubectl apply -f mysql.yaml
 # 查看pod状态
 kubectl get pod
 NAME READY STATUS RESTARTS AGE
 mysql-dp-pvc-5b59d6fc86-hvcmf 1/1 Running 0 22s
 # 查看pod详细信息
 kubectl describe pod mysql-dp-pvc-5b59d6fc86-md58d
 Volumes:
 nfs-pvc:
 Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
 ClaimName: pvc02
 ReadOnly: false
- 参数解析 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- # 关键参数解释: 
 persistentVolumeClaim: # 引用PVC
 claimName: mysql-pvc # 具体PVC的名称
 # 测试方法
 1.创建nfs-pv
 2.创建mysql-pvc
 3.创建mysql-deployment并挂载mysq-pvc
 4.登陆到mysql的pod里创建一个数据库
 5.将这个pod删掉,因为deployment设置了副本数,所以会自动再创建一个新的pod
 6.登录这个新的pod,查看刚才创建的数据库是否依然能看到
 7.如果仍然能看到,则说明数据是持久化保存的
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 奥利奥の麦旋风!




