前面已经介绍过,有些应用如果意外宕机,Kubernetes会将应用自动重启的机制,如rc、Deployment等,但是重启的Pod如何保证数据一致呢,这里就需要借助kubernetes的多种存储,例如ConfigMap(专门用来存储配置文件,就像配置文件中心)、Secret(存储一些需要加密的数据)、Volumn(用来存储一些数据)、PV(Persistent Volumn,一个动态的存储)。
ConfigMap
ConfigMap功能在Kubernetes1.2版本中引入,许多应用程序会从配置文件、命令行参数或者环境变量中读取配置信息。ConfigMap API给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制对象。
创建一个ConfigMap
ConfigMap可以使用目录创建、使用文件创建、使用字面值创建。
- 使用目录创建
1 | # ls ./configmap |
-from-file指定在目录下的所有文件都会在ConfigMap里面创建一个键值对,键的名字就是文件名,值就是文件的内容 *
- 使用文件创建
只要指定一个文件就可以从单个文件中创建ConfigMap
1 | # kubectl create configmap my-config --from-file=./configmap/a.properties |
-from-file这个参数可以使用多次,你可以使用两次分别指定上个例子中的那两个配置文件,效果就跟指定整个目录是一样的。
- 使用字面值创建
使用字面值创建,利用-from-litteral参数传递配置信息,该参数可以使用多次,格式如下
1 | # kubectl create configmap my-config --from-literal=log.level=warn |
Pod中使用ComfigMap
- 使用
ConfigMap来代替环境变量
1 | # vim configmap-env.yaml |
- 通过数据卷插件来使用
ConfigMap
1 | # vim configmap-volumn.yaml |
Secret
Secret解决了密码、token、密钥等敏感数据的配置,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。
Secret可以以Volumn或者环境变量的方式使用
Secret有三种类型:
ServiceAccount:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;Opaque:base64编码格式的Secret,用来存储密码、密钥等;kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
这里我们仅了解Opaque Secret,其他两种Secret暂时不做深究
Opaque Secret
- 创建及使用
Opaque类型的数据是一个map类型,要求value是base64编码格式:
1 | # echo -n "admin"|base64 |
Volumn 卷
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,Kubelet会重启它,但是容器中的文件将丢失–容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的Volumn抽象就很好的解决了这些问题。目前,Kubernetes支持多种类型的Volumn,例如GlusterFs、Ceph等先进的分布式文件系统。
Volumn的使用也比较简单,在大多数情况下,我们现在Pod上声明一个Volumn,然后在容器里引用该Volumn并Mount到容器里的某个目录上。举例来说,我们要给之前Tomcat Pod增加一个名字为dataVol的Volumn,并且Mount到容器的/mydata-data目录下,则只要对Pod的定义文件做如下修改即可
1 | spec: |
上面例子中emptyDir是Volumn的一种类型,Kubernets提供了丰富的Volumn类型。
emptyDir
一个emptyDir Volumn是在Pod分配到Node时创建的,从它的名字可以看出,他的初始化内容为空,并且无需指定宿主机上对应的目录文件,因为这是Kubernetes自动分配的一个目录,当Pod从Node上移除时,emptyDir中的数据也会被永久删除。
hostPath
hostPath为在Pod上挂载宿主机上的文件或目录。在下面的例子中使用宿主机的/data定义了一个hostPath类型的Volumn:
1 | volumes: |
Persistent Volumn
之前我们提到的Volumn是定义在Pod上的,属于“计算资源”的一部分,而实际上,“网络存储”是相对独立于“计算资源”而存在的一种实体资源。比如在使用虚拟机的情况下,我们通常会先定义一个网络存储,然后从中划出一个“网盘”并挂在到虚拟机上。Persistent Volumn(简称PV)和与之关联的Persistent Volumn Clain(简称PVC)也起到了类似的作用。
PV可以理解成Kubernetes集群中的某个网络存储中对应的一块存储,它与Volumn很类似,但有以下区别。
PV只能是网络存储,不属于任何Node,但可以在每个Node上访问。PV并不是定义在Pod上的,而是独立于Pod之外定义。PV目前只有一种类型:GCE Persistent Disks、NFS、RBD、iSCSCI、AWS ElasticBlockStore、CluserFS等。
下面给出了NFS类型PV的一个yaml定义声明,声明了需要5Gi的存储空间:
1 | apiVersion: v1 |
如果某个Pod想申请某种条件的PV,则首先需要定义一个PersistentVolumnClaim(PVC)对象:
1 | kind: PersistentVolumnClaim |
然后在Pod的Volumn定义中引用上述PVC即可:
1 | volumes: |
– 引用自知乎一起学习k8s