Projected Volume

投射数据卷http://docs.kubernetes.org.cn/429.html#projected
为容器提供预先定义好的数据,从容器的角度来看,这些 Volume 里的信息是被 Kubernetes“投射进容器中的”
到目前为止,Kubernetes 支持的 Projected volume一共有4种
secret,configMap, downwardAPI, serviceAccountToken(特殊的secret)

Secret

https://kubernetes.io/zh/docs/concepts/configuration/secret/
Secret 对象要求这些数据必须是经过 Base64 转码,以免出现明文隐患

  1. # echo -n 'admin' | base64
  2. YWRtaW4=
  3. # echo -n '123456' |base64
  4. MTIzNDU2

创建secret对象

  1. # cat user
  2. YWRtaW4=
  3. # cat pass
  4. MTIzNDU2
  5. # kubectl create secret generic user --from-file=./user
  6. # kubectl create secret generic pass --from-file=./pass
  7. # kubectl get secret |egrep "pass|user"
  8. pass Opaque 1 18h
  9. user Opaque 1 18h

YAML形式

  1. # cat secret.yaml
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5. name: robinsecert
  6. type: Opaque
  7. data:
  8. user: YWRtaW4=
  9. pass: MTIzNDU2
  10. # kubectl apply -f secret.yaml
  11. # kubectl get secret |grep secert
  12. robinsecert Opaque 2 18h

创建pod对象声明挂载secret对象

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: test-projected-volume
  5. spec:
  6. containers:
  7. - name: test-secret-volume
  8. image: busybox
  9. args:
  10. - sleep
  11. - "86400"
  12. volumeMounts:
  13. - name: mysql-cred
  14. mountPath: "/projected-volume"
  15. readOnly: true
  16. volumes:
  17. - name: mysql-cred
  18. projected:
  19. sources:
  20. - secret:
  21. name: user
  22. - secret:
  23. name: pass

验证注入效果

  1. # kubectl exec -it test-project-volume -- /bin/sh
  2. / # cat /projected-volume/user
  3. YWRtaW4=
  4. / # cat /projected-volume/pass
  5. MTIzNDU2

Downward API

https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/#the-downward-api
http://docs.kubernetes.org.cn/830.html#Downward_API
通过环境变量向容器暴露 Pod 信息,让 Pod 里的容器能够直接获取到这个 Pod API对象本身的信息
支持字段

  1. 1. 使用 fieldRef 可以声明使用:
  2. spec.nodeName - 宿主机名字
  3. status.hostIP - 宿主机 IP
  4. metadata.name - Pod 的名字
  5. metadata.namespace - Pod Namespace
  6. status.podIP - Pod IP
  7. spec.serviceAccountName - Pod Service Account 的名字
  8. metadata.uid - Pod UID
  9. metadata.labels['<KEY>'] - 指定 <KEY> Label
  10. metadata.annotations['<KEY>'] - 指定 <KEY> Annotation
  11. metadata.labels - Pod 的所有 Label
  12. metadata.annotations - Pod 的所有 Annotation
  13. 2. 使用 resourceFieldRef 可以声明使用:
  14. 容器的 CPU limit
  15. 容器的 CPU request
  16. 容器的 memory limit
  17. 容器的 memory request

ConfigMap

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
https://www.kubernetes.org.cn/configmap
保存不需要加密的、应用所需的配置信息,用法和secret一致

Pod Preset

https://www.kubernetes.org.cn/podpreset
http://docs.kubernetes.org.cn/789.html
Pod Preset是一种API资源,用来在创建pod时向其注入运行时需要的额外信息,如环境变量、存储卷等,通过使用label selector确定为pod应用那些Presets。
Preset允许用户创建具有通用性的模板而无需显式提供pod运行时才需要的信息,
允许模板的创建者只需提供pod运行时需要的信息而无需关注pod的实现细节。
定义preset设置时区

  1. # cat timezonePreset.yaml
  2. apiVersion: settings.k8s.io/v1alpha1
  3. kind: PodPreset
  4. metadata:
  5. name: timezone-init
  6. spec:
  7. selector: #此段必选设置,可以为空表示应用所有pod
  8. matchLabels:
  9. env:
  10. - name: TZ
  11. value: Asia/Shanghai

报错 error: unable to recognize “timezonePreset.yaml”: no matches for kind “PodPreset” in version “settings.k8s.io/v1alpha1” 则需编辑/etc/kubernetes/manifests/kube-apiserver.yaml在spec/containers/command段添加以下两段配置,保存后kubelet会自动重启kube-apiserver组件

  1. - --enable-admission-plugins=NodeRestriction,PodPreset
  2. - --runtime-config=settings.k8s.io/v1alpha1=true

