上一篇文章中,我们详细介绍了 Kubernetes 中的 Pod:
在实际的线上场景中,我们并不能在配置 Pod 的 yaml 里描述所有需要的信息,因为总有一些信息或因为其保密性,或因为其动态变化性,是不能够放在配置文件里的,那么,这类信息要怎么加入到我们的 Pod 配置体系中呢?
这就需要一种特殊的 Volume -- 投射数据卷,Projected Volume。本文我们就来详细介绍投射数据卷的用法。
之所以被称作“投射数据卷”,是因为这些数据是提前定义好,或者动态拉取,然后投射进 Kubernetes 的容器中的,它们有三种:
需要注意的是:
下面,我们来一一介绍。
Secret Volume 的作用是帮你把想要访问的加密数据存放到 etcd 中,这样,Pod 中的容器就可以通过挂载相应 Volume 的方式访问到这些加密信息了。
有两种方式可以创建 Secret Volume:
首先,我们需要两个文件,分别用来存储用户名和密码:
$ echo "admin" > username.txt $ echo "UjtLdUtzWOnfcIh8" > password.txt
然后,执行 kubectl create 命令就可以完成 Secret Volume 的创建:
$ kubectl create secret generic user --from-file=./username.txt $ kubectl create secret generic pass --from-file=./password.txt
编写配置文件:
apiVersion: v1
kind: Secret
metadata:
name: secret-volume
type: Opaque
data:
user: YWRtaW4=
pass: VWp0TGRVdHpXT25mY0loOAo=
同样,通过 kubectl create 命令,就可以完成 Secret Volume 的创建了:
$ kubectl create -f secret-volume.yaml
通过 kubectl get 命令可以进行 secret 的查询:
$ kubectl get secretes
事实上,这样查询出来的明文结果是具有很大的风险的,在真实的线上环境中,我们还需要开启 Secret 加密插件,进一步保障数据的保密性。
Secret Volume 虽然是一种用来保存加密信息的特殊的 Volume,但他的使用和其他 Volume 并没有明显区别。
例如,下面是一个 Pod 的定义:
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
我们通过 exec 命令进入到这个容器,通过查看挂载的目录就可以看到相应的内容了:
$ kubectl exec -it test-projected-volume -- /bin/sh $ cat /projected-volume/user root
ConfigMap 与 Secret 非常类似,也是通过用键值对的方式来保存数据的 Volume,区别在于 ConfigMap 并非用来保存加密数据的,他是用来保存配置信息的。
与 Secret 一样,ConfigMap 也有两种配置方法:
首先,我们先定义 properties 文件:
color.good=purple
color.bad=yellow
allow.textmod=true
执行 kubectl create 命令即可完成 ConfigMap 的创建:
$ kubectl create configmap ui-config --from-file=ui.properties
编写配置文件:
apiVersion: v1
kind: ConfigMap
metadata:
name: ui-config
data:
color.good: purple
color.bad: yellow
执行 kubectl create 命令即可完成 ConfigMap 的创建:
$ kubectl create -f config.yaml
通过 kubectl describe 命令就可以实现 ConfigMap 的查询了:
$ kubectl describe configmap ui-config
接下来我们来介绍两种可以在 Pod 中使用 ConfigMap 的方式:
除此以外,还可以编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap,这种方式后续再进行介绍,敬请期待。
# test-pod-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod-configmap
spec:
containers:
- name: test-busybox
image: busybox
imagePullPolicy: IfNotPresent
args:
- sleep
- "86400"
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: ui-config
key: color.good
- name: KEY2
valueFrom:
configMapKeyRef:
name: ui-config
key: color.bad
通常,我们会想要用 ConfigMap 来设置容器启动时的命令行参数,尽管这是 Kubernetes 不支持的,但它支持通过环境变量来配置启动参数,我们就可以如法炮制了:
# test-pod-configmap-cmd
apiVersion: v1
kind: Pod
metadata:
name: test-pod-configmap-cmd
spec:
containers:
- name: test-busybox
image: busybox
imagePullPolicy: IfNotPresent
command: [ "/bin/sh","-c","echo $(KEY1) $(KEY2)"]
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: ui-config
key: color.good
- name: KEY2
valueFrom:
configMapKeyRef:
name: ui-config
key: color.bad
restartPolicy: Never
同样,我们也可以将 ConfigMap 作为普通的 volume 挂载到容器中:
# test-pod-projected-configmap-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod-projected-configmap-volume
spec:
containers:
- name: test-pod-busybox
image: busybox
imagePullPolicy: IfNotPresent
args:
- sleep
- "86400"
volumeMounts:
- name: config-volume
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: config-volume
projected:
sources:
- configMap:
name: ui-config
在我们配置一个 Pod 时,我们把许许多多的信息编写在了配置文件上,但有时候,我们需要在容器中获取当前 Pod 的这些配置信息,我们又该怎么做呢?
Kubernetes 提供了 Downward 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 的定义中,我们定义了一个 downwardAPI 类型的 projected volume 并且挂载到了容器中,而这个容器的功能,就是循环打印挂载的 projected volume 中的文件内容。
于是我们看到打印出了我们为这个 pod 定义的 labels:
$ kubectl logs test-downwardapi-volume cluster="test-cluster1" rack="rack-22" zone="us-est-coast"
目前,Downward API 支持的字段已经非常丰富了,他分为两个部分:
上一篇文章中,我们详细介绍了 Kubernetes 中的 Pod:
<a id="10183740"></a>
在实际的线上场景中,我们并不能在配置 Pod 的 yaml 里描述所有需要的信息,因为总有一些信息或因为其保密性,或因为其动态变化性,是不能够放在配置文件里的,那么,这类信息要怎么加入到我们的 Pod 配置体系中呢?
这就需要一种特殊的 Volume -- 投射数据卷,Projected Volume。本文我们就来详细介绍投射数据卷的用法。
之所以被称作“投射数据卷”,是因为这些数据是提前定义好,或者动态拉取,然后投射进 Kubernetes 的容器中的,它们有四种:
需要注意的是,Pod 只能使用同一个命名空间中的 Projected Volume。
下面,我们来一一介绍。
Secret Volume 的作用是帮你把想要访问的加密数据存放到 etcd 中,这样,Pod 中的容器就可以通过挂载相应 Volume 的方式访问到这些加密信息了。
有两种方式可以创建 Secret Volume:
首先,我们需要两个文件,分别用来存储用户名和密码:
$ echo "admin" > username.txt $ echo "UjtLdUtzWOnfcIh8" > password.txt
然后,执行 kubectl create 命令就可以完成 Secret Volume 的创建:
$ kubectl create secret generic user --from-file=./username.txt $ kubectl create secret generic pass --from-file=./password.txt
编写配置文件:
apiVersion: v1
kind: Secret
metadata:
name: secret-volume
type: Opaque
data:
user: YWRtaW4=
pass: VWp0TGRVdHpXT25mY0loOAo=
同样,通过 kubectl create 命令,就可以完成 Secret Volume 的创建了:
$ kubectl create -f secret-volume.yaml
通过 kubectl get 命令可以进行 secret 的查询:
$ kubectl get secretes
事实上,这样查询出来的明文结果是具有很大的风险的,在真实的线上环境中,我们还需要开启 Secret 加密插件,进一步保障数据的保密性。
Secret Volume 虽然是一种用来保存加密信息的特殊的 Volume,但他的使用和其他 Volume 并没有明显区别。
例如,下面是一个 Pod 的定义:
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
我们通过 exec 命令进入到这个容器,通过查看挂载的目录就可以看到相应的内容了:
$ kubectl exec -it test-projected-volume -- /bin/sh $ cat /projected-volume/user root
ConfigMap 与 Secret 非常类似,也是通过用键值对的方式来保存数据的 Volume,区别在于 ConfigMap 并非用来保存加密数据的,他是用来保存配置信息的。
与 Secret 一样,ConfigMap 也有两种配置方法:
首先,我们先定义 properties 文件:
color.good=purple
color.bad=yellow
allow.textmod=true
执行 kubectl create 命令即可完成 ConfigMap 的创建:
$ kubectl create configmap ui-config --from-file=ui.properties
编写配置文件:
apiVersion: v1
kind: ConfigMap
metadata:
name: ui-config
data:
color.good: purple
color.bad: yellow
执行 kubectl create 命令即可完成 ConfigMap 的创建:
$ kubectl create -f config.yaml
通过 kubectl describe 命令就可以实现 ConfigMap 的查询了:
$ kubectl describe configmap ui-config
接下来我们来介绍两种可以在 Pod 中使用 ConfigMap 的方式:
除此以外,还可以编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap,这种方式后续再进行介绍,敬请期待。
# test-pod-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod-configmap
spec:
containers:
- name: test-busybox
image: busybox
imagePullPolicy: IfNotPresent
args:
- sleep
- "86400"
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: ui-config
key: color.good
- name: KEY2
valueFrom:
configMapKeyRef:
name: ui-config
key: color.bad
通常,我们会想要用 ConfigMap 来设置容器启动时的命令行参数,尽管这是 Kubernetes 不支持的,但它支持通过环境变量来配置启动参数,我们就可以如法炮制了:
# test-pod-configmap-cmd
apiVersion: v1
kind: Pod
metadata:
name: test-pod-configmap-cmd
spec:
containers:
- name: test-busybox
image: busybox
imagePullPolicy: IfNotPresent
command: [ "/bin/sh","-c","echo $(KEY1) $(KEY2)"]
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: ui-config
key: color.good
- name: KEY2
valueFrom:
configMapKeyRef:
name: ui-config
key: color.bad
restartPolicy: Never
同样,我们也可以将 ConfigMap 作为普通的 volume 挂载到容器中:
# test-pod-projected-configmap-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod-projected-configmap-volume
spec:
containers:
- name: test-pod-busybox
image: busybox
imagePullPolicy: IfNotPresent
args:
- sleep
- "86400"
volumeMounts:
- name: config-volume
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: config-volume
projected:
sources:
- configMap:
name: ui-config
在我们配置一个 Pod 时,我们把许许多多的信息编写在了配置文件上,但有时候,我们需要在容器中获取当前 Pod 的这些配置信息,我们又该怎么做呢?
Kubernetes 提供了 Downward 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 的定义中,我们定义了一个 downwardAPI 类型的 projected volume 并且挂载到了容器中,而这个容器的功能,就是循环打印挂载的 projected volume 中的文件内容。
于是我们看到打印出了我们为这个 pod 定义的 labels:
$ kubectl logs test-downwardapi-volume cluster="test-cluster1" rack="rack-22" zone="us-est-coast"
目前,Downward API 支持的字段已经非常丰富了,他分为两个部分:
例如:
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox:1.24
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never