kubernetes 存储卷
前言
默认情况下容器的数据都是非持久化的, 在容器消亡以后数据也跟着丢失, 所以 Docker 提供了 Volume 机制以便将数据持久化存储。 类似的, Kubernetes 提供了更强大的 Volume 机制和丰富的插件, 解决了容器数据持久化和容器间共享数据的问题。 与 Docker 不同, Kubernetes Volume 的生命周期与 Pod 绑定容器挂掉后 Kubelet 再次重启容器时, Volume 的数据依然还在而 Pod 删除时, Volume 才会清理。 数据是否丢失取决于具体的 Volume 类型, 比如 emptyDir 的数据会丢失, 而 PV 的数据则不会丢 PersistentVolume(pv)和PersistentVolumeClaim(pvc)是k8s提供的两种API资源,用于抽象存储细节。管理员关注于如何通过pv提供存储功能而无需关注用户如何使用,同样的用户只需要挂载pvc到容器中而不需要关注存储卷采用何种技术实现。 pvc和pv的关系与pod和node关系类似,前者消耗后者的资源。pvc可以向pv申请指定大小的存储资源并设置访问模式。
pv pvc相关知识
生命周期
pv和pvc遵循以下生命周期:
- 1.供应准备。管理员在集群中创建多个pv供用户使用。
- 2.绑定。用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前,pvc会保持未绑定状态。
- 3.使用。用户可在pod中像volume一样使用pvc。
- 4.释放。用户删除pvc来回收存储资源,pv将变成“released”状态。由于还保留着之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他pvc使用。
- 5.回收。pv可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。
- 保留策略允许人工处理保留的数据。
- 删除策略将删除pv和外部关联的存储资源,需要插件支持。
- 回收策略将执行清除操作,之后可以被新的pvc使用,需要插件支持。
pv属性
pv拥有以下属性:
- 容量,目前仅支持存储大小,未来可能支持IOPS和吞吐量等。
- 访问模式,ReadWriteOnce:单个节点读写。ReadOnlyMany:多节点只读。ReadWriteMany:多节点读写。挂载时只能使用一种模式。
- 回收策略,目前NFS和HostPath支持回收。 AWS、EBS、GCE、PD和Cinder支持删除。
- 阶段,分为Available(未绑定pvc)、Bound(已绑定)、Released(pvc已删除但资源未回收)、Failed(自动回收失败)
pvc属性
- 访问模式,与pv的语义相同。在请求资源时使用特定模式。
- 资源,申请的存储资源数量
pv类型
- emptyDir
- hostPath
- gcePersistentDisk
- awsElasticBlockStore
- nfs
- iscsi
- flocker
- glusterfs
- rbd
- cephfs
- gitRepo
- secret
- persistentVolumeClaim
- downwardAPI
- azureFileVolume
- ................
- ........(以下省略)
目前常用Volume 类型
emptyDir
如果 Pod 设置了 emptyDir 类型 Volume, Pod 被分配到 Node 上时候, 会创建emptyDir, 只要 Pod 运行在 Node 上, emptyDir 都会存在( 容器挂掉不会导致emptyDir 丢失数据) , 但是如果 Pod 从 Node 上被删除( Pod 被删除, 或者 Pod 发生迁移) , emptyDir 也会被删除, 并且永久丢失。
hostPath
hostPath 允许挂载 Node 上的文件系统到 Pod 里面去。 如果 Pod 需要使用 Node 上的文件, 可以使用 hostPath
NFS
NFS 是 Network File Syste
m 的缩写, 即网络文件系统。 Kubernetes 中通过简单地配置就可以挂载 NFS 到 Pod 中, 而 NFS 中的数据是可以永久保存的, 同时 NFS 支持同时写操作。
gcePersistentDisk
gcePersistentDisk 可以挂载 GCE 上的永久磁盘到容器, 需要 Kubernetes 运行在 GCE的 VM 中
awsElasticBlockStore
awsElasticBlockStore 可以挂载 AWS 上的 EBS 盘到容器, 需要 Kubernetes 运行在AWS 的 EC2 上。
gitRepo
gitRepo volume 将 git 代码下拉到指定的容器路径中
Projected Volume
Projected volume 将多个 Volume 源映射到同一个目录中, 支持 secret、 downwardAPI和 configMap
简单示例
emptyDir (节点级存储,生命周期与pod相同)
pod中有两个container挂载同一个emptyDir,nginx提供web服务,busybox则循环向挂载目录下的index.html文件写入数据
apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: myapp containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html - name: busybox image: busybox:latest volumeMounts: - name: html mountPath: /data command: - "/bin/sh" - "-c" - "while true; do echo $(date) >> /data/index.html; sleep 2; done" volumes: - name: html emptyDir: {}
查看pod是否运行
kubectl get pod -o wide
访问 pod
while true; do curl 10.32.0.6; sleep 1; done
hostPath (节点级存储,生命周期和node相同)
apiVersion: v1 kind: Pod metadata: name: pod-vol-hostpath namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html hostPath: path: /data/pod/volume1 type: DirectoryOrCreate
部署 pod
kubectl apply -f pod-hostpath-vol.yaml
创建挂载的目录
cd /data/pod/volume1 #添加一个index.html测试文件 echo "node1" > /data/pod/volume1/index.html
测试访问 (pod 删除在重新部署,文件还在)
kubectl get pods pod-vol-hostpath -o wide curl 10.32.0.6
NFS(永久存储,生命周期与NFS server相同)
安装 nfs 服务
# cents os yum install -y nfs-utils # ubuntu apt install nfs-kernel-server mkdir -p /data/volumes
在节点192.168.228.138创建nfs共享目录/data/volumes 并共享给192.168.228.0(这个根据自己的集群节点进行设置)网段都可以使用,并且root用户也可压缩使用
vi /etc/exports
重启 nfs 服务
# centos systemctl start nfs # ubuntu service nfs-kernel-server restart
定义 pod 挂载 nfs 服务资源
KIND: Pod VERSION: v1 RESOURCE: nfs <Object> DESCRIPTION: NFS represents an NFS mount on the host that shares a pod's lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs Represents an NFS mount that lasts the lifetime of a pod. NFS volumes do not support ownership management or SELinux relabeling. FIELDS: path <string> -required- #nfs服务器上是哪个路径 Path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs readOnly <boolean> #要不要挂载为只读,默认为false ReadOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs server <string> -required- #服务器地址 Server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
apiVersion: v1 kind: Pod metadata: name: pod-nfs namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html nfs: path: /data/volumes server: 192.168.228.138
部署 pod
kubectl apply -f pod-nfs-vol.yaml
写入数据到nfs中
echo "<h1>NFS stor01<h1>" >> /data/volumes/index.html echo "<h1>NFS zhangbiao<h1>" >> /data/volumes/index.html
查看 pod 的 ip 地址
kubectl get pods -o wide
访问 pod 中的 nginx 服务
curl 10.32.0.2
删除 pod 资源在重新创建,不论下载 pod 调度到那个节点上都能够正常的访问,从而实现持久话存储
kubectl delete -f pod-vol-nfs.yaml kubectl apply -f pod-vol-nfs.yaml curl 10.32.0.2