K8s-存储系统

Config Map

apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
# 类属性键;每一个键都映射到一个简单的值
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"

# 类文件键
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
---
apiVersion: v1
kind: Pod
metadata:
name: cm-test-app
spec:
containers:
- name: cm-test-app
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
volumeMounts:
# 挂载的容器目录
- mountPath: /configfiles
name: serverxml
volumes:
# volume的名字
- name: serverxml
configMap:
#cm 的name
name: game-demo
items:
# cm的 key
- key: game.properties
# 容器内文件名字
path: containergame.properties
# cm的 key
- key: user-interface.properties
# 容器内文件名字
path: user-xxx.properties

​ ConfigMap中的配置内容如果是UTF-8编码的字符,则将被系统认 为是文本文件。如果是其他字符,则系统将以二进制数据格式进行保存 (设置为binaryData字段)

Node本地存储卷

Kubernetes管理的Node本地存储卷(Volume)的类型如下。

  • EmptyDir:与Pod同生命周期的Node临时存储
  • HostPath:Node目录
  • Local:基于持久卷(PV)管理的Node目录

EmptyDir

在Volume会在Pod调度到Node上进行创建,与Pod处于同一个生命周期,Pod被销毁,Node上的目录也被销毁。

适用场景

  1. 基于磁盘进行合并的暂存空间
  2. 长时间的计算任务的中间检查点
  3. 为某个Web服务提供的临时网站内容文件

另外,EmptyDir可以通过medium字段设置存储介质为“Memory”, 表示使用基于内存的文件系统(tmpfs、RAM-backed filesystem)。虽然 tmpfs的读写速度非常快,但与磁盘中的目录不同,在主机重启之后, tmpfs的内容就会被清空。此外,写入tmpfs的数据将被统计为容器的内 存使用量,受到容器级别内存资源上限(Memory Resource Limit)的限 制。

HostPath

HostPath类型的存储卷用于将Node文件系统的目录或文件挂载到容 器内部使用

适用场景

  1. 容器内的关键数据需要持久化道宿主机
  2. 需要使用Docker里面某些内部数据,可以讲主机的/var/lib/docker目录挂载到容器内
  3. 监控系统,比如c Advisor需要采集宿主机的/sys目录下的内容
  4. Pod的启动依赖宿主机的某一个目录或文件就绪的场景

type的一些取值:

取值 描述
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory 在给定路径上必须存在的目录。
FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File 在给定路径上必须存在的文件。
Socket 在给定路径上必须存在的 UNIX 套接字。
CharDevice 在给定路径上必须存在的字符设备。
BlockDevice 在给定路径上必须存在的块设备。

一些注意事项:

  1. 即使配置了相同的HostPath,但是多个Pod在不同节点上的配置内容上不相同的
  2. 如果管理员设置了基于存储资源情况的调度策略,则HostPath 目录下的磁盘空间将无法计入Node的可用资源范围内,可能出现与预期 不同的调度结果。
  3. 如果是之前不存在的路径,则由kubelet自动创建出来的目录或 文件的owner将是root,这意味着如果容器内的运行用户(User)不是 root,则将无法对该目录进行写操作,除非将容器设置为特权模式 (Privileged),或者由管理员修改HostPath的权限以使得非root用户可写
  4. HostPath设置的宿主机目录或文件不会随着Pod的销毁而删 除,在Pod不再存在之后,需要由管理员手工删除

PV和PVC

K8s支持静态模式和动态模式,静态模式需要手动创建PV,动态模式则是利用StorageClass,让StorageClass接管,自动完成PV和PVC的绑定。

创建过程

PVC会一直等待适合的PV出现,不然一直在Pending状态。

PV一旦与PVC完成绑定,就会被PVC独占。

删除pvc过程

  1. 对PVC的删除操作将等到使用它的Pod被删除之后再执行 举例来说,当用户删除一个正在被Pod使用的PVC时,PVC对象不 会被立刻删除,查看PVC对象的状态,可以看到其状态 为“Terminating”,以及系统为其设置的Finalizer为“kubernetes.io/pvcprotection”:

  2. 对PV的删除操作将等到绑定它的PVC被删除之后再执行 举例来说,当用户删除一个仍被PVC绑定的PV时,PV对象不会被 立刻删除,查看PV对象的状态,可以看到其状态为“Terminating”,以及 系统为其设置的Finalizer为“kubernetes.io/pvc-protection”:

