k8s初级实战01--数据卷
1 基础概念
Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用程序带来一些问题。问题一:当容器崩溃时文件丢失,kubelet 会重新启动容器, 但容器会以干净的状态重启。 问题二:会在同一 Pod 中运行多个容器并共享文件时出现。 Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。
卷的核心是包含一些数据的一个目录,Pod 中的容器可以访问该目录。
使用卷时, 在 .spec.volumes 字段中设置为 Pod 提供的卷,并在 .spec.containers[*].volumeMounts 字段中声明卷在容器中的挂载位置。
数据卷的常见概念包括PV、PVC、StorageClass:
持久卷(Persistent Volume,PV)是集群中的一块存储,可以由管理员事先供应,或者使用存储类(Storage Class)来动态供应。PV 属于集群资源,不属于某个命名空间。
持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。PVC 可以请求特定大小和访问模式(ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany )。
存储类(StorageClass)为管理员提供了描述存储 “类” 的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。
k8s 中支持很多类型卷,具体如下:
名称 | 功能说明 |
---|---|
awsElasticBlockStore | |
azureDisk | |
azureFile | |
cephfs | |
cinder | |
configMap | |
downwardAPI | |
emptyDir | 在pod中创建空文件夹 |
fc (光纤通道) | |
flocker (已弃用) | |
gcePersistentDisk | |
gitRepo (已弃用) | |
glusterfs | |
hostPath | 挂载宿主机器目录 |
iscsi | |
local | 代表的是某个被挂载的本地存储设备,例如磁盘、分区或者目录 |
nfs | 挂载nfs目录 |
persistentVolumeClaim | |
portworxVolume | |
projected | |
quobyte | |
rbd | |
scaleIO (已弃用) | |
secret | |
storageOS | |
vsphereVolume |
2 常见用法
2.1 pod 直接挂载
2.1.1 pod 直接挂载emptyDir
emptyDir 多用于在同一个pod内的不同容器之间共享数据,它仅仅在pod创建的时候被创建,随着pod的删除而消失(数据也会被永久删除);以下为emptyDir的使用案例:
vim pod-busybox-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox-emptydir
spec:
containers:
- image: busybox:1.32
name: busybox-nfs
resources: {
}
command:
- sh
- -c
- 'sleep 6000'
volumeMounts:
- name: vol-empty
mountPath: /data-empty
readOnly: false
volumes:
- name: vol-empty
emptyDir: {
}
测试效果:
2.1.2 pod 直接挂载hostPath
hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃生舱;以下为 hostPath 的使用案例:
vim pod-busybox-localpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox-local
spec:
containers:
- image: busybox:1.32
name: busybox-nfs
resources: {
}
command: [sh,-c,'sleep 6000']
volumeMounts:
- name: data-local
mountPath: /data-local
volumes:
- name: data-local
hostPath:
path: /disk0
type: Directory
测试效果:
2.1.3 pod 直接挂载nfs
nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod ,不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享;以下为nfs 的使用案例:
此需要预先创建nfs,具体创建方式可以参考笔者博文: shell编程笔记2–nfs挂载

vim pod-busybox-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox-nfs
spec:
containers:
- image: busybox:1.32
name: busybox-nfs
resources: {
}
command: [sh,-c,'sleep 6000']
volumeMounts:
- name: data-nfs
mountPath: /data-nfs
volumes:
- name: data-nfs
nfs:
readOnly: false
server: 10.120.75.102
path: /mnt/mysql01
测试效果:
2.1.4 通过 medium: Memory 挂载shm
默认情况下,pod 中容器shm为64m,但是实际有些业务需要更大量的shm,因此可以通过emptyDir 的 medium: Memory 来挂载宿主机的shm,从而提高容器的shm大小。
vim pod_shm.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-shm
spec:
containers:
- image: busybox:1.32
name: busybox
command:
- /bin/sh
- '-c'
- 'sleep 3600'
volumeMounts:
- mountPath: /dev/shm
name: v-dev-shm
resources:
requests:
cpu: '100m'
memory: '10Mi'
volumes:
- name: v-dev-shm
emptyDir:
medium: Memory
测试效果:
2.2 pod+pv+pvc挂载
2.2.1 localPath
vim pv-mysql-local.yaml
apiVersion: v1
kind: PersistentVolume #资源类型
metadata:
name: mysql-local-pv
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteMany #访问模式,多个客户端读写
persistentVolumeReclaimPolicy: Recycle #回收策略-可以回收
hostPath:
path: /disk0/mysql01
vim pvc-mysql-local.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-local-pvc
namespace: default
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 5Gi
vim pod-mysql-localpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-local
spec:
containers:
- image: busybox:1.32
name: busybox-nfs
resources: {
}
command: [sh,-c,'sleep 10000']
volumeMounts:
- name: data-local
mountPath: /data-local
volumes:
- name: data-local
persistentVolumeClaim:
claimName: mysql-local-pvc
2.2.2 nfs
vim pv-mysql-nfs.yaml
apiVersion: v1
kind: PersistentVolume #资源类型
metadata:
name: mysql-nfs-pv
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteMany #访问模式,多个客户端读写
persistentVolumeReclaimPolicy: Recycle #回收策略-可以回收
nfs:
path: "/mnt/mysql01"
server: 10.120.75.102 #k8s-nfs matser
readOnly: false #只读
vim pvc-mysql-nfs.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-nfs-pvc
namespace: default
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 5Gi
vim pod-mysql-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-nfs
spec:
containers:
- image: busybox:1.32
name: busybox-nfs
resources: {
}
command: [sh,-c,'sleep 10000']
volumeMounts:
- name: data-nfs
mountPath: /data-nfs
volumes:
- name: data-nfs
persistentVolumeClaim:
claimName: mysql-nfs-pvc
3 注意事项
- 使用emptyDir 挂载shm的时候,尽量不要设置limitSize,否则当使用达到上限后会导致pod被驱逐。