1. ConfigMap
1.1. 概述
ConfigMap 是 Kubernetes 中用于存储非机密配置数据的 API 对象,允许你将配置与应用程序代码分离,从而实现更灵活的应用程序部署。
ConfigMap 主要用于:
- 存储环境变量。
- 存储命令行参数。
- 存储配置文件。
- 存储任何需要与容器镜像分离的配置数据。
注意事项:
- ConfigMap 必须在 Pod 创建之前存在。
- ConfigMap 位于特定命名空间中,Pod 只能引用相同命名空间中的 ConfigMap。
- 静态 Pod 不能引用 ConfigMap。
- ConfigMap 文件大小限制为 1MB(ETCD 数据库限制)。
1.2. 创建 ConfigMap 示例
1.2.1. 使用 yaml 文件创建
配置数据在 data 字段下,key:value 形式保存,value 值需要是字符串(非字符串需加上引号转化为字符串)。
# cm-test.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test1-config
namespace: default
data:
xxx: "111"
yyy: "222"
data.1: hello
data.2: world
config: |
property.1=value-1
property.2=value-2
property.3=value-3
YAML创建:
kubectl apply -f cm-test.yaml
Bash查看:
$ kubectl get cm test1-config
NAME DATA AGE
test1-config 5 75s
# 查看 ConfigMap 的详细数据
$ kubectl describe cm test1-config
Name: test1-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
config:
----
property.1=value-1
property.2=value-2
property.3=value-3
data.1:
----
hello
data.2:
----
world
xxx:
----
111
yyy:
----
222
BinaryData
====
Events: <none>
Bash在上述 yaml 文件中可以看到 config 字段后面有一个 | 符号,| 符号是一个 YAML 多行字符串标识符,它的作用是指示后面的内容是一个 保留换行符的多行字符串。常用标识符示例如下:
|
:表示后面的值是一个多行字符串,并且保留换行符。
data:
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
# 实际内容,会被原样存储
enemy.types=aliens,monsters
player.maximum-lives=5
Bash>
:在 yaml 中表示折叠换行,内容最末尾的换行会保留,但文中部分只有空白行才会被识别为换行,原来的换行符都会被转换成空格。
description: >
This is a long description
that will be folded into
a single line.
# 实际存储为
This is a long description that will be folded into a single line.
Bash- 上述两个符号搭配 + 或 – 号:+ 表示保留文字块末尾的换行,- 表示删除字符串末尾的换行。
value: |
hello
world
# {"value": "hello\nworld\n"}
value: |-
hello
world
# {"value": "hello\nworld"}
value: |+
hello
world
# {"value": "hello\nworld\n\n"} (有多少个回车就有多少个\n)
Bash综合示例:
# test1-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test1-config
namespace: default
data:
config1: |
property.1=value-1
property.2=value-2
property.3=value-3
config2: |-
hello
world
config3: |+
hello
world
config4: >
第一行
第二行
第三行
config5: >-
第一行
第二行
第三行
config6: >+
第一行
第二行
第三行
YAML部署后查看:
kubectl get cm test1-config -o json
{
"apiVersion": "v1",
"data": {
"config1": "property.1=value-1\nproperty.2=value-2\nproperty.3=value-3\n",
"config2": "hello\nworld",
"config3": "hello\nworld\n\n\n",
"config4": "第一行\n第二行 第三行\n",
"config5": "第一行\n第二行 第三行",
"config6": "第一行\n第二行 第三行\n\n\n"
},
"kind": "ConfigMap",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"data\":{\"config1\":\"property.1=value-1\\nproperty.2=value-2\\nproperty.3=value-3\\n\",\"config2\":\"hello\\nworld\",\"config3\":\"hello\\nworld\\n\\n\\n\",\"config4\":\"第一行\\n第二行 第三行\\n\",\"config5\":\"第一行\\n第二行 第三行\",\"config6\":\"第一行\\n第二行 第三行\\n\\n\\n\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"test1-config\",\"namespace\":\"default\"}}\n"
},
"creationTimestamp": "2025-08-14T02:37:50Z",
"name": "test1-config",
"namespace": "default",
"resourceVersion": "1730632",
"uid": "e7a71835-78ff-412f-a0a3-bd94db8883f8"
}
}
Bash1.2.2. 命令行创建
在 Kubernetes 中,可以使用 kubectl create configmap
命令通过多种方式创建 ConfigMap。
- –from-literal:直接指定键值对。
kubectl create configmap db-config \
--from-literal=DB_HOST=mysql \
--from-literal=DB_PORT=3306
# 查看
kubectl get configmap db-config -o yaml
apiVersion: v1
data:
DB_HOST: mysql
DB_PORT: "3306"
kind: ConfigMap
metadata:
creationTimestamp: "2025-08-14T03:42:24Z"
name: db-config
namespace: default
resourceVersion: "1732245"
uid: 7bbccdea-86b9-4ed9-a629-b0e71dc6aad3
Bash- –from-file:基于指定的文件或目录创建,文件名为 key,文件内容为 value,也可以单独指定 key。
- –from-file 可以多次使用。
- –from-file 指定目录时,会将目录下所有文件以 key:value 形式导入到 ConfigMap 中。
- 指定键名:
kubectl create configmap my-config --from-file=my-key=path/to/file
- –from-env-file:表示基于指定的 env 文件创建 ConfigMap。
- env 文件为一组环境变量的配置数据,文件每行都为 key=value 的格式,等号两边不能有空格。
- 创建 ConfigMap 时:
- 忽略以 # 开头的注释行。
- 忽略空行。
- 对文本的内容不做转义处理。
- 示例如下:
env.file:
DB_HOST=mysql
# 注释
DB_PORT=3306
DB_NAME=mydb
TeX创建:
kubectl create configmap db-env-config --from-env-file=env.file
Bash查看:
kubectl get cm db-env-config -o yaml
apiVersion: v1
data:
DB_HOST: mysql
DB_NAME: mydb
DB_PORT: "3306"
kind: ConfigMap
metadata:
creationTimestamp: "2025-08-14T04:04:21Z"
name: db-env-config
namespace: default
resourceVersion: "1735188"
uid: 5c84c915-c8dd-4fbd-baa0-a0970ae3259d
Bash1.2.3. 创建不可修改的 ConfigMap
从 Kubernetes v1.19 版本开始,ConfigMap 新增了 immutable 字段,用于设置配置数据不可修改,即 ConfigMap 资源对象一旦创建成功后就不可修改,如需修改,则只能通过先删除再重建来实现。
这样做的好处包括:
- 防止意外更新 ConfigMap 对应用带来的异常影响。
- 减少 API Server 监控 ConfigMap 的变化所带来的性能损耗。
- immutable 字段的配置示例如下:
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
YAML1.3. 在 Pod 中使用 ConfigMap
容器应用通过以下几种方式使用 ConfigMap:
- 将 ConfigMap 中的内容设置为容器内的环境变量。
- 同样将 ConfigMap 中的内容设置为容器内的环境变量,并作为命令行参数使用。
- 通过 Volume 将 ConfigMap 中的内容挂载为容器中的文件或目录。
1.3.1. 作为环境变量
单个环境变量注入:
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
- name: my-container
image: busybox
command: ["/bin/sh", "-c", "tail -f /dev/null"]
env:
- name: SPECIAL_LEVEL # 容器中的环境变量名
valueFrom:
configMapKeyRef:
name: special-config # ConfigMap 名称
key: SPECIAL_LEVEL # ConfigMap 中的键
optional: false # 可选,如果为 true 则 ConfigMap 或键不存在时不会报错
YAML全部键值作为环境变量注入:
apiVersion: v1
kind: Pod
metadata:
name: envfrom-pod
spec:
containers:
- name: my-container
image: busybox
command: ["/bin/sh", "-c", "tail -f /dev/null"]
envFrom:
- configMapRef:
name: special-config # 将整个 ConfigMap 的所有键值作为环境变量
optional: false
YAML1.3.2. 作为命令行参数
apiVersion: v1
kind: Pod
metadata:
name: args-pod
spec:
containers:
- name: my-container
image: busybox
command: ["/bin/sh", "-c", "echo $(SPECIAL_LEVEL) && tail -f /dev/null"] # 作为命令行参数使用
env:
- name: SPECIAL_LEVEL
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_LEVEL
YAML1.3.3. 作为卷挂载
完整挂载整个 ConfigMap:
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config # ConfigMap 内容将挂载到此目录
volumes:
- name: config-volume
configMap:
name: special-config # 要挂载的 ConfigMap 名称
optional: false
YAML挂载特定键:
apiVersion: v1
kind: Pod
metadata:
name: specific-key-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/special-key # 单个键将挂载到此路径
subPath: special-key # 指定要挂载的子路径
volumes:
- name: config-volume
configMap:
name: special-config
items: # 指定要包含的键
- key: SPECIAL_KEY # ConfigMap 中的键名
path: special-key # 挂载后的文件名
YAML设置文件权限:
apiVersion: v1
kind: Pod
metadata:
name: permission-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
defaultMode: 0600 # 设置文件权限为 600
items:
- key: config-file
path: my-config
mode: 0644 # 设置特定文件的权限为 644
YAML1.4. ConfigMap 热更新
在 Kubernetes 中,当你对 ConfigMap 进行更新或删除重建时,如果 ConfigMap 被挂载为 Volume 到了 Pod 内,那么这些更新是可以被反映到 Pod 文件系统上的文件内容中的,这也就是我们所说的”热更新”。
- Kubernetes 会定期检查并更新挂载的内容。
- 更新周期由 kubelet 的
--sync-frequency
参数控制(默认 1 分钟)。
测试示例如下:
# configmap-update.yaml
apiVersion: v1
data:
mysql.conf: |
host=127.0.0.1
port=3306
redis.conf: |
host=127.0.0.1
port=6379
kind: ConfigMap
metadata:
name: cm-demo
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: testcm5-pod
spec:
volumes:
- name: my-volume
configMap:
name: cm-demo
containers:
- name: testcm5
image: busybox
command: [ "/bin/sh","-c","sleep 10000" ]
volumeMounts:
- name: my-volume
mountPath: /etc/config
YAML创建:
kubectl apply -f configmap-update.yaml
Bash查看:
kubectl exec -it testcm5-pod -- sh
/ # cat /etc/config/
..2025_08_14_08_11_00.3823437720/ mysql.conf
..data/ redis.conf
/ # cat /etc/config/mysql.conf
host=127.0.0.1
port=3306
Bash更新 ConfigMap:
kubectl edit cm cm-demo # 将配置改动一下
apiVersion: v1
data:
mysql.conf: |
host=127.0.0.1
port=99999
Bash查看验证:
/ # cat /etc/config/mysql.conf
host=127.0.0.1
port=99999
Bash注意:这里的热更新只是配置文件更新了,这并不意味着运行在 Pod 中的应用会自动知道这些更改。事实上,很多的应用在启动时只会读取一次配置文件,而在运行时不会再对配置文件做任何检查。这就意味着,即使配置文件的内容被更新了,这些应用也不会感知到这种变化,必须重启应用才能加载新的配置。
1.5. 实现应用自动加载更新的配置
我们可以通过 Reloader 来实现应用的配置文件热更新,Reloader 是一个 Kubernetes 控制器(Controller),它会监视集群中的 ConfigMap
和 Secret
资源。当这些资源被修改时,Reloader 会自动触发引用它们的 Deployment
、StatefulSet
或 DaemonSet
进行滚动更新(Rolling Update),使 Pod 加载新的配置。
项目下载地址:
wget https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
Bash部署 Reloader 后,只需要在需要在 Deployment
、StatefulSet
或 DaemonSet
等控制器的注解部分加上 reloader.stakater.com/auto: "true"
,或指定具体的 ConfigMap/Secret
则可以实现自动加载新配置。
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
# 当名为 "my-config" 的 ConfigMap 更新时重启 Pod
reloader.stakater.com/auto: "true"
# 或指定具体 ConfigMap/Secret
reloader.stakater.com/search: "my-config"
Bash2. Secret
2.1. 概述
Secret 是 Kubernetes 中用于存储和管理敏感信息的对象,如密码、OAuth 令牌、SSH 密钥等。与 ConfigMap 类似,但专门设计用于敏感数据。
Secret 与 ConfigMap 的主要区别:
特性 | Secret | ConfigMap |
数据类型 | 敏感信息 | 非敏感配置 |
存储方式 | 默认 base64 编码 | 明文存储 |
安全特性 | 可加密存储 (etcd) | 无额外加密 |
典型用途 | 密码、密钥、令牌 | 应用配置、环境变量 |
Secret 常用类型,例如:
- Opaque (默认) :base64 编码格式的 Secret,通用类型,用于任意用户定义的敏感数据。
- kubernetes.io/tls:存放证书以及私钥。
- kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息,类型标识为 docker-registry。
2.2. Opaque 类型
特点:
- 可以存储任意键值对数据,适用于非结构化敏感信息(如密码、SSH 密钥、API 密钥等)。
- 可以自定义键名。
- 不会对内容做格式校验(纯存储)。
Secret 资源提供了 2 个可用字段:data 和 stringData。
- data 字段的数据必须是 base64 编码的任意数据。
- stringData 字段允许 Secret 使用未编码的字符串。
2.2.1. data 字段的使用
首先将明文转换成 base64 编码:
echo -n 'pingk' | base64 # 结果是 cGluZ2s=
echo -n '123456' | base64 # 结果是 MTIzNDU2
Bash创建一个 Secret:
# opaque-data-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: opaque-data-secret
data:
username: cGluZ2s=
password: MTIzNDU2
YAML部署后查看:
$ kubectl get secrets opaque-data-secret
NAME TYPE DATA AGE
opaque-data-secret Opaque 2 45s
$ kubectl describe secrets opaque-data-secret
Name: opaque-data-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
username: 5 bytes
$ kubectl get secrets opaque-data-secret -o yaml
apiVersion: v1
data:
password: MTIzNDU2
username: cGluZ2s=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"MTIzNDU2","username":"cGluZ2s="},"kind":"Secret","metadata":{"annotations":{},"name":"opaque-data-secret","namespace":"default"}}
creationTimestamp: "2025-08-14T12:07:20Z"
name: opaque-data-secret
namespace: default
resourceVersion: "1799963"
uid: cc05f59c-5d55-4203-bdbb-9a7e907fa656
type: Opaque
Bash2.2.2. stringData 字段的使用
某些场景下想将非 base64 编码的字符串放入 Secret 中,就需要用到 stringData 字段。
创建一个 Secret:
# opaque-stringData-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: opaque-stringdata-secret
type: Opaque
stringData:
username: pingk
password: "123456"
# 多行文本形式同 configmap
stringData:
config.yaml: |
username: pingk
password: 123456
YAML部署后查看:
# 可以看到自动编码为了 base64
kubectl get secrets opaque-stringdata-secret -o yaml
apiVersion: v1
data:
password: MTIzNDU2
username: cGluZ2s=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"opaque-stringdata-secret","namespace":"default"},"stringData":{"password":"123456","username":"pingk"},"type":"Opaque"}
creationTimestamp: "2025-08-14T12:22:44Z"
name: opaque-stringdata-secret
namespace: default
resourceVersion: "1802033"
uid: 4766141e-53d1-43c0-a75a-db8759542fb2
type: Opaque
Bash2.2.3. 命令行创建方式
直接指定键值对:
kubectl create secret generic my-secret \
--from-literal=username=admin \
--from-literal=password='123456'
# generic:表示通用类型
# 会自动编码 base64
Bash从文件创建:
kubectl create secret generic ssh-key-secret \
--from-file=ssh-privatekey=~/.ssh/id_rsa \
--from-file=ssh-publickey=~/.ssh/id_rsa.pub
Bash2.2.4. 引用 Secret
创建好 Secret 对象后,有两种方式来使用它:
- 以环境变量的形式。
- 以 Volume 的形式挂载。
挂载卷的方式:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- image: busybox
name: busybox
command: ["/bin/sh","-c","sleep 10000"]
# 挂载到容器内,挂载为一个目录
volumeMounts:
- name: xxx
mountPath: /etc/my-secret
# 卷声明
volumes:
- name: xxx
secret:
secretName: test-secret
YAML环境变量的方式:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- image: busybox
name: busybox
args: ["sleep", "36000"]
env:
- name: USER
valueFrom:
secretKeyRef:
name: test-secret
key: username
optional: false # 可选,默认就是false
- name: PASSWORD
valueFrom:
secretKeyRef:
name: test-secret
key: password
- name: CONFIG
valueFrom:
secretKeyRef:
name: demo-secret
key: config.yaml
YAML2.2. tls 类型
特点:
- 专门用于存储 TLS 证书和私钥。
- 必须包含两个固定字段:
tls.crt
:证书文件(PEM 编码)tls.key
:私钥文件(PEM 编码)
- Kubernetes 会验证证书和私钥的格式。
2.2.1. 创建方式
yaml 文件创建:
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert> # 证书内容(base64 编码)
tls.key: <base64-encoded-key> # 私钥内容(base64 编码)
YAML命令行创建:
kubectl create secret tls tls-secret \
--cert=path/to/cert.pem \
--key=path/to/key.pem
Bash2.2.2. 使用示例
在 Ingress 中启用 HTTPS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
tls:
- hosts:
- example.com
secretName: tls-secret # 引用 TLS Secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
YAML在 Service 中启用 TLS:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- name: https
port: 443
targetPort: 8443
selector:
app: my-app
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
ports:
- containerPort: 8443
volumeMounts:
- name: tls-secret
mountPath: "/etc/tls"
readOnly: true
volumes:
- name: tls-secret
secret:
secretName: tls-secret # 挂载 TLS Secret
YAMLPod 直接挂载 TLS 文件:
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: tls
mountPath: "/etc/nginx/ssl"
volumes:
- name: tls
secret:
secretName: tls-secret # 挂载到 Pod
items:
- key: tls.crt
path: server.crt # 证书重命名为 server.crt
- key: tls.key
path: server.key # 私钥重命名为 server.key
YAML2.3. dockerconfigjson 类型
dockerconfigjson 是 Kubernetes 中一种特殊类型的 Secret,专门用于存储 Docker 镜像仓库的认证信息。它允许 Kubernetes 在拉取私有镜像时自动提供认证凭据。
2.3.1. 创建方式
yaml 文件创建:
# 创建完整的 config.json
cat > config.json <<EOF
{
"auths": {
"registry.example.com": {
"username": "myuser",
"password": "S3cr3tP@ss",
"auth": "dXNlcm5hbWU6cGFzc3dvcmQ=",
"email": "myuser@example.com"
}
}
}
EOF
# 转换为 base64
cat config.json | base64 -w 0
# 创建 Secret YAML
apiVersion: v1
kind: Secret
metadata:
name: my-registry-secret
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-config.json>
Bash命令行创建:
kubectl create secret docker-registry <secret-name> \
--docker-server=<registry-server> \
--docker-username=<username> \
--docker-password=<password> \
--docker-email=<email>
Bash2.3.2. 使用示例
在创建 Pod 拉取镜像时使用:
apiVersion: v1
kind: Pod
metadata:
name: private-pod
spec:
containers:
- name: private-app
image: registry.example.com/private/image:latest
imagePullSecrets:
- name: my-registry-secret # 指定 dockerconfigjson Secret
YAML为 ServiceAccount 添加 pull secret:
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
imagePullSecrets:
- name: my-registry-secret
# ServiceAccount 添加 imagePullSecrets 后,所有使用该 ServiceAccount 的 Pod 都可以直接引用私有镜像仓库,而无需在每个 Pod 中单独指定 imagePullSecrets
YAML2.4. Secret 热更新
Secret 的热更新机制与 ConfigMap 相同。
2.5. Secret 标记不可变
apiVersion: v1
kind: Secret
metadata:
...
data:
...
immutable: true # 标记为不可变
YAML2.6. 总结
同样 Secret 文件大小限制为 1MB(ETCD 的要求);Secret 虽然采用 Base64 编码,但是我们还是可以很方便解码获取到原始信息,所以对于非常重要的数据还是需要慎重考虑,可以考虑使用 Vault 来进行加密管理。