三、ConfigMap
ConfigMap 与 Secret 类似,区别就是 ConfigMap 保存的是不需要加密的、应用所需的配置文件信息。
ConfigMap 的用法几乎与 Secret 完全相同,可以使用 kubectl create configmap
从文件或者目录创建 ConfigMap,也可以直接编写 ConfigMap 对象的 YAML 文件。
[root@master01 yaml]# cat test-db.text database.host=localhost database.port=3306 database.username=admin database.password=secret # 从 test-db.text 文件中,创建 configmap。 [root@master01 yaml]# kubectl create configmap my-config --from-file=test-db.text configmap/my-config created
查看 configmap 中 data 数据信息,可以看到是和 test-db.text 配置文件中一致的,后期也是可以通过环境变量和 Voluem 卷的方式使用(同上述 Secret)。
[root@master01 yaml]# kubectl get configmap my-config -o yaml
例:
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: my-image env: - name: DATABASE_HOST valueFrom: configMapKeyRef: name: my-config key: database.host - name: DATABASE_PORT valueFrom: configMapKeyRef: name: my-config key: database.port - name: DATABASE_USERNAME valueFrom: configMapKeyRef: name: my-config key: database.username - name: DATABASE_PASSWORD valueFrom: configMapKeyRef: name: my-config key: database.password
四、Downward API
Downward API 是一种特性,它允许容器在运行时获取关于自身和它所在 Pod 的一些元数据信息。这些信息可以作为环境变量或卷挂载提供给容器使用。
如果按照 Downward(下载)这个单词意思理解就是: 将 Pod 或容器自身的元数据信息下载到是运行状态的容器中使用。
Downward API 提供了以下作用:
总的来说,Downward API 提供了一种在容器运行时获取 Pod 和容器自身元数据的机制,使容器能够动态获取并使用这些信息。这对于编写灵活且适应性强的应用程序非常有用,并能够在 Kubernetes 环境中提供更多的自动化和配置选项。
可用字段
只有部分 Kubernetes API 字段可以通过 Downward API 使用。
- fieldRef:传递 Pod 级字段的信息
- resourceFieldRef:传递 Container 级字段的信息
1.可通过 fieldRef
获得的信息
metadata.name
:Pod 的名称metadata.namespace
:Pod 的命名空间metadata.uid
:Pod 的唯一 ID- …
2.可通过 resourceFieldRef
获得的信息
limits.cpu
:容器的 CPU 限制值requests.cpu
:容器的 CPU 请求值requests.memory
:容器的内存请求值limits.memory
:容器的内存限制值- …
Kubernetes 官网:更多可用字段信息
举个例子:
我们定义了一个 Pod 名为 projected-buxybox,并创建了一个名为 app 的容器。我们使用了一个 Projected Volume,并将其挂载到了 /etc/config 目录下。 并使用 fieldRef 来获取 Pod 的元数据信息,使用 resourceFieldRef 来获取容器的元数据信息。
items.path
:定义元数据信息的目录是什么。fieldRef.fieldPath
:定义 Pod 元数据信息的值是什么。resourceFieldRef.resource
:定义 容器 元数据信息的值是什么。
apiVersion: v1 kind: Pod metadata: name: projected-buxybox spec: containers: - name: app image: busybox imagePullPolicy: IfNotPresent args: - sleep - "3600" resources: limits: cpu: "2" requests: cpu: "1" volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume projected: sources: - downwardAPI: items: - path: "pod_name" fieldRef: fieldPath: metadata.name - path: "pod_namespace" fieldRef: fieldPath: metadata.namespace - path: "cpu_limits" resourceFieldRef: containerName: app resource: limits.cpu - path: "cpu_request" resourceFieldRef: containerName: app resource: requests.cpu
验证:部署 Pod ,并查看 /etc/config 目录下,获取的值是否正确。
[root@master01 yaml]# kubectl apply -f projected-buxybox-pod.yaml [root@master01 yaml]# kubectl get -f projected-buxybox-pod.yaml NAME READY STATUS RESTARTS AGE projected-buxybox 1/1 Running 0 3m11s [root@master01 yaml]# kubectl exec -it projected-buxybox -- /bin/sh / # ls /etc/config/ cpu_limits cpu_request pod_name pod_namespace / # cat /etc/config/cpu_limits 2 / # cat /etc/config/cpu_request 1 / # cat /etc/config/pod_name projected-buxybox / # cat /etc/config/pod_namespace default
小结
注意:Downward API 能够获取到的信息,一定是 Pod 里的容器进程启动之前就能够确定下来的信息。而如果你想要获取 Pod 容器运行后才会出现的信息,比如,容器进程的 PID,那就肯定不能使用 Downward API 了,而应该考虑在 Pod 里定义一个 sidecar 容器。
Secret、ConfigMap,以及 Downward API 这三种 Projected Volume 定义的信息,大多还可以通过环境变量的方式出现在容器里。但是,通过环境变量获取这些信息的方式,不具备自动更新的能力。所以,一般情况下,我都建议你使用 Volume 文件的方式获取这些信息。
五、ServiceAccountToken
如果我有一个 Pod,而且在 Pod 中安装 Kubernetes 的 Clinet,想实现可以从容器里直接访问并且操作这个 Kubernetes 的 API ?这种方式是可行的,不过,你首先要解决 API Server 的授权问题,这就需要 ServiceAccount 服务对象了。
1.Service Account 是什么?
- Service Account(服务账号)是 Kubernetes 中用于身份验证和授权的实体,进行权限分配的对象。它是为 Pod 提供访问 Kubernetes API 的身份凭据。每个 Service Account 都有一个唯一的名称和对应的身份令牌(Token)。
- Service Account 可以与 Pod 关联,使 Pod 具有与 Kubernetes API 进行交互的权限。它允许 Pod 在运行时进行身份验证,并根据其配置的权限来执行操作,例如创建、更新或删除资源。
比如,Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作权限。
2.ServiceAccountToken 是什么?
像上述这样的权限分配操作,实际上是通过一种它所绑定的一个 ServiceAccountToken。任何运行在 Kubernetes 集群上的应用,都必须使用这个 ServiceAccountToken 里保存的授权信息,也就是 Token,才能访问 kube-apiserver。
另外,为了方便使用,Kubernetes 已经为你提供了一个默认“服务账户”(default Service Account)。如图:
并且,任何一个运行在 Kubernetes 里的 Pod,都可以直接使用这个默认的 Service Account,而无需显示地声明挂载它,因为是默认自动挂载(可以设置不挂载,默认挂载)靠 Projected Volume 机制实现。
你可以查看任意一个运行中的 Pod,你会发现一个 类型为 Projected 并且包含来自多个源的注入数据的卷(Service Account 的身份令牌),然后自动挂载在每个容器的一个固定目录上 /var/run/secrets/kubernetes.io/serviceaccount
,容器可以通过该路径访问令牌,并将其用于与 Kubernetes API 的安全通信。
这里提供了两种查看方式,如下图:
kubectl describe pod mysql-pod
下图我们可以看到,这个 Projected 包含来自多个源的注入数据的卷,使用了 ServiceAccountToken、ConfigMap、DownwardAPI。
kubectl get pod -o yaml mysql-pod
所以 Pod 中的容器应用,就可以直接使用这个目录下的授权信息和文件与 kube-apiserver 访问, Projected 目录下的内容,如图所示:
这种把 Kubernetes 客户端以容器的方式运行在集群里,然后使用 default Service Account 自动授权的方式,被称作 “InClusterConfig”(内部集群配置),也是我最推荐的进行 Kubernetes API 编程的授权方式。
除了默认的 ServiceAccount 还可以自定义 ServiceAccount 来对应不同的权限设置。这样 Pod 在使用这个 Service Account 对应的 ServiceAccountToken 时权限就更加灵活。
总结
今天,介绍了 Pod 的 Volume 的 Projected 服务对象。
你还应该认真体会一下 Kubernetes “一切皆对象” 的设计思想:比如,应用是 Pod 对象,应用的配置是 ConfigMap 对象,应用要访问的密码则是 Secret 对象。
最后:技术交流、博客互助,点击下方或主页推广加入哦!!