k8s 卷存储
应用场景
pod 中的容器的数据随着pod 的重启,删除就会消失,有的应用场景需要持久化数据,这时就需要卷挂载。
Tips:
volumes 是 pod 的一个组成部分, 因此像容器一样在 pod 的规范中就定义了。 它们不是独立的 Kubernetes 资源对象, 也不能单独创建或删除。 pod 中的所有容器都可以使用卷, 但必须先将它挂载在每个需要访问它的容器中。 在每个容器中, 都可以在其文件系统的任意位置挂载卷。
常见的类型
empty 配置
emptyDir类型的Volume在Pod分配到Node上时被创建,Kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。 这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。
在Pod中的定义
apiVersion: vl kind: Pod metadata: name: fortune spec: containers: - image: luksa/fortune #第一个容器名为 html-asdf name: html-asdf volumeMounts: - name: html #容器挂载的本地卷为 html mountPath: /var/htdocs #挂载到容器的此目录 - image: nginx:alpine name: web-server #第二个容器称为 web-server volumeMounts : - name: html #容器挂载的本地卷为 html mountPath: /usr/share/nginx/html #设为只读 readOnly: true ports: - containerPort: 80 protocol: TCP volumes - name: html #命名为html emptyDir: {} #卷的类型为emptyDir
volumes: - name: html emptyDir medium: Memory
使用 Git 仓库作为存储卷
Notice:
apiVersion: vl kind: Pod metadata: name: gitrepo-vol-pod spec: containers: - image: nginx:alpine name: web-server volumeMounts : - name : html mountPath: /usr/share/nginx/html readOnly: true ports: - containerPort: 80 protocol: TCP volumes: - name: html #容器挂载的本地卷为 html gitRepo: repository: https://github.com/kzf/asdf-website-example.git revision: master directory: .
Tips:
为了实现pod gitrepo 目录与git 仓库实时同步可以通过 sidecar 容器
hostPath卷
应用场景
使用持久化存储
使用云厂商的存储
apiVersion: vl kind: Pod metadata: name: mongodb spec: volumes: - name: mongodb-data awsElasticBlockStore: volumeid: my-volume fsType: ext4 containers: ...
使用NFS卷
volumes: - name: vol-name nfs: server: 1.2.3.4 path: /somewhere/path
使用其他存储技术
从底层存储技术解耦pod(持久卷和持久卷声明)
创建持久卷
持久卷不属于任何命名空间, 它跟节点一样是集群层面的资源。
apiVersion: vl kind: PersistentVolume metadata: name: fortune spec: capacity: storage: lGi accessModes: - ReadWriteOnce #可以被单个客户端挂载为读写模 - ReadOnlyMany #式或者被多个客户端挂载为只读(这里指的是持久卷声明) persistentVolumeReclaimPolicy: Retain #当声明被释放后,PersistentVolume 将会被保留(不清理和删除) gcePersistentDisk: #PersistentVolume指定支持之前创建的GCE持久磁盘 pdName: asdf fsType: ext4
查看
$ kubectl get pv
NAME CAPACITY RECLAIMPOLICY ACCESSMODES STATUS
mongodb-pv lGi Retain RWO,ROX Available
通过创建持久卷声明来获取持久卷
持久卷声明是属于命名空间的资源对象,持久卷声明只能被同一命名空间内的 pod 创建使用
apiVersion: vl kind: PersistentVolumeClaim metadata: name: fortune-pvc spec: resources: requests: storage: lGi #申请1G 的存储空间 accessModes: - ReadWriteOnce #可以被单个客户端挂载为读写模 storageClassName: "" #将空字符串指定为存储类名可确保PVC 绑定到预先配置的 PV,而不是动态配置新的PV。关于动态配置pv 下文有介绍。
当创建好声明, kubernetes 就会找到适当的持久卷并将其绑定到声明 ,持久卷的容量必须足够大以满足声明的需求,并且卷模式必须包含声明中指定的访问模式 。在该示例中,声明请求 1GiB 的存储空间和 ReadWriteOnce 访问模式,之前创建的持久卷符合刚刚声明中 的这两个条件,所以它被绑定到对应的声明中。
列举持久卷声明
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
mongodb-pvc Bound mongodb-pv lGi RWO,ROX 3s
RWO ReadWriteOnce -- 仅允许单个节点挂载读写。 ROM ReadOnlyMany -- 仅允许多个节点挂载只读。 RWX ReadWriteMany -- 允许多个节点挂载读写这个卷。
pod 中使用持久卷声明
apiVersion: vl kind: Pod metadata: name: mongodb spec: containers: - image: mongo name: mongodb volumeMounts: - name : mogodb-data mountPath: /data/db ports: - containerPort: 27017 protocol: TCP volumes: - name: mongodb-data persistentVolumeClaim: claimName: mongodb-pvc
针对持久卷的回收有两种方式:自动回收,手动回收。
持久卷的动态卷配置
StorageClass 资源定义
apiVersion: vl kind: StorageClass metadata: name: fast provisioner: kubernetes.io/gce-pd #用于配置持久卷的插件 parameters: type:pd-ssd #传递给parameters的参数 zone:europe-westl-b
创建一个请求特定存储类的 PVC 定义
vi storageclass.yaml apiVersion: vl kind: PersistentVolumeClaim metadata: name: mongodb-pvc spec: storageClassName:fast #该pvc请求自定义存储类 resources: requests storage: lGi #申请1G 的存储空间 accessModes: - ReadWriteOnce #可以被单个客户端挂载为读写模 随后查看会发现自动生成了一个持久卷 $ kubectl get pv NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS STORAGECLASS pvc-le6bc048 lGi RWO Delete Bound fast 可以看到动态配置的持久卷其容量和访问模式是在PVC中所要求的 。它的回收策略是 Delete,这意味着当PVC被删除时,持久卷也将被删除。 除了 PV置备程序还提供了真实的存储空间,fast StorageClass 被配置为使用 kubernetes.io/gce-pd 从而提供了GCE 持久磁盘。 可以使用以下命令查看磁盘 $ gcloud compute disks list NAME ZONE SIZE_GB TYPE STATUS kekub-dy-pvc-le6bc04 europe-westl-d 1 pd-standard READY 如上所示例 盘的名称表明它是动态配置的, 同时 类型显示为一个 SSD,正如在前面创建的存储类中所指定的那样。
注意 如果在 PVC 中引用一个不存在的存储类, PV 的配直将失败(在 PVC 上使用 kubectl describe 时,将会看到 ProvisioningFailed 事件)
了解存储类的使用
$ kubectl get sc NAME TYPE fast kubernetes.io/gce-pd standard (default) kubernetes.io/gce-pd
Notice:
1、如果持久卷 明没有明确指出要使用哪个存储类, 默认存储类会用于动态提供持久卷的内容。
2、如果尚未将 storageClassName 属性设置为空字符串, 则尽管已存在适当的预配置持久卷,但动态卷置备程序仍将配置新的持久卷。
动态持久卷的配置图