参考:https://kubernetes.io/docs/concepts/storage/volumes/
一个运行中的容器,缺省情况下,对文件系统的写入,都是发生在其分层文件系统的可写层的,一旦容器运行结束,所有写入都会被丢弃。因此需要对持久化支持。
Kubernetes 中通过 Volume 的方式提供对存储的支持。下面对一些常见的存储概念进行一点简要的说明。
EmptyDir
顾名思义,EmptyDir是一个空目录,他的生命周期和所属的 Pod 是完全一致的,可能读者会奇怪,那还要他做什么?EmptyDir的用处是,可以在同一 Pod 内的不同容器之间共享工作过程中产生的文件。
缺省情况下,EmptyDir 是使用主机磁盘进行存储的,也可以设置emptyDir.medium 字段的值为Memory,来提高运行速度,但是这种设置,对该卷的占用会消耗容器的内存份额。
apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: - image: gcr.io/google_containers/test-webserver name: test-container volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {}
HostPath
这种会把宿主机上的指定卷加载到容器之中,当然,如果 Pod 发生跨主机的重建,其内容就难保证了。
这种卷一般和DaemonSet搭配使用,用来操作主机文件,例如进行日志采集的 FLK 中的 FluentD 就采用这种方式,加载主机的容器日志目录,达到收集本主机所有日志的目的。
apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: - image: gcr.io/google_containers/test-webserver name: test-container volumeMounts: - mountPath: /test-pd name: test-volume volumes: - name: test-volume hostPath: # directory location on host path: /data
NFS/GlusterFS/CephFS/AWS/GCE 等等
作为一个容器集群,支持网络存储自然是重中之重了,Kubernetes 支持为数众多的云提供商和网络存储方案。
各种支持的方式不尽相同,例如 GlusterFS 需要创建 Endpoint,Ceph/NFS 之流就没这么麻烦了。
各种个性配置可移步参考文档。
ConfigMap 和 Secret
镜像使用的过程中,经常需要利用配置文件、启动脚本等方式来影响容器的运行方式,如果仅有少量配置,我们可以使用环境变量的方式来进行配置。然而对于一些较为复杂的配置,例如 Apache 之类,就很难用这种方式进行控制了。另外一些敏感信息暴露在 YAML 中也是不合适的。
ConfigMap 和 Secret 除了使用文件方式进行应用之外,还有其他的应用方式;这里仅就文件方式做一点说明。
例如下面的 ConfigMap,将一个存储在 ConfigMap 中的配置目录加载到卷中。
apiVersion: v1 kind: Pod metadata: name: dapi-test-pod spec: containers: - name: test-container image: gcr.io/google_containers/busybox command: [ "/bin/sh", "-c", "ls /etc/config/" ] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: # Provide the name of the ConfigMap containing the files you want # to add to the container name: special-config restartPolicy: Never
注意,这里的 ConfigMap 会映射为一个目录,ConfigMap 的 Key 就是文件名,每个 Value 就是文件内容,比如下面命令用一个目录创建一个 ConfigMap:
kubectl create configmap \ game-config \ --from-file=docs/user-guide/configmap/kubectl
创建一个 Secret:
kubectl create secret generic \ db-user-pass --from-file=./username.txt \ --from-file=./password.txt
使用 Volume 加载 Secret:
apiVersion: v1 kind: Pod metadata: name: mypod namespace: myns spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: /etc/foo readOnly: true volumes: - name: foo secret: secretName: mysecret
可以看到 Secret 和 ConfigMap 的创建和使用是很相似的。在 RBAC 中,Secret 和 ConfigMap 可以进行分别赋权,以此限定操作人员的可见、可控权限。
PV & PVC
PersistentVolume 和 PersistentVolumeClaim 提供了对存储支持的抽象,也提供了基础设施和应用之间的分界,管理员创建一系列的 PV 提供存储,然后为应用提供 PVC,应用程序仅需要加载一个 PVC,就可以进行访问。
而 1.5 之后又提供了 PV 的动态供应。可以不经 PV 步骤直接创建 PVC。
参考:http://blog.fleeto.us/translation/dynamic-provisioning-and-storage-classes-kubernetes-0