k8s学习笔记(五)存储

为了管理存储,Kubernetes提供了Secret用于管理敏感信息,ConfigMap存储配置,Volume、PV、PVC、StorageClass等用来管理存储卷。

一、Secret

Secret有三种类型:

  • Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
  • Opaque :base64编码格式的Secret,用来存储密码、密钥等;
  • kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息。

Opaque Secret

Opaque类型的数据是一个map类型,要求value是base64编码格式:

获取base64

创建Opaque Secret

使用secret的方式有两种:

  • 以Volume方式
  • 以环境变量方式
将Secret挂载到Volume中

将Secret导出到环境变量中

Service Account

Service Account用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中。

二、ConfigMap

ConfigMap API资源用来保存key-value pair配置数据,这个数据可以在pods里使用,或者被用来为像controller一样的系统组件存储配置数据。

创建ConfigMap的方式有三种:

  • 使用目录创建
  • 使用文件创建
  • 使用字面值创建

使用目录创建

比如我们已经有了一些配置文件,其中包含了我们想要设置的ConfigMap的值:

使用下面的命令可以创建一个包含目录中所有文件的ConfigMap。

使用文件创建

刚才使用目录创建的时候我们—from-file指定的是一个目录,只要指定为一个文件就可以从单个文件中创建ConfigMap。

使用字面值创建

使用文字值创建,利用—from-literal参数传递配置信息,该参数可以使用多次,格式如下;

Pod中使用ConfigMap

其实与Secret类似

使用ConfigMap来替代环境变量

创建后输出内容:

用ConfigMap设置命令行参数

基于上述的ConfigMap,在command中进行输出

输出内容

通过数据卷插件使用ConfigMap

在数据卷里面使用这个ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容:

我们也可以在ConfigMap值被映射的数据卷里控制路径。

三、Volume、 Persistent Volume

首先要区分docker volume和k8s volume的区别。

对于无状态的Docker容器,容器重启时容器数据会自动清除。对于数据库、日志文件等可以实时变化的数据我们需要使用Volume。

Kubernetes底层支持Docker的容器运行引擎,为了不绑定在特定的容器技术上,Kubernetes没有使用Docker的Volume机制,而是重新制定了自己的通用数据卷插件规范,以配合不同的容器运行时来使用(如Docker和rkt)。

可以参考这个链接:https://zhuanlan.zhihu.com/p/62908569

Volume

Volume 分为本地数据卷 和 网络数据卷。

本地数据卷

1、 emptyDir,是一个匿名的空目录, 由k8s在创建pod的时候创建,销毁的时候一起销毁。

2、 hostPath, 与emptyDir的区别是,它在Pod之外独立存在,由用户指定路径名。

网络数据卷

这种存储卷不和某个具体的K8S节点绑定,而是独立于K8S节点存在的,整个存储集群和K8S集群是两个集群,相互独立。

Kubernetes 支持以下类型的卷:

  • awsElasticBlockStore
  • azureDisk
  • azureFile
  • cephfs
  • csi
  • downwardAPI
  • fc
  • flocker
  • gcePersistentDisk
  • gitRepo
  • glusterfs
  • iscsi
  • local
  • nfs
  • persistentVolumeClaim
  • projected
  • portworxVolume
  • quobyte
  • rbd
  • scaleIO
  • secret
  • storageos
  • vsphereVolume

等等。

如果已有的存储不能满足要求,还可以开发自己的Volume插件,只需要实现Volume.go 里定义的接口。

参考:https://github.com/kubernetes/kubernetes/blob/master/pkg/volume/volume.go

Persistent Volume

普通Volume和使用它的Pod之间是一种静态绑定关系,在定义Pod的文件里,同时定义了它使用的Volume。Volume 是Pod的附属品,我们无法单独创建一个Volume,因为它不是一个独立的K8S资源对象。

而Persistent Volume 简称PV是一个K8S资源对象,所以我们可以单独创建一个PV。它不和Pod直接发生关系,而是通过Persistent Volume Claim,简称PVC来实现动态绑定。Pod定义里指定的是PVC,然后PVC会根据Pod的要求去自动绑定合适的PV给Pod使用。

PV的访问模式
  • ReadWriteOnce(RWO):是最基本的方式,可读可写,但只支持被单个Pod挂载。
  • ReadOnlyMany(ROX):可以以只读的方式被多个Pod挂载。
  • ReadWriteMany(RWX):这种存储可以以读写的方式被多个Pod共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是NFS。在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。
配置方式

静态配置,是管理员手动创建一堆PV,组成一个PV池,供PVC来绑定。

动态配置,是指在现有PV不满足PVC的请求时,可以使用存储分类(StorageClass),

描述具体过程为:PV先创建分类,PVC请求已创建的某个类(StorageClass)的资源,这样就达到动态配置的效果。即通过一个叫 Storage Class的对象由存储系统根据PVC的要求自动创建。

回收策略
  • Retain – 手动重新使用
  • Recycle – 基本的删除操作 (“rm -rf /thevolume/*”)
  • Delete – 关联的后端存储卷一起删除,后端存储例如AWS EBS, GCE PD或OpenStack Cinder
卷的状态
  • Available –闲置状态,没有被绑定到PVC
  • Bound – 绑定到PVC
  • Released – PVC被删掉,资源没有被在利用
  • Failed – 自动回收失败
持久卷的声明

PersistentVolumeClaim

访问模式

在请求具有特定访问模式的存储时,声明使用与卷相同的约定。

卷模式

声明使用与卷相同的约定,指示将卷作为文件系统或块设备使用。

资源

像 pod 一样,声明可以请求特定数量的资源。在这种情况下,请求是用于存储的。相同的资源模型适用于卷和声明。

选择器

声明可以指定一个标签选择器来进一步过滤该组卷。只有标签与选择器匹配的卷可以绑定到声明。选择器由两个字段组成:

  • matchLabels:volume 必须有具有该值的标签
  • matchExpressions:这是一个要求列表,通过指定关键字,值列表以及与关键字和值相关的运算符组成。有效的运算符包括 In、NotIn、Exists 和 DoesNotExist。

所有来自 matchLabels 和 matchExpressions 的要求都被“与”在一起——它们必须全部满足才能匹配。

声明可以通过使用属性 storageClassName 指定 StorageClass 的名称来请求特定的类。只有所请求的类与 PVC 具有相同 storageClassName 的 PV 才能绑定到 PVC。

PVC 不一定要请求类。其 storageClassName 设置为 “” 的 PVC 始终被解释为没有请求类的 PV,因此只能绑定到没有类的 PV(没有注解或 “”)。

PVC的声明