前言
在Pod中应用配置和密码,我们可以创建配置对象ConfigMap和密码对象Secret。
而这两种对象的使用有多种方式:
- 存储卷方式
- 环境变量方式
- 命令行方式
非加密ConfigMap
https://kubernetes.io/docs/concepts/configuration/configmap/
ConfigMap 常用在两种情况中. 第一种是提供环境变量.第二种是提供配置文件
写法
kind: ConfigMap
apiVersion: v1
metadata:
name: cm-demo
namespace: default
data:
data.1: hello
data.2: world
nginx.conf: |
property.1=value-1
property.2=value-2
property.3=value-3
immutable: true
immutable: true 表示这是一个不可变更的CM,一旦CM创建,则这个属性不可更改。意味着如果你要更改,则需要删除CM和调用CM的Pod。
上述例子中, 包含两种写法
- 环境变量
data.1: hello
data.2: world
- 配置文件
nginx.conf: |
property.1=value-1
property.2=value-2
property.3=value-3
nginx.config 是文件名, 管道符 | 下面是文件内容.
需要注意的是, 内容依然要遵循 yaml 的缩进规则
使用
Pod调用示例
spec:
containers:
- name: nginx
image: nginx
command: ["/bin/sh", "-c", "echo ${DATA.1} ${DATA.2}"]
ports:
- containerPort: 80
env:
- name: DATA1
valueFrom:
configMapKeyRef:
name: cm-demo # 这是ConfigMap名,而不是configMap临时卷.
key: data.1 # 这是ConfigMap里的key
- name: DATA2
valueFrom:
configMapKeyRef:
name: cm-demo
key: data.2
volumeMounts:
- name: cm-demo-vc
subPath: nginx.conf
mountPath: /etc/nginx/nginx.conf
volumes:
- name: cm-demo-vc
configMap:
name: cm-demo
上述subPath方式,虽然可以挂载一个单一配置对象到具体的文件,但是这种方式配置对象更新不会同步到容器中。
仅部分key同步到挂载点
volumeMounts:
- name: config
mountPath: "/config" # ConfigMap对象key的文件根路径。
readOnly: true
volumes:
- name: config
configMap:
name: game-demo
# 指定一个数组,仅将数组里列出的ConfigMap对象key创建为文件。
items:
- key: "game.properties" # ConfigMap对象key
path: "game.properties" # 文件名
- key: "user-interface.properties"
path: "user-interface.properties"
临时卷
- 通过在 spec.volumes.configMap 中定义临时卷 cm-demo-vc。
- 然后通过 spec.containers.volumeMounts 挂载临时卷。
- 这种方式下ConfigMap更新后,pod内挂载的也会同时更新。(更新速度并不是立马就能响应,也是轮询更新),而且仅限于没有使用subPath的方式。
💢需要注意的是,挂载点需要防止容器目录里原有的文件被清除。
环境变量
- 通过在 spec.containers.env 中定义. 例子中, DATA1 是环境变量名, DATA1的值通过valueFrom定义.最终,你可以在容器中使用环境变量DATA1和DATA2
- 这种方式下ConfigMap更新后,环境变量不会更新。
加密Secret
https://kubernetes.io/docs/concepts/configuration/secret/
secret对象里的值需要写入加密后的.
写法
我们定义一个用户密码对,分别时username和password
secret对象要求值必须进行base64编码加密(当type为Opaque的时候).
[root@k8s00 test-yaml]# echo -n "admin" | base64
YWRtaW4=
[root@k8s00 test-yaml]# echo -n "admin321" | base64
YWRtaW4zMjE=
# 创建 secret 对象 mysecret
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: default
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
👀type
用来定义不同的类型,例如:
Opaque
普通加密字符串kubernetes.io/tls
tls证书kubernetes.io/dockerconfigjson
docker仓库账户密码kubernetes.io/service-account-token
服务账户授权token
使用
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
command:
- sleep
- "3600"
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
volumeMounts:
- name: mysecret-vol
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: mysecret-vol
secret:
secretName: mysecret
临时卷
- 通过在 spec.volumes.secret 中定义临时卷 mysecret-vol。
- 剩余用法和 spec.volumes.configMap 一样。
环境变量
- 通过在 spec.containers.env 中定义。
测试
在通过上述配置创建好资源后,我们进入pod,进行测试.
[root@k8s00 test-yaml]# kubectl exec -it mypod -- /bin/sh
===可以看到两个加密信息生成了两个软连接,并指向了隐藏文件
/ # ls -l /etc/foo
total 0
lrwxrwxrwx 1 root root 15 Sep 17 07:18 password -> ..data/password
lrwxrwxrwx 1 root root 15 Sep 17 07:18 username -> ..data/username
===环境变量
/ # echo ${SECRET_USERNAME}
admin
===文件方式
/ # cat /etc/foo/username
admin
限制
- 资源和Pod限制在同一命名空间
- 对象数据大小不能超过1MB
- 当pod引用不存在的对象时,pod无法启动
其它
-
命令方式创建
kubectl create configmap/secret
xxx 这里xxx可以用两种方式:
- –from-literal=
= 指定kv - –from-file=<文件/目录> 当为目录的时候,会递归将目录里的文件都写入对象中
- –from-literal=
-
在Pod中隐藏配置或者密码文件
你可以将
secret.data.<key>
写成secret.data.<.key>
来隐藏它.
信息提供Downward API
https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/
Downward API用来向Pod中运行的容器公开提供容器和Pod的信息。
一个简单的例子: 将资源限制数据挂载到容器/etc/podinfo
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox:1.24
command: ["sh", "-c"]
args:
- while true; do
echo -en '\n';
if [[ -e /etc/podinfo/cpu_limit ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
if [[ -e /etc/podinfo/cpu_request ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
if [[ -e /etc/podinfo/mem_limit ]]; then
echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
if [[ -e /etc/podinfo/mem_request ]]; then
echo -en '\n'; cat /etc/podinfo/mem_request; fi;
sleep 5;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
divisor: 1m
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
divisor: 1m
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
divisor: 1Mi
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
divisor: 1Mi
projected volume使用方式
kubernetes 提供了一种卷类型 projected volume。可以将多个volume挂载到一个位置上。
写法:
volumeMounts:
- name: all-in-one
mountPath: /etc/allinfo
readonly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: user
- secret:
name: pass
- configmap:
name: content
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
user, pass, content, labels, annotations 将会以文件形式存在于容器挂载点 /etc/allinfo 内。
创建Secret对象: secret: user 和 secret: pass
echo -n "admin" > ./username.txt
kubectl create secret generic user --from-file=./username.txt
echo -n "1f2d1e2e67df" > ./username.txt
kubectl create secret generic pass --from-file=./password.txt
创建 ConfigMap对象: content
echo -n "userinfo" > ./content.txt
kubectl create configmap content --from-file=./content.txt
DownwardAPI 临时卷内容直接配置里写入