Kubernetes之存储卷与数据持久化
1. 存储卷概念
存储卷是定义在Pod资源之上,可被其内部的所有容器挂载的共享目录,它关联至某外部的存储设备之上的存储空间,从而独立于容器自身的文件系统,而数据是否具有持久能力则取决于存储卷自身是否支持持久机制。
2. 支持的存储卷类型

注意:
1. emptyDir与hostPath属于节点级别的卷类型,emptyDir的生命周期与Pod资源相同,而使用hostPath卷的Pod一旦被重新调度至其他节点,那么它将无法再使用此前的数据。
2. 使用网络存储系统,NFS,Ceph,GlusterFS
3. 使用PV
4. Secret和ConfigMap是两种特殊的卷类型
Secret用于向Pod传递敏感信息,如密码,私钥,证书文件等,
ConfigMap用于向Pod注入非敏感数据,使用时,用户将数据直接存储于ConfigMap对象中,而后直接在Pod中使用ConfigMap卷引用它
3. 存储卷的使用方式
1. 定义存储卷
spec :
...
volumes :
- name: logdata
emptyDir : {)
- name. example
gitRepo:
repository : https://github.com/iKubernetes/k8s_book.git
revision : master
directory: .
spec.volumes字段
由两个字段组成:spec.volumes.name和spec.volumes.VOL_TYPE
2. 挂载存储卷
containers:
- image: harbor.zp.com/dev_zp/tomcat:v2
name: tomcat-base
volumeMounts:
- name: tomcat-base-logs
mountPath: /usr/local/apache-tomcat-8.5.43/logs
- name: tomcat-base-webapps
mountPath: /usr/local/apache-tomcat-8.5.43/webapps
spec.containers. volumeMounts
name: 指定要挂载的存储的名称
mountPath: 挂载点路径,容器文件系统上的路径
readOnly: 是否挂载为只读卷
subPath: 挂载存储卷时使用的子路劲
4. 临时存储卷
1. emptyDir存储卷
在Pod对象启动时被创建,而在Pod对象被移除时会被一并删除
emptyDir存储卷定义于.spec.volumes.emptyDir嵌套字段中,可用字段主要包含两个:
medium: 存储介质的类型,取值为:default或memory
sizeLimit: 当前存储卷的空间限额,默认为nil,表示不限制;在使用memory的时,需要设置该限额
apiVersion: v1
kind: Pod
metadata:
name: redis-pod
spec:
containers:
- image: redis
name: redis
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
2. gitRepo存储卷
使用gitRepo存储卷的Pod资源在创建时,会首先创建一个空目录并克隆一份指定的Git仓库中的数据至该目录,而后创建容器并挂载该存储卷
定义gitRepo类型的存储卷,可嵌套使用的字段:
repository: git仓库的URL
directory: 目标目录名称,名称中不能包含".."字符;“.”表示将仓库中的数据直接复制到卷目录中
revison: 特定revision的提交哈希码
apiVersion : v1
kind : Pod
metadata :
name : vol-gitrepo-pod
spec:
containers:
- name : nginx
image: nginx:1.12-alpine
volumeMounts :
- name : html
mountPath : /usr/share/nginx/html
volumes :
- name : html
gitRepo :
repository: https://github.com/iKubernetes/k8s_book.git
directory : .
revision : ”master ”
5. 节点存储卷
hostPath类型的存储卷是指将工作节点上某文件系统的目录或文件挂载于Pod中的一种存储卷,它可独立于Pod资源的生命周期,因而具有持久性。
配置hostPath存储卷的嵌套字段共有两个:path和type
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: /tmp-test
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /tmp
type: Directory
6. 网络存储卷
1. NFS存储卷
NFS存储卷在Pod对象终止后仅是被卸载而非删除,定义NFS存储卷,常用到以下字段:
server: NFS服务器的IP地址或主机名
path: NFS服务器导出的文件系统路径
readOnly: 是否以只读方式挂载,默认为false
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
nfs:
server: 192.168.0.200
path: /opt/wwwroot
2. RBD存储卷
1. 要配置Pod资源使用RBD存储卷,需要以下几个前提条件
1. 存在某可用的Ceph RBD存储集群,否则就需要创建一个
2. 在Ceph RBD集群中创建一个能满足Pod资源数据存储需要的存储映像(image)
3. 在Kubernetes集群内的各节点上安装Ceph客户端程序包(ceph-common)
2. 配置RBD类型的存储卷,需要指定要连接的目标服务器和认证信息等,这一点通常使用以下嵌套字段进行定义
1. monitors: ceph存储监视器,逗号分隔的字符串列表
2. image: image的名称
3. pool: 存储池名称,默认为RBD
4. user: 用户名,默认为admin
5. keyring RBD用户认证时使用的keyring文件路径,默认为/etc/ceph/keyring
6. secretRef RBD用户认证时使用的保存有相应认证信息的Secret对象
7. readOnly 只读
8. fsType 要挂载的存储卷的文件系统类型
apiVersion : vl
kind : Pod
metadata :
name : vol-rbd-pod
spec :
containers :
- name : redis
image : redis:4-alpine
ports :
- containerPort : 6379
name : redisport
volumeMounts :
- mountPath : /data
name : redis-rbd-vol
volumes :
- name : redis-rbd-vol
rbd :
monitors :
- ’ 172 . 16 . 0 . 56 : 6789 ’
- ' 172 . 16 . 0 . 57 : 6789 '
- ' 172 . 16 . 0.58 : 6789 '
pool : kube
image : redis
fsType : ext4
readOnly : false
user : admin
secretRef :
name : ceph-secret
3. GlusterFS存储卷
1. 要配置Pod资源使用GlusterFS存储卷,需要事先满足以下条件
1. 存在一个GlusterFS集群
2. 创建一个存储需要的卷
3. 在k8s集群节点上安装GlusterFS客户端程序包(glusterfs和glusterfs-fuse)
2. 定义GlusterFS的存储卷,包含的字段
1. endpoints
2. path 用到的GlusterFS集群的卷路径
3. readOnly 是否只读
3. 创建Endpoints资源
apiVersion : v1
kind: Endpoints
metadata:
name: glusterfs-endpoints
subsets:
- addresses:
- ip: gfs01.ilinux.io
ports :
- port : 24007
name : glusterd
- addresses :
- ip : gfs02.ilinux.io
ports :
- port : 24007
name : glusterd
- addresses :
- ip : gfs03.ilinux.io
ports :
- port : 24007
name: glusterd
或者用这种方式写
apiVersion: v1
kind: Endpoints
metadata:
name: glusterfs-cluster
namespace: default
subsets:
- addresses:
- ip: 192.168.99.204
- ip: 192.168.99.205
- ip: 192.168.99.206
- ip: 192.168.99.207
ports:
- port: 49152
protocol: TCP
4. 定义存储卷和挂载存储卷
apiVersion : v1
kind : Pod
metadata :
name : vol-glusterfs-pod
labels :
app : redis
spec :
containers:
-name : redis
image : redis:alpine
ports :
- containerPort : 6379
name : redisport
volumeMounts :
- mountPath: /data
name : redisdat a
volumes :
- name : redisdata
glusterfs :
endpoints: glusterfs-endpoints
path: kube-redis
readOnly : false
4. Cinder存储卷
apiVersion : v1
kind : Pod
metadata :
name: vol-cinder-pod
spec:
containers :
- image : mysql
name : mysql
args :
- ” - ignore-db-dir ”
-” lost+found”
env :
- name : MYSQL_ ROOT_ PASSWORD
value : YOUR PASS
ports
- containerPort : 3306
name: mysqlport
volumeMounts:
- name : mysqldata
mountPath : /var/lib/mysql
volumes :
- name : mysqldata
cinder :
volumeID : e2b8d2f7-wece-90dl-a505-4acf607a90bc
fsType : ext4
7. 持久存储卷
PV,PVC及存储设备的关系

