文章目录
作用: 将配置文件和程序分离 ,也是云原生的要素
ConfigMap - 用于明文存储、或者变量存储
Secret - 用于密码存储
限制: 不同namespace下的cm和secret相互隔离(可重名创建)
调度类型的资源 比如deployment要使用configmap时 需要和configmap资源在同一namespace下、否则挂载失败
限制: 以环境变量方式使用的 ConfigMap 数据不会被自动更新。 更新这些数据需要将 Pod删除重建 ,重启业务也不好使,因为数据是在Pod创建时加载进去的。
限制: 使用 ConfigMap 作为 subPath 卷挂载的容器将不会收到 ConfigMap 的更新。
ConfiMap
Configmap创建文件
- 创建配置文件
mkdir config
[root@k8s-master01 config]# cat test1.conf
k8s.io=true
return=false
[root@k8s-master01 config]# cat test2.conf
user=root
password=123qq...A
- 创建configmap
# ./config 会将路径下的所有文件纳入到configmap中
# ./config/a.txt 也可以单独指定某个文件
kubectl create cm configmap --from-file=./config
kubectl get cm
NAME DATA AGE
configmap 2 7s
kube-root-ca.crt 1 6d
[root@k8s-master01 pod]# kubectl get cm configmap -o yaml
apiVersion: v1
data:
test1.conf: |
k8s.io=true
return=false
test2.conf: |
user=root
password=123qq...A
kind: ConfigMap
metadata:
creationTimestamp: "2023-11-25T11:13:26Z"
name: configmap
namespace: default
resourceVersion: "383299"
uid: b1fd4feb-2803-4b1d-a11e-205c370ac39b
Configmap创建环境变量
- 创建变量
- 如果有程序需要使用环境变量也可以用configmap来管理
方式1
[root@k8s-master01 config]# cat env1.conf
level=info
logrote=3
[root@k8s-master01 config]# kubectl create cm env --from-env-file=env1.conf
[root@k8s-master01 config]# kubectl get cm/env -o yaml
apiVersion: v1
data:
level: info
logrote: "3"
kind: ConfigMap
metadata:
creationTimestamp: "2023-11-25T11:27:43Z"
name: env
namespace: default
resourceVersion: "385176"
uid: 5ac5da16-0efa-4f9a-a75b-1d998a6697e7
方式2
kubectl create cm env-literal \
--from-literal=user=root \
--from-literal=always=True
[root@k8s-master01 config]# kubectl get cm/env-literal -o yaml
apiVersion: v1
data:
always: "True"
user: root
kind: ConfigMap
metadata:
creationTimestamp: "2023-11-25T11:31:45Z"
name: env-literal
namespace: default
resourceVersion: "385703"
uid: 185b5ec1-9eb2-42cb-a8d4-9e9f7ca2133a
变量使用问题和总结
- 创建时指定–from-env-file 注定就是做环境变量使用的
- 创建时指定–from-file 注定就是做文件挂载的
- 如果你的文件是这样?
[root@k8s-master01 pod]# cat a.txt
a=123
v1=222
ccc # 故意不写成key=value格式
# 创建env的cm
详细内容是这样的
[root@k8s-master01 pod]# kubectl get cm/test -o yaml
apiVersion: v1
data:
a: "123"
ccc: "" # 注意ccc的值是空
v1: "222"
kind: ConfigMap
- 另外还有一个现象就是如果你是指定的–from-file那get yaml的时候多半有个 | 它的key是文件名称,这时候你想使用这里的变量v1来传入容器、多半会报错的
[root@k8s-master01 pod]# kubectl get cm/test -o yaml
apiVersion: v1
data:
a.txt: |
a=123
v1=222
kind: ConfigMap
Configmap使用之valueFrom
- 创建一个deployment
cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine
name: nginx
env:
- name: LIVES # 容器中Key的名称
valueFrom: # value从哪拿
configMapKeyRef:
name: env # 从env这个configmap中拿
key: logrote # 拿logrote的value 赋值给 LIVES
# 查看env这个configmap
[root@k8s-master01 pod]# kubectl get cm | grep env
env 2 24m
# 查看env详情:
[root@k8s-master01 pod]# kubectl get cm/env -o yaml
apiVersion: v1
data:
level: info
logrote: "3"
kind: ConfigMap
metadata:
creationTimestamp: "2023-11-25T11:27:43Z"
name: env
namespace: default
resourceVersion: "385176"
uid: 5ac5da16-0efa-4f9a-a75b-1d998a6697e7
logrote对应的value是3
# 在容器中验证 符合预期
kubectl exec -it dp-cm-558d7d9fb5-clv56 -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=dp-cm-558d7d9fb5-clv56
NGINX_VERSION=1.15.12
LIVES=3
Configmap使用之envFrom
常用
- 使用envfrom将所有configMap中的数据定义为容器的环境变量,configMap中的键成为Pod中环境变量的名称
# 截取部分
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine
name: nginx
envFrom:
- configMapRef:
name: env
prefix: fromcm # 变量前缀可不写
# 创建deployment
kubectl apply -f dp-cm.yaml
# 验证
kubectl exec -it dp-cm-6db659fc54-rlw9g -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=dp-cm-6db659fc54-rlw9g
NGINX_VERSION=1.15.12
fromcmpassword=123qqq...A
fromcmlevel=info
fromcmlogrote=7
Configmap使用之以文件的形式挂载(多个文件)
- 如果指定的路径 容器内存在,容器里的路径就会被覆盖
- configmap更新 容器会更新
# 创建configmap
[root@k8s-master01 more_conf]# pwd
/root/pod/more_conf
[root@k8s-master01 more_conf]# ls
deploy-ingress.yaml dp-cm.yaml ingress.yaml man_port.yaml nd.yaml nginx.yaml secret.yaml sts.yaml svc_hd.yaml svc_ser.yaml whdp.yaml
kubectl create cm more-conf --from-file=./more_conf/ # 创建configmap
kubectl get cm/more-conf -o yaml # 每个文件名是key名称 value则是对应的文件内容
# 修改deployment 挂载文件
[root@k8s-master01 pod]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine
name: nginx
volumeMounts:
- name: more-conf-volume
mountPath: /etc/kolla
volumes:
- name: more-conf-volume # volume的名称
configMap: # 使用configmap的挂载方式
name: more-conf # 指定configmap的名称
# 进入容器查看挂载文件
[root@k8s-master01 pod]# kubectl exec -it dp-cm-6dc4b68f9f-qbkhb -- sh
/ # ls /etc/kolla/
deploy-ingress.yaml ingress.yaml nd.yaml secret.yaml svc_hd.yaml whdp.yaml
dp-cm.yaml man_port.yaml nginx.yaml sts.yaml svc_ser.yaml
Configmap使用之以文件的形式挂载(单个文件)
- 如果指定的路径 容器内存在,容器里的路径就会被覆盖
- configmap更新 容器会更新
1. 创建configmap
这里引用上方的configmap
[root@k8s-master01 pod]# kubectl get cm/more-conf
NAME DATA AGE
more-conf 11 6h48m
2. 更新deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine
name: nginx
volumeMounts:
- name: more-conf-volume
mountPath: /etc/kolla/
volumes:
- name: more-conf-volume # volume的名称
configMap: # 使用configmap的挂载方式
name: more-conf # 指定configmap的名称
items: # # 来自 ConfigMap 的一组键,将被创建为文件
- key: deploy-ingress.yaml
path: deploy-ingress.yaml
- key .... # 可以指定多个
3. 验证:
[root@k8s-master01 pod]# kubectl exec -it dp-cm-d976b6568-5t4bh -- ls /etc/kolla
deploy-ingress.yaml
上面的例子定义了一个卷并将它作为/etc/kolla/ 文件夹挂载到 demo 容器内, 创建一个文件,/etc/kolla/deploy-ingress.yaml, 尽管 ConfigMap 中包含了多个键。 这是因为 Pod 定义中在 volumes 节指定了一个 items 数组。 如果你完全忽略 items 数组,则 ConfigMap 中的每个键都会变成一个与该键同名的文件, 因此你会得到11个文件。
Configmap配置文件之修改
想修改配置文件?
两种方法:
- 直接edit cm ,容器内大概30s-1min左右会更新
- 修改configmap后端对应的文件(但是前提是configmap的引用没有使用subpath、如果你是文件subPath的方式挂载 容器里是不会更新的)
# 比如这里2048 改成1024
[root@k8s-master01 pod]# cat nginx.conf | grep 2048
worker_connections 2048;
[root@k8s-master01 pod]# sed -i 's/2048/1024/' nginx.conf
# 利用configmap的创建命令指定 dry-run 生成yaml文件 并交给replace替换
kubectl create cm conf --from-file=nginx.conf \
--dry-run -o yaml | kubectl replace -f -
# 直接替换
# 或者
kubectl create cm conf --from-file=nginx.conf \
--dry-run -o yaml > nginx.yaml
kubectl replace -f nginx.yaml
# 进入容器查看
大概30s - 1min后 容器内会更新
但容器更新的前提是 你是采用目录的方式挂载而不是subpath文件的方式挂载!
Secret
- secret的类型
创建secret
使用kubectl
官网链接:https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-kubectl/
1. 使用源文件
将凭据保存到文件:
echo -n 'admin' > ./username.txt
echo -n 'S!B\*d$zDsb=' > ./password.txt
-n 标志用来确保生成文件的文末没有多余的换行符。
这很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,额外的换行符也会被编码。 你不需要对文件中包含的字符串中的特殊字符进行转义。
2. 在 kubectl 命令中传递文件路径:
kubectl create secret generic db-user-pass \
--from-file=./username.txt \
--from-file=./password.txt
3. 默认键名为文件名。你也可以通过 --from-file=[key=]source 设置键名,例如:
kubectl create secret generic db-user-pass \
--from-file=username=./username.txt \
--from-file=password=./password.txt
4. 查看
[root@k8s-master01 pod]# kubectl get secret
NAME TYPE DATA AGE
db-user-pass Opaque 2 3s
default-token-58576 kubernetes.io/service-account-token 3 6d18h
5. 使用get 或者describe是看不到源数据的,因为经过base64 编译
[root@k8s-master01 pod]# kubectl get secret/db-user-pass -oyaml
apiVersion: v1
data:
password.txt: UyFCXCpkJHpEc2I9
username.txt: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2023-11-26T05:01:45Z"
name: db-user-pass
namespace: default
resourceVersion: "439762"
uid: 55d730a7-1a79-4900-8901-1369c04678c5
type: Opaque
6. 解码
kubectl get secret/db-user-pass -o jsonpath='{.data}'
{"password.txt":"UyFCXCpkJHpEc2I9","username.txt":"YWRtaW4="}
echo UyFCXCpkJHpEc2I9 | base64 --decode
S!B\*d$zDsb=
使用资源文件
官网地址: https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-config-file/
将这些字符串转换为 base64:
echo -n 'admin' | base64
echo -n '1f2d1e2e67df' | base64
输出类似于:
YWRtaW4=
MWYyZDFlMmU2N2Rm
创建清单:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kubectl apply -f ./secret.yaml
创建 Secret 时提供未编码的数据
对于某些场景,你可能希望使用 stringData 字段。 这个字段可以将一个非 base64 编码的字符串直接放入 Secret 中, 当创建或更新该 Secret 时,此字段将被编码。
[root@k8s-master01 pod]# cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
apiUrl: "https://my.api.com/api/v1"
username: <user>
password: <password>
[root@k8s-master01 pod]# kubectl apply -f secret.yaml
kbectl secret/mysecret created
输出类似于:
[root@k8s-master01 pod]# kubectl get secret/mysecret -o yaml
apiVersion: v1
data:
apiUrl: aHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MQ==
password: PHBhc3N3b3JkPg==
username: PHVzZXI+
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"stringData":{"apiUrl":"https://my.api.com/api/v1","password":"\u003cpassword\u003e","username":"\u003cuser\u003e"},"type":"Opaque"}
creationTimestamp: "2023-11-26T05:21:19Z"
name: mysecret
namespace: default
resourceVersion: "442324"
uid: 45902cf1-d469-45e9-9694-67e18adcd5f5
type: Opaque
Secret使用之以文件的形式挂载
- 与configmap类似
# 确保有secret
[root@k8s-master01 pod]# kubectl get secret | grep mysecret
mysecret Opaque 3 4m58s
[root@k8s-master01 pod]# cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
secret.conf: |
apiUrl: "https://my.api.com/api/v1"
username: <user>
password: <password>
# pod引用
[root@k8s-master01 pod]# cat dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dp-cm
name: dp-cm
spec:
replicas: 1
selector:
matchLabels:
app: dp-cm
template:
metadata:
labels:
app: dp-cm
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine
name: nginx
volumeMounts:
- name: secret-conf # 挂载哪个卷
mountPath: /etc/secret/config # 挂载到哪
volumes:
- name: secret-conf # 卷的名称
secret: # 卷的类型
secretName: mysecret # 后端secret的名称
验证:
kubectl exec -it dp-cm-7dcc68777-7jmsd -- sh
cd /etc/secret/config
cat secret.conf
apiUrl: "https://my.api.com/api/v1"
username: <user>
password: <password>
# 可以看到已经成功加载进来了
Secret使用之valueFrom
官网地址:https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data
- 使用来自 Secret 中的数据定义容器变量
定义环境变量为 Secret 中的键值偶对
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
或者使用指定文件的方法创建
[root@k8s-master01 pod]# cat user.conf
backend-username='backend-admin'
[root@k8s-master01 pod]# kubectl create secret generic secret-env2 --from-file=backend-username=./user.conf
这样key名就变成 backend-username了,不然key名是文件名 user.conf
[root@k8s-master01 pod]# cat pod-single-secret-env-variable.yaml
apiVersion: v1
kind: Pod
metadata:
name: env-single-secret
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME # 容器中key名
valueFrom:
secretKeyRef:
name: backend-user # 指定secret
key: backend-username # secret的key对应的value赋值给SECRET_USERNAME
创建 Pod:
kubectl create -f pod-single-secret-env-variable.yaml
在 Shell 中,显示容器环境变量 SECRET_USERNAME 的内容:
kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
输出类似于:
backend-admin
Secret使用之envFrom
- 使用 envFrom 来将 Secret 中的所有数据定义为环境变量。 Secret 中的键名成为容器中的环境变量名:
- 官网链接:https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data
# 创建包含多个键值偶对的 Secret:
kubectl create secret generic test-secret \
--from-literal=username='my-app' \
--from-literal=password='39528$vdg7Jb'
#使用 envFrom 来将 Secret 中的所有数据定义为环境变量。
# Secret 中的键名成为容器中的环境变量名:
# 创建Pod
apiVersion: v1
kind: Pod
metadata:
name: envfrom-secret
spec:
containers:
- name: envars-test-container
image: nginx
envFrom:
- secretRef:
name: test-secret
kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
在 Shell 中,显示环境变量 username 和 password 的内容
kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
输出类似与:
username: my-app
password: 39528$vdg7Jb
secret案例之拉取私有仓库镜像
- 假如你使用私有仓库镜像,那拉取的时候是需要先login的
- 如果不login会拉取失败
- 创建secret、资源对象引用即可
kubectl create secret docker-registry private-registry-login --docker-username=xxx@qq.com\
--docker-password=xxxx \
--docker-email=xxxx@163.com \
--docker-server=registry.cn-beijing.aliyuncs.com
kubectl get secret | grep registry
private-registry-login kubernetes.io/dockerconfigjson 1 59s
# deployment使用secret
root@k8s-master01 pod]# cat dp-cm.yaml
...
spec:
imagePullSecrets:
- name: private-registry-login
containers:
- image: registry.cn-beijing.aliyuncs.com/java-demo-test/nginx:needlogin
name: nginx
secret案例之管理https证书
# 使用openssl模拟创建不受信任的证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.com"
# 一般自己买的证书也会有这两个文件
[root@k8s-master01 secret]# ll
total 8
-rw-r--r-- 1 root root 1090 Nov 26 22:00 tls.crt
-rw-r--r-- 1 root root 1704 Nov 26 22:00 tls.key
# 创建secret
kubectl create secret tls nginx-test-tls --key=tls.key --cert=tls.crt
kubectl get secret
NAME TYPE DATA AGE
nginx-test-tls kubernetes.io/tls 2 4s
# 配置ingress
[root@k8s-master01 pod]# cat ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- backend:
service:
name: whdp
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- secretName: nginx-test-tls
# 本地更改hosts将nginx.test.com 映射到 某个宿主机上
# 测试访问
subPath使用
- subPath挂载不会覆盖原有路径的内容,但是缺点是不支持更新
# subpath挂载
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine
name: nginx
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/nginx.conf #文件方式挂载
subPath: nginx.conf # 指定文件名
volumes:
- name: nginx-conf # volume的名称
configMap: # 使用configmap的挂载方式
name: conf # 指定configmap的名称
总结
configmap 和secret 都需要提前创建
configmap和secret都可以为pod提供挂载和变量的方式
变量的方式有envfrom全部变量和valuefrom单个变量的引用
configmap和secret 需要和引用的pod或者资源对象在同一个ns下