k8s config和secret配置教程

简单的配置管理,可以把信息写入文件放在项目里,然后打包发布,但这样会有信息泄露的安全风险,经常会看到谁谁谁把项目上传到github,然后公司数据库/敏感密钥泄漏等。所以,现在的公司一般会自建发布平台,通过发布平台管理配置,流程:配置修改->审核->发布。了解到这背景,我们就知道config跟secret在整个软件开发过程中扮演的角色,接下来就学习如何配置config/secret并使用

当然,一般情况下,配置管理没有那么简单,要考虑多种环境如dev/test/release以及地区区分,操作需小心谨慎,一不小心就出现遗漏、错配,此外,还有多人开发时配置冲突等,这些都是开发过程中要注意的问题

Config

以下展示configMap的简单配置,必须字段apiVersion、kind、metadata、data/binaryData。data可以是key-value键值对,也可以是文件名-文件内容,数据的大小不能超过1MB,具体可以查看官网api描述文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# game-demo.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
# 1. key-value
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"

# 2. filename-content
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true

执行命令写入k8s,查看并验证配置信息

1
2
3
4
5
6
# 写入k8s
kubectl apply -f game-demo.yam
#
kubectl get cm game-demo
# 查看config数据
kubectl describe cm game-demo

有了配置信息,怎么搭配container使用?有4种使用方式可供参考

  1. 在容器命令和参数内
  2. 容器的环境变量
  3. 在只读卷里面添加一个文件,让应用来读取
  4. 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

以下启动一个pod,在启动时打印输出config信息,主要展示的是环境变量跟配置文件两种方式,也就是上面的2和3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: registry.noname.io:5000/alpine:3.20.1
command:
- /bin/sh
- "-c"
- |
echo $PLAYER_INITIAL_LIVES;
echo $UI_PROPERTIES_FILE_NAME;
ls -l /config/game.properties;
cat /config/game.properties;
ls -l /config/user-interface.properties;
cat /config/user-interface.properties;
# 方式2:configMap->环境变量
env:
# 定义环境变量
- name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的
valueFrom:
configMapKeyRef:
name: game-demo # 这个值来自 ConfigMap
key: player_initial_lives # 需要取值的键
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
# 方式3:configMap->文件
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# 你可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中
- name: config
configMap:
# ConfigMap的名字
name: game-demo
# 指定key创建为path文件
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"

执行命令

1
2
3
4
5
6
7
8
9
10
11
# 创建pod
kubectl apply -f configmap-demo-pod.yaml
# 查看configmap-demo-pod运行情况
kubectl get pod | grep configmap-demo-pod
# pod是否有其他异常
kubectl describe pod configmap-demo-pod
# 查看command输出日志
kubectl logs configmap-demo-pod
# 清理config、pod
kubectl delete -f game-demo.yaml
kubectl delete -f configmap-demo-pod.yaml

Secret

secret的应用场景想到的只有数据库密码,如果真的要跟数据库其他配置分离也挺蛋疼的,以下简单展示如何使用

secret与config非常相似,有如下相同点

  1. key/value 的形式
  2. 属于某个特定的 namespace
  3. 可以导出到环境变量
  4. 可以通过目录/文件形式挂载 (支持挂载所有 key 和部分 key)

不同点:

  1. secret 可以被 ServerAccount 关联 (使用)
  2. secret 可以存储 register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像
  3. secret 支持 Base64 加密
  4. secret 文件存储在 tmpfs 文件系统中,Pod删除后secret文件也会对应的删除

配置secret

1
2
3
4
5
6
7
# dotfile-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=

验证

1
kubectl get secret dotfile-secret -o json | jq '.data | map_values(@base64d)'

使用secret,有以下几种方式

  1. 作为挂载到一个或多个容器上的卷中的文件
  2. 作为容器的环境变量
  3. 由kubelet在为Pod拉取镜像时使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# secret-dotfiles-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: registry.noname.io:5000/alpine:3.20.1
command:
- ls
- "-la"
- "/etc/secret-volume"
# /etc/secret-volume/.secret-file
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"

执行命令

1
2
3
4
5
6
7
8
9
10
11
# 创建pod
kubectl apply -f secret-dotfiles-pod.yaml
# 查看secret-dotfiles-pod运行情况
kubectl get pod | grep secret-dotfiles-pod
# pod是否有其他异常
kubectl describe pod secret-dotfiles-pod
# 查看command输出日志
kubectl logs secret-dotfiles-pod
# 清理config、pod
kubectl delete -f dotfile-secret.yaml
kubectl delete -f secret-dotfiles-pod.yaml

参考

ConfigMaps
Secrets