一、ConfigMap¶
1.1 概述¶
ConfigMap是一种API对象,用来将 非加密数据 保存到 键值对 中。可以用作环境变量、命令行参数或者存储卷中的配置文件。
ConfigMap可以将环境变量配置信息和容器镜像解耦,便于应用配置的修改。如果需要存储加密信息时可以使用Secret对象。
1.2 作用¶
ConfigMap是Kubernetes系统上两种特殊类型的存储卷,ConfigMap对象用于为容器中的应用提供配置文件等信息。
例如:nginx、redis、mysql、coredns、jenkins、apollo等配置文件,实现统一管理, 热更新等;
1.3 创建ConfigMap的常用3种方式¶
1、命令行方式创建,格式:--from-literal=key=value
# 创建cm
[root@master01 1]# kubectl create configmap cm1 --from-literal=server_name=www.xxx.com --from-literal=listen=80
# 查看
[root@master01 1]# kg cm
NAME DATA AGE
cm1 2 5s
# 环境复原
[root@master01 1]# k delete cm cm1
2、通过指定文件(内设多个键值对),格式: --from-env-file=文件路径
# 定义加密文件
cat > env.txt <<EOF
server_name=www.xxx.com
listen=80
EOF
# 创建cm
[root@master01 1]# kubectl create configmap cm2 --from-env-file=env.txt
# 查看
[root@master01 1]# kg cm
NAME DATA AGE
cm2 2 6s
# 环境复原
[root@master01 1]# k delete cm cm2
3、通过YMAL文件创建
# 创建cm模板
[root@master01 1]# k create cm cm3 --from-literal=server_name=www.xxx.com --from-literal=listen=80 --dry-run=client -oyaml > cm3.yaml
# 定义yaml文件
[root@master01 1]# vim cm3.yaml
apiVersion: v1
data:
listen: "80"
server_name: www.xxx.com
kind: ConfigMap
metadata:
name: cm3
# 创建
[root@master01 1]# kaf cm3.yaml
# 环境复原
[root@master01 1]# k delete -f cm3.yaml
另外一种创建方式:
apiVersion: v1
data:
nginx.conf: |
server {
server_name www.nginx.com;
listen 80;
root /home/nginx/www/
}
metadata:
name: nginx-conf
labels:
app: nginx-conf
1.4 ConfigMap的2种使用方式¶
1、通过环境变量的方式传递给pod
# 创建cm1
[root@master01 1]# kubectl create configmap cm1 --from-literal=server_name=www.xxx.com --from-literal=listen=80
# 创建pod模板
[root@master01 1]# k run pod-cm1 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28 --dry-run=client -oyaml > pod-cm1.yaml
# 定义
[root@master01 1]# vim pod-cm1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-cm1
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28
name: busybox
args: [ "/bin/sh", "-c", "sleep 10000" ]
envFrom: # env方式
- configMapRef:
name: cm1 # configmap名称
# 应用
[root@master01 1]# kaf pod-cm1.yaml
# 查看
[root@master01 1]# kgp | grep pod-cm1
pod-cm1 1/1 Running 0 5s
[root@master01 1]# kubectl exec pod-cm1 -- env|grep listen
listen=80
# 修改监听端口为99
[root@master01 1]# k edit cm cm1
apiVersion: v1
data:
listen: "99"
server_name: www.xxx.com
kind: ConfigMap
metadata:
creationTimestamp: "2023-11-10T01:52:21Z"
name: cm1
namespace: default
resourceVersion: "940983"
uid: b42dd508-73c4-4286-9e66-758701ca71d3
# 再次验证,观察到端口没有更新
[root@master01 1]# kubectl exec pod-cm1 -- env|grep listen
listen=80
# 环境复原
[root@master01 1]# k delete -f pod-cm1.yaml
[root@master01 1]# k delete cm cm1
2、通过volume的方式挂载到pod内
# 定义加密文件
cat > env.txt <<EOF
server_name=www.xxx.com
listen=80
EOF
# 创建cm
[root@master01 1]# kubectl create configmap cm2 --from-env-file=env.txt
# 创建pod模板
[root@master01 1]# k run pod-cm2 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28 --dry-run=client -oyaml > pod-cm2.yaml
# 定义
[root@master01 1]# vim pod-cm2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-cm2
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28
name: busybox
args: [ "/bin/sh", "-c", "sleep 10000" ]
volumeMounts: # 用volume挂载方式
- name: vol-cm # 对应下面的volume名
mountPath: "/etc/nginx" # 挂载到容器内部的路径
readOnly: true # 只读
volumes:
- name: vol-cm # 卷名称
configMap:
name: cm2 # configmap的名称
# 应用
[root@master01 1]# kaf pod-cm2.yaml
# 查看
[root@master01 1]# kgp | grep pod-cm2
pod-cm2 1/1 Running 0 8s
[root@master01 1]# kubectl exec pod-cm2 -- cat /etc/nginx/listen
80
# 修改监听端口为99
[root@master01 1]# k edit cm cm2
apiVersion: v1
data:
listen: "99"
server_name: www.xxx.com
kind: ConfigMap
metadata:
creationTimestamp: "2023-11-10T02:00:08Z"
name: cm2
namespace: default
resourceVersion: "941120"
uid: 4323506b-1ecc-430a-9a31-2a11983b67a1
# 再次验证,观察到端口更新(要等个1分钟左右)
[root@master01 1]# kubectl exec pod-cm2 -- cat /etc/nginx/listen
99
# 环境复原
[root@master01 1]# k delete -f pod-cm2.yaml
[root@master01 1]# k delete cm cm2
1.5 ConfigMap的热更新¶
结论:
-
通过环境变量的方式传递给pod。这种方式不会热更新;
-
通过volume的方式挂载到pod内。这种方式会热更新;
验证第1种方式:编辑修改对应的configmap
# 编辑
kubectl edit cm cm1
# 验证
kubectl exec pod-cm1 -- env|grep listen
验证第2种方式:编辑修改对应的configmap
# 编辑
kubectl edit cm cm2
# 验证
kubectl exec pod-cm2 -- cat /etc/nginx/listen
验证对应的pod里的变化,一段时间后会改变
二、Secret¶
Secret与ConfigMap类似,主要的区别是Secret存储的是密文,而ConfigMap存储的是明文。
所以ConfigMap可以用配置文件管理,而而 Secret可用于密码,密钥,token等敏感数据的配置管理。
Secret有4种类型:
- Opaque: base64编码格式的Secret,用来存储密码、密钥、信息、证书等,类型标识符为generic
- Service Account: 用来访问Kubernetes API,由Kubernetes自动创建,并且会 自动挂载 到Pod的/run/secrets/kubernetes.io/serviceaccount目录中
- kubernetes.io/dockerconfigjson: 用来存储私有 docker registry的认证 信息, 类型标识为docker-registry。
- kubernetes.io/tls: 用于为SSL通信模式存储 证书 和 私钥 文件,命令式创建类型标识为tls。
2.1 Opaque¶
1、将明文密码进行base64编码
[root@master01 1]# echo -n hellomysql |base64
aGVsbG9teXNxbA==
2、编写创建secret的YAML文件
# 创建secret模板文件
[root@master01 1]# k create secret generic secret-mysql --dry-run=client -oyaml > secret-mysql.yaml
# 定义yaml文件
[root@master01 1]# vim secret-mysql.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-mysql
data:
password: aGVsbG9teXNxbA==
# 应用
[root@master01 1]# kaf secret-mysql.yaml
# 查看
[root@master01 1]# kg secret | grep secret-mysql
secret-mysql Opaque 1 30s
2.1.1 Secret的2种使用方式¶
1、通过ENV变量的方式
创建mysql的pod示例,引用来自如上的 secret-mysql
# 定义yaml文件
[root@master01 1]# vim secret-mysql.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-mysql
data:
password: aGVsbG9teXNxbA==
# 应用
[root@master01 1]# kaf secret-mysql.yaml
------------
# 创建pod模板
[root@master01 1]# k run pod-mysql-secret1 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23 --dry-run=client -oyaml > pod-mysql-secret1.yaml
# 定义yaml文件
[root@master01 1]# vim pod-mysql-secret1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-mysql-secret1
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: secret-mysql # 对应创建的secret名字
key: password
# 应用
[root@master01 1]# kaf pod-mysql-secret1.yaml
# 查看
[root@master01 1]# kgp | grep pod-mysql
pod-mysql-secret1 1/1 Running 0 5m39s
# 验证,其中密文会被转义成明文
[root@master01 1]# kubectl exec pod-mysql-secret1 -- env | grep MYSQL_ROOT_PASSWORD
MYSQL_ROOT_PASSWORD=hellomysql
# 提前获取加密密码
[root@master01 1]# echo -n "mysql" | base64
bXlzcWw=
# 修改密码为mysql
[root@master01 1]# k edit secret secret-mysql
apiVersion: v1
data:
password: bXlzcWw=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"aGVsbG9teXNxbA=="},"kind":"Secret","metadata":{"annotations":{},"name":"secret-mysql","namespace":"default"}}
creationTimestamp: "2023-11-10T03:09:08Z"
name: secret-mysql
namespace: default
resourceVersion: "960444"
uid: 6b5d95d5-a329-4f80-ba96-f298de3213f4
type: Opaque
# 再次验证,观察到密码未被修改
[root@master01 1]# kubectl exec pod-mysql-secret1 -- env | grep MYSQL_ROOT_PASSWORD
MYSQL_ROOT_PASSWORD=hellomysql
# 环境复原
[root@master01 1]# k delete -f pod-mysql-secret1.yaml
[root@master01 1]# k delete -f secret-mysql.yaml
2、通过volume的方式挂载
# 定义yaml文件
[root@master01 1]# vim secret-mysql.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-mysql
data:
password: aGVsbG9teXNxbA==
# 应用
[root@master01 1]# kaf secret-mysql.yaml
------------
# 创建pod模板
[root@master01 1]# k run pod-mysql-secret2 --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23 --dry-run=client -oyaml > pod-mysql-secret2.yaml
# 定义yaml文件
[root@master01 1]# vim pod-mysql-secret2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-mysql-secret2
spec:
containers:
- name: busybox
image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28
args:
- /bin/sh
- -c
- sleep 100000
volumeMounts:
- name: vol-secret #定义挂载的卷,对应下面定义的卷名
mountPath: "/opt/passwd" #挂载目录(支持热更新),也可以使用subPath挂载文件(但不支持热更新)
readOnly: true #只读
volumes:
- name: vol-secret #定义卷名
secret: #使用secret
secretName: secret-mysql #对应创建好的secret名
# 应用
[root@master01 1]# kaf pod-mysql-secret2.yaml
# 查看
[root@master01 1]# kgp | grep pod-mysql-secret2
pod-mysql-secret2 1/1 Running 0 49s
# 验证
[root@master01 1]# kubectl exec pod-mysql-secret2 -- cat /opt/passwd/password
hellomysql
# 提前获取加密密码
[root@master01 1]# echo -n "mysql" | base64
bXlzcWw=
# 修改密码为mysql
[root@master01 1]# k edit secret secret-mysql
apiVersion: v1
data:
password: bXlzcWw=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"aGVsbG9teXNxbA=="},"kind":"Secret","metadata":{"annotations":{},"name":"secret-mysql","namespace":"default"}}
creationTimestamp: "2023-11-10T03:09:08Z"
name: secret-mysql
namespace: default
resourceVersion: "960444"
uid: 6b5d95d5-a329-4f80-ba96-f298de3213f4
type: Opaque
# 等待1分钟后再次验证,观察到密码已被修改
[root@master01 1]# kubectl exec pod-mysql-secret2 -- cat /opt/passwd/password
mysql
# 环境复原
[root@master01 1]# k delete -f pod-mysql-secret2.yaml
[root@master01 1]# k delete -f secret-mysql.yaml
2.1.2 小结¶
- 通过env的方式 pod中参数并未发生变化;
- 需重启pod;
-
推荐更新configMap的name;
-
通过挂载的方式 pod中参数发生变化;
2.2 dockerconfigjson¶
场景:使用jenkins自动部署容器到K8S中,其中一个步骤就是在运行容器前需要下载当前应用镜像,这时候就需要我们通过secret创建docker类型的秘钥来进行授权并拉取镜像
# 提前使用docker login登录harbor私仓,不然不会生成授权文件
docker login xxx
# 查看授权文件
[root@master01 1]# cat /root/.docker/config.json
# 通过授权文件来进行加密创建
[root@master01 1]# kubectl create secret generic harborsecret --from-file=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson -n default
引用:
apiVersion: v1
kind: Pod
metadata:
name: fooTest
spec:
containers:
- name: fooTest
image: xxx/xxxxapp:v1
imagePullSecrets:
- name: harborsecret
2.3 kubernetes.io/tls¶
场景:在K8S业务场景中,很多服务通过ingress进行暴露,多数应用的核心通讯协议为 https,这就需要我们引入对应域名的证书tls;
kubectl create secret tls ingress-secret2023 -ndefault --key 7128773_xxxx.com.key --cert 7128773_xxxx.com.pem
引用:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/proxy-body-size: "0"
ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
app: harbor
chart: harbor
heritage: Tiller
release: xxxx
name: xxxx-harbor-ingress
namespace: default
spec:
rules:
- host: core-harbor.xxxx.com
http:
paths:
- backend:
serviceName: xxxx-harbor-portal
servicePort: 80
path: /
- backend:
serviceName: xxxx-harbor-core
servicePort: 80
path: /api/
- backend:
serviceName: xxxx-harbor-core
servicePort: 80
path: /service/
- backend:
serviceName: xxxx-harbor-core
servicePort: 80
path: /v2/
- backend:
serviceName: xxxx-harbor-core
servicePort: 80
path: /chartrepo/
- backend:
serviceName: xxxx-harbor-core
servicePort: 80
path: /c/
- host: core-harbor.xxxx.com
http:
paths:
- backend:
serviceName: xxxx-harbor-notary-server
servicePort: 4443
path: /
tls:
- hosts:
- core-harbor.xxxx.com
secretName: ingress-secret2023