再次查看api-version并创建即可成功

  1. # kubectl api-versions | grep settings.k8s.io
  2. settings.k8s.io/v1alpha1
  3. # kubectl apply -f timezonePreset.yaml
  4. podpreset.settings.k8s.io/timezone-init created
  5. # kubectl get podpresets
  6. NAME CREATED AT
  7. timezone-init 2019-09-11T12:10:01Z

定义pod的yaml文件

  1. # cat busybox.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: timezone-test
  6. spec:
  7. containers:
  8. - name: minial
  9. image: busybox
  10. 应用后查看一下这个 Pod API 对象多了新添加的时区设置
  11. # kubectl apply -f busybox.yaml
  12. pod/timezone-test created
  13. # kubectl get pod timezone-test -o yaml
  14. apiVersion: v1
  15. kind: Pod
  16. metadata:
  17. annotations:
  18. kubectl.kubernetes.io/last-applied-configuration: |
  19. {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"timezone-test","namespace":"default"},"spec":{"containers":[{"image":"busybox","name":"minial"}]}}
  20. podpreset.admission.kubernetes.io/podpreset-timezone-init: "6946675"
  21. creationTimestamp: "2019-09-11T12:19:17Z"
  22. name: timezone-test
  23. namespace: default
  24. resourceVersion: "6948419"
  25. selfLink: /api/v1/namespaces/default/pods/timezone-test
  26. uid: 86679227-6bf6-4d76-a2e3-c926593819d4
  27. spec:
  28. containers:
  29. - env:
  30. - name: TZ
  31. value: Asia/Shanghai
  32. image: busybox
  33. imagePullPolicy: Always
  34. name: minial

Kubernetes为Preset提供了一个允许控制器(admission controller),当创建创建pod的请求到达时,通过这个允入控制器将label selector选中的Preset应用到pod中,具体流程如下:

  1. 检索系统中所有可用的Presets。
  2. 检查所有Preset的label selector是否与当前pod的标签匹配。
  3. 尝试将匹配Preset中的各种资源合并进正在创建的pod。
  4. 如果发生错误,为pod抛出合并Preset失败的异常事件,然后在不合并Preset所提供资源的情况下创建pod(合并失败并没有阻挡pod的创建)。
  5. 如果合并成功,向合并后的结果spec加入到pod的注解中,表示pod被Preset修改了,注册格式如下:
  6. podpreset.admission.kubernetes.io/podpreset-: “”
  7. 每个pod可以被0到多个Preset匹配,每个Preset可以应用到0到多个pod。当Preset被应用到pod时,kubernetes会修改pod的spec。当注入Env、EnvFrom、VolumeMounts时,kubernetes会修改pod中除init container以外的其它所有container的spec,当注入volume时,修改pod的spec。

    健康检查和恢复机制

    可以为Pod里的容器定义一个健康检查的探针(Probe),kubelet会根据这个Probe的返回值判断容器的状态,而不是以docker是否在运行来做判断依据—生产环境检查健康存活的手段
    demo—exec
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. labels:
    5. test: liveness
    6. name: test-liveness-exec
    7. spec:
    8. containers:
    9. - name: liveness
    10. image: busybox
    11. args:
    12. - /bin/sh
    13. - -c
    14. - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    15. livenessProbe: (健康检查)
    16. exec:
    17. command:
    18. - cat
    19. - /tmp/healthy
    20. initialDelaySeconds: 5 (容器启动后5S执行)
    21. periodSeconds: 5 (每5S执行一次)
    demo—http
    1. ...
    2. livenessProbe:
    3. httpGet:
    4. path: /healthz
    5. port: 8080
    6. httpHeaders:
    7. - name: X-Custom-Header
    8. value: Awesome
    9. initialDelaySeconds: 3
    10. periodSeconds: 3
    demo—tcp
    1. ...
    2. livenessProbe:
    3. tcpSocket:
    4. port: 8080
    5. initialDelaySeconds: 15
    6. periodSeconds: 20
    Pod恢复机制,也叫restartPolicy,pod spec部分的标准字段,默认为Always,Pod 的恢复过程,永远都是发生在当前节点上,除非pod.spec.node发生了变化,否则就算主机宕机也不会主动迁移到其他节点上去。
    Kubernetes 中并没有 Docker 的 Stop 语义。所以虽然是 Restart(重启),但实际却是重新创建容器—create
    pod.spec.restartPolicy
  • Always:在任何情况下,只要容器不在运行状态,就自动重启
  • OnFailure: 只在容器 异常时才自动重启容器;
  • Never: 从来不重启容器