K8s之Projected Volume
阅读原文时间:2023年07月15日阅读:1
  • Secret:帮你把Pod想要访问的加密数据,存放到Etcd中,然后,通过在Pod容器里挂载Volume的方式,访问这些Secret里保存的信息,

      Secret典形场景,比如存放数据库的Credential信息:

apiVersion: v1
kind: Pod
metadata:
name: test-projected-volume
spec:
containers:

  • name: test-secret-volume
    image: busybox
    args:

    • sleep
    • "86400"
      volumeMounts:
    • name: mysql-cred
      mountPath: "/projected-volume"
      readOnly: true
      volumes:
  • name: mysql-cred
    projected:
    sources:

    • secret:
      name: user #用户名

    • secret:
      name: pass #密码

        这里用到的数据库的用户名和密码,正是以Secret对象的方式交给Kubernetes保存的,操作指令如下:

$ cat ./username.txt
admin
$ cat ./password.txt
defaUlt

$ kubectl create secret generic user --from-file=./username.txt
$ kubectl create secret generic pass --from-file=./password.txt

  接下来创建Pod, 然后进入容器验证:

#创建
$ kubectl create -f test-projected-volume.yaml

#验证

$ kubectl exec -it test-projected-volume -- /bin/sh
$ ls /projected-volume/
user
pass
$ cat /projected-volume/user
admin
$ cat /projected-volume/pass
defaUlt

  从上面的结果中可以看出,保存在Etcd中的用户名和密码信息,以及以文件的形式出现在了容器的Volume目录里。

  • ConfigMap与Secret类似,区别在于ConfigMap保存的是不需要加密的应用的配置信息等。和Secret用法几乎相同;

      比如一个Java应用所需要的配置文件(.properties文件),就可以通过下面的方式保存在ConfigMap中:

# .properties文件的内容
$ cat example/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice

从.properties文件创建ConfigMap

$ kubectl create configmap ui-config --from-file=example/ui.properties

查看这个ConfigMap里保存的信息(data)

$ kubectl get configmaps ui-config -o yaml
apiVersion: v1
data:
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
name: ui-config

  • Downward API,它的作用是:让 Pod 里的容器能够直接获取到这个 Pod API 对象本身的信息

      例子如下:

apiVersion: v1
kind: Pod
metadata:
name: test-downwardapi-volume
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
projected:
sources:
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels

  在这个 Pod 的 YAML 文件中,我定义了一个简单的容器,声明了一个 projected 类型的 Volume。只不过这次 Volume 的数据来源,变成了 Downward API。而这个 Downward API Volume,则声明了要暴露 Pod 的 metadata.labels 信息给容器。

  通过这样的声明方式,当前 Pod 的 Labels 字段的值,就会被 Kubernetes 自动挂载成为容器里的 /etc/podinfo/labels 文件。而这个容器的启动命令,则是不断打印出 /etc/podinfo/labels 里的内容。

所以,当我创建了这个 Pod 之后,就可以通过 kubectl logs 指令,查看到这些 Labels 字段被打印出来,如下所示:

$ kubectl create -f dapi-volume.yaml
$ kubectl logs test-downwardapi-volume
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"

目前,Downward API 支持的字段已经非常丰富了,比如:

1. 使用fieldRef可以声明使用:
spec.nodeName - 宿主机名字
status.hostIP - 宿主机IP
metadata.name - Pod的名字
metadata.namespace - Pod的Namespace
status.podIP - Pod的IP
spec.serviceAccountName - Pod的Service Account的名字
metadata.uid - Pod的UID
metadata.labels[''] - 指定的Label值
metadata.annotations[''] - 指定的Annotation值
metadata.labels - Pod的所有Label
metadata.annotations - Pod的所有Annotation

  1. 使用resourceFieldRef可以声明使用:
    容器的CPU limit
    容器的CPU request
    容器的memory limit
    容器的memory request

      Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”,它是 Kubernetes 进行权限分配的对象。比如,Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作的权限。

      像这样的 Service Account 的授权信息和文件,实际上保存在它所绑定的一个特殊的 Secret 对象里的。这个特殊的 Secret 对象,就叫作 ServiceAccountToken。任何运行在 Kubernetes 集群上的应用,都必须使用这个 ServiceAccountToken 里保存的授权信息,也就是 Token,才可以合法地访问 API Server

      所以说,Kubernetes 项目的 Projected Volume 其实只有三种,因为第四种 ServiceAccountToken,只是一种特殊的 Secret 而已。

      另外,为了方便使用,Kubernetes 已经为你提供了一个的默认“服务账户”(default Service Account)。并且,任何一个运行在 Kubernetes 里的 Pod,都可以直接使用这个默认的 Service Account,而无需显示地声明挂载它。