本文共 4989 字,大约阅读时间需要 16 分钟。
本文环境为Kubernetes V1.11,操作系统版本为 CentOs 7.3,Kubernetes集群安装可以参考
容器中的存储都是临时的,因此Pod重启的时候,内部的数据会发生丢失。实际应用中,我们有些应用是无状态,有些应用则需要保持状态数据,确保Pod重启之后能够读取到之前的状态数据,有些应用则作为集群提供服务。这三种服务归纳为无状态服务、有状态服务以及有状态的集群服务,其中后面两个存在数据保存与共享的需求,因此就要采用容器外的存储方案。
Kubernetes中存储中有四个重要的概念:Volume、PersistentVolume PV、PersistentVolumeClaim PVC、StorageClass。掌握了这四个概念,就掌握了Kubernetes中存储系统的核心。我用一张图来说明这四者之间的关系。
volume
属性来定义存储的类型,通过volumeMount
来定义容器内的挂载点。StorageClassName
、matchLabels
或者matchExpressions
三种方式。Docker提供了,Volume 是磁盘上的文件夹并且没有生命周期的管理。Kubernetes 中的 Volume 是存储的抽象,并且能够为Pod提供多种存储解决方案。Volume 最终会映射为Pod中容器可访问的一个文件夹或裸设备,但是背后的实现方式可以有很多种。
emptyDir在Pod被分配到Node上之后创建,并且在Pod运行期间一直存在。初始的时候为一个空文件夹,当Pod从Node中移除时,emptyDir将被永久删除。Container的意外退出并不会导致emptyDir被删除。emptyDir适用于一些临时存放数据的场景。默认情况下,emptyDir存储在Node支持的介质上,不管是磁盘、SSD还是网络存储,也可以设置为Memory
。
apiVersion: v1kind: Podmetadata: name: tomcat-ccb namespace: default labels: app: tomcat node: devops-103spec: containers: - name: tomcat image: docker.io/tomcat volumeMounts: - name: tomcat-storage mountPath: /data/tomcat - name: cache-storage mountPath: /data/cache ports: - containerPort: 8080 protocol: TCP env: - name: GREETING value: "Hello from devops-103" volumes: - name: tomcat-storage hostPath: path: /home/es - name: cache-storage emptyDir: {}
hostPath就是将Node节点的文件系统挂载到Pod中,在之前的例子中也可以看到用法。
apiVersion: v1kind: Podmetadata: name: test-pdspec: containers: - image: k8s.gcr.io/test-webserver name: test-container volumeMounts: - mountPath: /test-pd name: test-volume volumes: - name: test-volume hostPath: # directory location on host path: /data # this field is optional type: Directory
A local volume represents a mounted local storage device such as a disk, partition or directory.
local类型作为静态资源被PersistentVolume使用,不支持Dynamic provisioning。与hostPath相比,因为能够通过PersistentVolume的节点亲和策略来进行调度,因此比hostPath类型更加适用。local类型也存在一些问题,如果Node的状态异常,那么local存储将无法访问,从而导致Pod运行状态异常。使用这种类型存储的应用必须能够承受可用性的降低、可能的数据丢失等。
apiVersion: v1kind: PersistentVolumemetadata: name: wwwspec: capacity: storage: 100Mi volumeMode: Filesystem accessModes: ["ReadWriteOnce"] persistentVolumeReclaimPolicy: Delete storageClassName: local-storage local: path: /home/es nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - devops-102 - devops-103
对于使用了PV的Pod,Kubernetes会调度到具有对应PV的Node上,因此PV的节点亲和性 nodeAffinity 属性是必须的。
PersistentVolume nodeAffinity is required when using local volumes. It enables the Kubernetes scheduler to correctly schedule Pods using local volumes to the correct node.
Persistent Volumes 提供了一个抽象层,向用户屏蔽了具体的存储实现形式。
生命周期:
PersistenVolume 这个功能目前是通过Plugin插件的形式实现的,目前的版本V1.11.1有19中,特别关注了一下HostPath。
HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
kind: PersistentVolumeClaimapiVersion: v1metadata: name: myclaimspec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 8Gi storageClassName: slow selector: matchLabels: release: "stable" matchExpressions: - {key: environment, operator: In, values: [dev]}
一些属性
matchLabels
和matchExpressions
。StorageClass为管理员提供了一种描述存储类型的方法。通常情况下,管理员需要手工创建所需的存储资源。利用动态容量供给的功能,就可以实现动态创建PV的能力。动态容量供给 Dynamic Volume Provisioning 主要依靠StorageClass。
kind: StorageClassapiVersion: storage.k8s.io/v1metadata: name: local-storageprovisioner: kubernetes.io/no-provisionervolumeBindingMode: WaitForFirstConsumer
转载地址:http://aqrkz.baihongyu.com/