前言
在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
data.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
- 配置文件
data.conf: |
property.1=value-1
property.2=value-2
property.3=value-3
data.conf 是文件名, 管道符 | 下面是文件内容. ✨需要注意的是, data.conf 内容依然要遵循 yaml 的缩进规则
命令式写法
kubectl create cm cm-demo --from-file=data.conf
使用
- 方法1
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox
spec:
replicas: 1
selector:
matchLabels:
run: busybox
template:
metadata:
labels:
run: busybox
spec:
containers:
- name: busybox
image: busybox
command: ["/bin/sh", "-c", "echo ${DATA1} ${DATA2}"]
env:
- name: DATA1
valueFrom:
configMapKeyRef:
name: cm-demo # 注意,这是ConfigMap对象名
key: data.1 # 这是ConfigMap里的key
- name: DATA2
valueFrom:
configMapKeyRef:
name: cm-demo
key: data.2
volumeMounts:
- name: cm-demo-vol
mountPath: "/etc" # cm 对象获取的 key 内容文件的根路径。
readOnly: true
volumes:
- name: cm-demo-vol
configMap:
name: cm-demo
items: # items 就是获取 cm 对象下的所有 key
- key: "data.conf" # 获取名叫 data.conf 的 key
path: "data.conf" # 将 data.conf 这个 key 的内容写入到 /etc/data.conf 这个路径文件里
通过上面的写法,可以在容器内找到 /etc/data.conf 。
✨当你更新 cm 对象的时候,cm 对象会把更新内容同步到容器中。更新速度并不是立马就能响应,也是轮询更新。
💥注意:这种方式会清空 mountPath 路径。因为挂载点是目录。
- 方法2
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox
spec:
replicas: 1
selector:
matchLabels:
run: busybox
template:
metadata:
labels:
run: busybox
spec:
containers:
- name: busybox
image: busybox
command: ["/bin/sh", "-c", "echo ${DATA1} ${DATA2}"]
env:
- name: DATA1
valueFrom:
configMapKeyRef:
name: cm-demo # 注意,这是ConfigMap对象名
key: data.1 # 这是ConfigMap里的key
- name: DATA2
valueFrom:
configMapKeyRef:
name: cm-demo
key: data.2
volumeMounts:
- name: cm-demo-vol
subPath: data.conf
mountPath: "/etc/data.conf"
readOnly: true
volumes:
- name: cm-demo-vol
configMap:
name: cm-demo
✨这种通过 subPath 获取 cm 的 key data.conf,并针对性的挂载到指定文件 /etc/data.conf 。可以避免挂载点是目录的时候被覆盖。
💥这种方式,cm对象修改无法同步到容器中。
-
方法3
通过在 spec.containers.env 中定义. 例子中, DATA1 是环境变量名, DATA1的值通过valueFrom定义.最终,你可以在容器中使用环境变量DATA1和DATA2
通过在 spec.containers.envFrom 中定义一组环境变量,这种方式要求 cm 里的 key 必须都符合 C_IDENTIFIER 规范.
env:
- name: DATA1
valueFrom:
configMapKeyRef:
name: cm-demo # 注意,这是ConfigMap对象名
key: data.1 # 这是ConfigMap里的key
- name: DATA2
valueFrom:
configMapKeyRef:
name: cm-demo
key: data.2
envFrom:
- configMapRef:
name: cm-envs
- 💥这种方式下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
✨secret 也支持 immutable: true ,即不可变的 secret。
- 使用2
通过在 spec.containers.envFrom.secretRef 中定义一组环境变量,这种方式要求 secret 里的 key 必须都符合 C_IDENTIFIER 规范.
kubectl explain deployment.spec.template.spec.containers.envFrom.secretRef
immutable: true
有以下好处
- 避免对象被意外修改
- 降低 kube-apiserver 的压力,因为不可变,所以 kubelet 就无需 watch kube-apiserver.
临时卷
- 通过在 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的信息。
例子1:
apiVersion: apps/v1
kind: Deployment
metadata:
name: oom-sims
namespace: default
labels:
app: oom-sims
spec:
replicas: 1
selector:
matchLabels:
app: oom-sims
template:
metadata:
labels:
app: oom-sims
spec:
volumes:
- name: dumplog
emptyDir: {}
containers:
- name: oom-sims-container
image: cloudbeer/oom-sims:1.0
command: ["/bin/sh", "-c", "java -Xms256m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumplog/${RANDOM}.dump -jar /app/oom-sims-1.0-SNAPSHOT.jar 1000"]
resources:
requests:
memory: "2Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "500m"
volumeMounts:
- name: dumplog
mountPath: /dumplog
- name: dumplogupload
image: aaa103439/dumplogupload:latest
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: OSS_ENDPOINT
value: "oss-cn-beijing-internal.aliyuncs.com"
- name: OSS_ACCESSID
value: "" #
- name: OSS_ACCESSSECRET
value: ""
- name: OSS_BUCKET
value: "juaiit"
- name: OSS_DUMPER_ROOT
value: "logs/dump/$(NAMESPACE)"
- name: APP_NAME # 应用名称,这个名称会附加在文件名后面
value: $(POD_NAME)_$(NODE_IP)
- name: DUMPER_ROOT # 会监视这个文件夹下面的文件,-XX:HeapDumpPath = DUMPER_ROOT/xxx.DUMPER_SUFFIX
value: "/dumplog"
- name: DUMPER_SUFFIX # dump 文件后缀
value: ".dump"
volumeMounts:
- name: dumplog
mountPath: /dumplog
例子2: 将资源限制数据挂载到容器/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 临时卷内容直接配置里写入