1. 创建PV
通用字段
1. Capacity 当前PV的容量
2. 访问模式
ReadWriteOnce 仅可被单个节点读写挂载,RWO
ReadOnlyMany 可被多个节点同时只读挂载,ROX
ReadWriteMany 可被多个节点同时读写挂载,RWX
3. persistentVolumeReclaimPolicy PV空间被释放时的处理机制
Retain 保持不动,由管理员随后手动回收
Recycle 空间回收,删除存储卷目录下的所有文件,仅NFS和hostPath支持此操作
Delete 删除存储卷,仅部分云端存储系统支持
4. volumeMode 卷模型
5. storageClassName 当前PV所属的StorageClass的名称
6. mountOptions 挂载选项组成的列表,如ro,soft,hard等
2. 定义使用NFS存储后端的PV
kind : PersistentVolume
metadata :
name : pv-nfs-0001
labels :
release: stable
spec :
capacity :
storage : 5Gi
volumeMode : Filesystem
accessModes :
- ReadWriteMany
persistentVolumeReclaimPolicy : Recycle
storageClassName : slow
mountOptions :
- hard
- nfsvers=4.1
nfs :
path: "/webdata/htdocs"
server : nfs.ilinux.io
3. 定义使用RBD存储后端
apiVersion: v1
kind : PersistentVolume
metadata:
name : pv-rbd-0001
spec :
capacity:
storage : 2Gi
accessModes:
- ReadWriteOnce
rbd :
monitors:
- ceph-mon01.ilinux.io:6789
- ceph-mon02.ilinux.io:6789
- ceph-mon03.ilinux.io:6789
pool : kube
image: pv-rbd-0001
user : admin
secretRef:
name: ceph-secret
fsType : ext4
readOnly : false
persistentVolumeReclaimPolicy: Retain
4. 查看PV
kubectl get pv pv-rbd-0001
PV的四种状态
Available 可用状态的自由资源,尚未被PVC绑定
Bound 已经绑定至某PVC
Released 绑定的PVC已经被删除,但资源尚未被集群回收
Failed 因自动回收资源失败而处于的故障状态
5. 创建PVC
通过申请占用某个PV,它与PV是一对一的关系,用户无需关心其底层实现细节。申请时,用户只需指定目标空间的大小,访问模式,PV标签选择器和StorageClass等相关信息即可。
通用字段
1. accessMode 访问模式与PV相同
2. resources 当前PVC需要占用的资源量最小值
3. selector 绑定时对PV应用的标签选择器
4. storageClassName 所依赖的存储类的名称
5. volumeMode 卷类型
6. volumeName 用于直接指定要绑定的PV的卷名
6. 创建NFS的PVC
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : pvc-nfs-0001
lables :
release : "stable"
spec:
accessModes:
- ReadWriteMany
volumeMode : Filesystem
resources :
requests :
storage : 5Gi
storageClassName: slow
selector :
matchLabels:
release: "stable"
7. 创建RBD的PVC
apiVerison: v1
kind : PersistentVolumeClaim
metadata :
name : pvc-rbd-0001
spec:
accessModes :
- ReadWriteOnce
volumeMode : Filesystem
resources :
requests :
storage : 2Gi
storageClassName : fast
selector :
matchLabels :
release : "stable"
7. 查看pvc
kubectl get pvc pvc-rbd-0001
8. 在pod中使用PVC
在pod资源中调用PVC资源,只需要在定义volumes时使用persistentVolumeClaims字段嵌套指定两个字段即可
apiVersion : v1
kind : Pod
metadata :
name: vol-rbd-pod
spec :
containers :
- name: redis
image : redis:4-alpine
ports:
- containerPort: 6379
name : redisport
volumeMounts :
mountPath : /data
name : redis-rbd-vol
volumes :
- name : redis-rbd-vol
persistenιVolumeClaim :
claimName : pv-rbd-0001

浙公网安备 33010602011771号