「Kubernetes」- Volumes and Configuration Data

  CREATED BY JENKINSBOT

「卷」在Pod上运行的所有容器都可以访问的目录。「卷」可以保证个别容器重启的时候,数据能够保存下来。

「卷」分为以下几类:

	本地节点卷:emptyDir或者hostPath
	通用网络卷:nfs,flusterfs,cephfs
	云商提供的卷:awsElasticBlickStore,azureDisk,gcePersistentDisk
	特殊用途的卷:secret、gitRepo

使用那种卷根据实际情况确定。

8.1. Exchanging Data Between Containers via a Local Volume

如果一个Pod上运行了两个或多个容器,如果要交换数据,可以使用emptyDir类型的本地数据卷。

以下的两个容器挂载了同一个本地卷:

kind: Pod
apiVersion: v1
metadata:
  name: sahrevol
spec:
  containers:
  - name: c1
    image: centos:7
    command:
      - "sh"
      - "-c"
      - "whatever"
    volumeMount:
      - name: xchange
        mountPath: /tmp/xchange
  - name: c2
    image: centos:7
    command:
      - "sh"
      - "-c"
      - "whatever"
    volumeMount:
      - name: xchange
        mountPath: /tmp/data
  volumns:
  - name: xchange
    emptyDir: {}

创建容器后,可以到容器中查看挂载点。

!!!如果节点关闭,或者节点进行维护,那本地数据会对视。

大多数时候还是使用网络卷。

8.2. Passing an API Access Key to a Pod Using a Secret

如何让开发人员范围一个密钥文件。

	# echo -n "open whatever" > ./passhprase
	# kubectl create secret generic "secret-name" --from-file=./passphrase
	# kubectl describe secrets/pp

上面是管理员的责任,下面就是开发人员使用这个密钥了:

apiVersion: v1
kind: Pod
metadata:
  name: ppconsumer
spec:
  containers:
    - name: shell
      image: busybox
      command:
        - "sh"
	    - "-c"
	    - "whatever"
	  volumeMounts:
	    - name: passphrase
	      mountPath: /tmp/access
	      readOnly: true
  volumes:
    - name: passphrase
      secret:
        secretName: pp

如果需要在容器中访问该密码,则简单的读取/tmp/accsss/passphrase即可。

Secret存在于命名空间的环境中,使用时要考虑到这一点。

通过以下方式可以在Pod上运行的容器中访问Secret:

	卷
	环境变量

加密文件最大1MB数据。除了自定义的Secret外,k8s还会为自动访问API的服务帐号生成Secret。例如,如果安装了Prometheus服务,会自动生成secret。

kubectl create secret可以创建三种类型的secret:

	docker-registry:可以用于注册Docker
	generic:它可以根据本地文件、目录或者常量值生成secret,(你需要自行进行base64编码)
	tls:用于创建Ingress的SSL证书;

命令kubectl describe不会用明文显示secret的内容,避免偷窥。但是内容并未加密,只是进行了base64编码。

kubectl get secret pp -o yaml

k8s 1.7之前,API服务器将secret以明文的方式保存在etcd中。现在可以启动kube-apiserver的时候,使用–experimental-encryption-provider-config对secret进行加密。

8.3. Providing Configuration Data to an Application

如何向应用程序提供配置数据:ConfigMap

通过ConfigMap可以将配置通过「环境变量」或「配置文件」的方式提供给Pod。

	kubectl create configmap "cm-name" --from-literal=siseversion=0.9

现在就可以使用这个配置映射了:

kind: Deploymet
apiVerison: extensions/v1beta1
metadata:
  name: cmapp
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: cmapp
    spec:
      containers
        - name: sise
          image: whatever
          ports:
            - containerPort: 9876
          env:
            - name: SIMPLE_SVC_VERSION
              valueFrom:
                configMapKeyRef:
                  name: sisconfig
                  key: siseversion

也可以从配置文件中创建ConfigMap对象:kubectl create configmap “cm-name” –from-file=example.cfg

接下来挂载配置文件:

kind: Pod
apiVersion: v1
metadata:
  name: oreilly
spec:
  containers:
    - image: busybox
      command:
        - "sh"
        - "-c"
        - "whatever"
      volumeMount:
        - mountPath: /oreilly
          name: oreilly
      name: busybox
  volumes:
    - name: oreilly
      configMap:
        name: "cm-name"

然后该文件是有效的。

8.4. Using a Persistent Volume with Minikube

持久化数据存储:Persistent Volume

创建hostPath类型的PV,并以挂载普通卷的方式将PV挂载到容器的文件系统内。分为两步:

	(1)管理员创建PV对象;
	(2)开发者创建PVC对象;

(1)管理员创建PV对象:

kind: PersistentVolume
apiVerion: v1
metadatda:
  name: hostpathpv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp/data"

# 当然,前提是这个目录是存在的。

(2)开发者创建PVC对象,来使用空间:

# 如果要使用PV,则要先进行PVC定义,声明要使用某个持久卷
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mypvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resource:
    request:
      # 申请200Mi空间
      strage: 200Mi

kubectl create -f pvc.yaml
kubectl get pv # 来查看状态

(3)在容器中使用该卷:

# ...
volume:
  - name: pvc-claim
    persistentVolumeClaim:
      claimName: mypvc

!!!这个案例中使用了hostPath类型的PV,生成环境中不建议使用。应该定义NFS或者Amazon ElasticBlockStore支持的网络卷。

!!!PV是集群内的资源,没有命名空间。而PVC则是命名空间内的资源。

8.5. Understanding Data Persistency on Minikube

掌握Minikube上的数据存储。部署一个有状态的应用程序,例如MySQL集群。

使用PVC申请空间:

# data.yaml
kind: PersistentVolumnClaim
apiVersion: v1
metadata:
  name: data
spec:
  accessModes:
    - ReadWriteOnce
  resource:
    requests:
      storage: 1Gi

然后创建该PVC:kubctl create -f data.yaml
查看状态:kubectl get pv

接下来就是在Pod中使用该PVC:

kind: Pod
apiVersion: v1
metadata:
  name: db
spec:
  container:
    - name: mysql
      image: mysql:5.5
      volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
      env:
        - name: MySQL_ROOT_PATH
          value: root
  volumns:
    - name: data
      persistentVolumeClaim:
        claimName: data

!!!minikube中有默认的存储类,该存储类定义了一个默认的PV provisioner,这意味这当PVC创建时,k8s会自动创建一个相应的PV来忙组该PVC。

!!!查看minikube的默认存储类:kubectl get storageclass,该存储类使用的存储provisioner会创建hostPath类型的PV。

!!!你可以测试以下,直接定义一个PVC,然后使用kubectl get pv命令查看自动创建的PV。因此,即使Pod死亡,或者被删除,数据依旧会保存下来。

storage classes允许管理员定义各种所需的存储类。对于开发人员来说,storage classes可以抽象存储类型,并方便开发人员直接使用PVC,而无需关心存储本身。

8.6. Dynamically Provisioning Persistent Storage on GKE

Dynamic Volume Provisioning