资源回收

用户使用存储资源之后,可以删除pvc,与PVC绑定的PV会标记为“已释放“,但是不能马上与其他PVC绑定。通过之前的PVC写入的数据储存还在存储设备上,在删除了这些数据之后。PV才能再次使用。

​ PV可以设置资源的回收策略(Reclaim Policy),有 二种Retain(保留数据)、Delete(删除数据)

Retain:

删除PVC之后,PV不会被删除,会标记为released模式,但是PV数据存在,在清空之前不能被使用。清理步骤:

  1. 删除PV对象
  2. 删除PV存储的数据
  3. 创建新的PV

Delete:

自动删除PV的存储数据。

通过动态供应机制创建的PV将继承StorageClass的回收策略,默认 为Delete策略。管理员应该基于用户的需求设置StorageClass的回收策 略,或者在创建出PV后手工更新其回收策略。

StorageClass

StoragesClass资源一但被创建,就无法修改,如果需要修改,只能删除原来的,进行重建。

apiVersion: storage.k8s.io/v1 
kind: StorageClass
metadata:
name: default
namespace: nfs #所在名称空间
provisioner: fuseim.pri/ifs #存储提供者是谁 需要和上段env里指定的name下的
# 资源回收策略,默认是Delete
reclaimPolicy: Retain

绑定模式:VBM

  1. Immediate:当一个PVC创建的时候,动态马上进行PV版定。
  2. WaitForFirstConsumer:PVC和PV的绑定模式延迟到第一个使用PVC的Pod创建之后进行

CSI

在CSI成为Kubernetes的存储供应标准之后,存 储提供方的代码就能与Kubernetes代码彻底解耦,部署也与Kubernetes核 心组件分离。显然,存储插件的开发由提供方自行维护,就能为 Kubernetes用户提供更多的存储功能,也更加安全可靠。基于CSI的存储 插件机制也被称为“out-of-tree”(树外)的服务提供方式,是未来 Kubernetes第三方存储插件的标准方案。

CSI Controller

主要功能是提供存储服务视角对存储资源和存储卷进行管理和操作。在Kubernetes中建议将其部署为单实例Pod,可以使用 StatefulSet或Deployment控制器进行部署,设置副本数量为1,保证一种 存储插件只运行一个控制器实例。

一个Pod会运行俩个容器:

  1. 和master(kube-controller-manager),通信的辅助sidecar容器。在sidecar容器内包含external-attacher和external- provisioner俩个容器。
    • external-attacher:监控Volume Attachment资源对象的变更,接触发对CSI端点的ControlPushlish和ControllerUnpublish操作
    • external-provisioner:监控PersistentVolumeClaim资源对象的变更,触发CSI端点的CreateVolume和DeleteVolume操作
  2. CSI Driver储存驱动容器

CSI Node

主要功能是对Node主机上对Volume进行管理和 操作。在Kubernetes中建议将其部署为DaemonSet,在需要提供存储资源 的各个Node上都运行一个Pod。

在Pod中主要有俩个容器:

  1. 与kubelet通信的辅助sidecar容器的node-driver-register,主要功能是将存储驱动注册到kubelet中
  2. CSI Driver存储驱动容器,,由第三方存储提供商提供,主要功 能是接收kubelet的调用,需要实现一系列与Node相关的CSI接口,例如 NodePublishVolume接口(用于将Volume挂载到容器内的目标路径)、 NodeUnpublishVolume接口(用于从容器中卸载Volume),等等。node-driver-registrar容器与kubelet通过Node主机一个hostPath目录下 的unix socket进行通信。CSI Driver容器与kubelet通过Node主机另一个 hostPath目录下的unix socket进行通信,同时需要将kubelet的工作目录 (默认为/var/lib/kubelet)挂载给CSI Driver容器,用于为Pod进行 Volume的管理操作(包括mount、umount等)