容器部署过程中一般有以下三种数据:
挂载外部存储的能力
卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)
两个信息后才可以使用相应的Volume官方给出了k8s支持的所有卷类型,点击查看:Volumes | Kubernetes
存储分为以下几类:
本地:hostPath,emptyDir
网络:nfs,cephfs,rbd,glusterfs
公有云:awsElasticBlockStore,azureDisk
k8s本身存储:secret,configMap,downwardAPI
创建一个空卷,挂载到Pod中的容器。Pod删除该卷也会被删除。
应用场景:Pod中容器之间数据共享
pod实现:网络共享(infra container),存储共享(emptyDir)
示例程序emptyDir.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: write
image: centos
command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;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: {}
卷挂载是针对容器的,故
volumeMounts
要与container
同级
yaml应用完成后,k8s会在宿主机创建一个空目录,路径在/var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~empty-dir/data/
,所有的文件都会挂载在这个空目录中,下面介绍查找方法:
kubectl get pod -o wide
docker ps | grep my-pod
3.找到pod-id:37a7c719-31b6-4a4f-bfa0
4.接着去目录下查看执行结果:
cd /var/lib/kubelet/pods/37a7c719-31b6-4a4f-bfa0-acacea1fac22/volumes/kubernetes.io~empty-dir/data
可以发现文件夹下产生了一个hello文件.文件内容可以直接cat查看或者通过kubectl查看:kubectl logs -f my-pod read
挂载Node文件系统上文件或者目录到Pod中的容器。
应用场景:Pod中容器需要访问宿主机文件
示例:hostPath.yaml
将宿主机/tmp
目录挂载到pod的/data
目录中
apiVersion: v1
kind: Pod
metadata:
name: my-pod2
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- sleep 36000
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
hostPath:
path: /tmp
type: Directory
挂载的目录为当前节点宿主机目录,不是其他节点的也不是远程存储的目录
示例程序nfs.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
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.6
path: /data/nfs
在nfs服务器上新建一个index.html,内容为123:
echo 123 > index.html
选择一个pod,exec进去看看:
以上说明,nfs挂载没问题!其他两个pod中也会有同样的index.html
访问pod的ip:
持久卷对上述配置磁盘(nfs)的角色进行划分,并且抽象出来两个资源:
PersistentVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
1.静态
2.动态
PersistentVolumeClaim(PVC):让用户不需要关心具体的Volume实现细节
解决的痛点:专人做专事,运维只负责提供存储空间,用户不需要关心怎么实现,直接用配置好的存储即可。
pv与pvc一一对应,用户申请一块容量,会匹配一个pv,该pv会与这个pvc绑定
示例:
作为开发者,需要关注前两个yaml,先写部署的镜像信息,再指定数据卷类型(pvc)(左图),然后再指定需要的容量和访问模式(中间图),它们通过pvc的名称关联;这两块一般写在同一个yaml中(左图和中图);右图一般是运维人员提前准备好的pv,里面包含了卷的来源,访问模式和大小
原理图:
解释:中间部分为运维人员准备的一些存储池,存储池中有很多的pv,当开发者在k8s中申请一块存储时,执行完yaml之后,pvc会自动查找与其定义的访问模式或者容量相匹配的pv并与之绑定,只有绑定了pv成功申请了存储之后,pod才会显示running状态,否则一直显示pending状态
注意pv与pvc一一对应并且绑定
总结:
PVC与PV:
示例
my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumes:
- name: www
persistentVolumeClaim:
claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
my-pvc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /data/nfs
server: 192.168.0.6
效果
补充:
Kubernetes支持持久卷的存储插件:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
PV与PVC匹配:
1、访问模式(三种访问方式: ReadWriteOnce(RWO), ReadOnlyMany(ROX), ReadWriteMany(RWX))
2、存储容量(PVC如果没有找到精确对应的PV时,会根据就近PV匹配)
当pvc去申请容量时,它会根据存储类自动创建pv,pvc申请多大空间,pv就会创建多大空间
Kubernetes支持动态供给的存储插件:
https://kubernetes.io/docs/concepts/storage/storage-classes/
由此可见,k8s并不支持nfs的pv动态供给,故需要安装插件让其支持,插件地址为:
https://github.com/kubernetes-incubator/external-storage
下载安装存储插件:点击下载
注意:deployment.yml中的nfs地址需要手动更改!!!路径不存在会自动创建。
cd nfs-client
kubectl apply -f .
示例
my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumes:
- name: www
persistentVolumeClaim:
claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
storageClassName: "managed-nfs-storage" # 指定存储类
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
“The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.” – Tom Cargill
标 题:kubernetes存储(上)