K8s ConfigMaps与Secret实现配置分离过程
作者:大新屋
本文介绍Kubernetes中ConfigMaps和Secret的创建方式及应用,涵盖文件、literal、YAML方法,强调命名空间匹配与键名大小写一致性,Secret类型如Opaque、dockerconfigjson用于加密配置,热更新需注意envFrom等参数限制
- 提示:kubernetes 官方ConfigMaps文档说明:https://kubernetes.io/docs/concepts/configuration/configmap/
- 提示:kubernetes 官方Secret文档说明:https://kubernetes.io/docs/concepts/configuration/secret/
- 提示: ConfigMap和Secret引用Key必须存在,ConfigMaps主要用于明文的配置信息,Secret主要用于需要加密的配置信息,ConfigMap和Secret 配置信息不建议过多
- 提示:envFrom、valueFrom参数无法热更新环境变量,使用subrsth参数是无法热更新的
- 提示:ConfigMap支持的数据data和binaryData两种数据对象,data是UTF-8字符集,binaryData是二进制数据(base64编码的字符串)
一、ConfigMaps创建形式
1、基于文件创建ConfigMaps
### 创建ConfigMaps 配置信息 mkdir -p /data/yaml/configmap/conf cat > /data/yaml/configmap/conf/nginx01.config << 'EOF' nginx=1.24 user=nginx01 passwd=123456 EOF cat > /data/yaml/configmap/conf/nginx02.config << 'EOF' nginx=1.26 user=nginx02 password=123456 EOF ### 基于目录创建ConfigMaps kubectl create configmap nginx-cm01 --namespace=default --from-file=/data/yaml/configmap/conf ### 基于单个文件创建ConfigMaps kubectl create configmap nginx-cm02 --namespace=default --from-file=/data/yaml/configmap/conf/nginx01.config ### 基于多个文件创建ConfigMaps kubectl create configmap nginx-cm03 --namespace=default --from-file=/data/yaml/configmap/conf/nginx01.config --from-file=/data/yaml/configmap/conf/nginx02.config ### 自定义ConfigMaps data名称 kubectl create configmap nginx-cm04 --namespace=default --from-file=nginx-1.24=/data/yaml/configmap/conf/nginx01.config ### 查看ConfigMaps kubectl get configmap -n default kubectl get cm -n default kubectl get configmap nginx-cm01 -n default -oyaml kubectl get cm nginx-cm01 -n default -oyaml ### 删除ConfigMaps kubectl delete cm nginx-cm01 nginx-cm02 nginx-cm03 nginx-cm04 -n default
2、基于文件导入env创建ConfigMaps
### 创建ConfigMaps 配置信息 mkdir -p /data/yaml/configmap/conf cat > /data/yaml/configmap/conf/redis01.config << 'EOF' redis_version1=3.6 user1=redis01 passwd1=123456 EOF cat > /data/yaml/configmap/conf/redis02.config << 'EOF' redis_version2=4.6 user2=redis02 passwd2=123456 EOF ### 基于单个env文件创建ConfigMaps kubectl create cm redis-cm01 --namespace=default --from-env-file=/data/yaml/configmap/conf/redis01.config ### 基于多个env文件创建ConfigMaps kubectl create configmap redis-cm02 --namespace=default --from-env-file=/data/yaml/configmap/conf/redis01.config --from-env-file=/data/yaml/configmap/conf/redis02.config ### 查看ConfigMaps kubectl get cm -n default kubectl get cm redis-cm01 -n default –oyaml ### 删除ConfigMaps kubectl delete cm redis-cm01 redis-cm02 -n default
3、基于literal创建ConfigMaps
kubectl create cm nginx-literal -n default --from-literal=nginx_version=1.26 --from-literal=user=nginx01 --from-literal=password=123456 kubectl get cm -n default kubectl get cm nginx-literal -n default -oyaml
4、基于yaml文件创建ConfigMaps
cat > /data/yaml/configmap/configmap.yaml <<'EOF' apiVersion: v1 kind: ConfigMap metadata: name: game-demo namespace: default data: player_initial_lives: "3" ui_properties_file_name: "user-interface.properties" game.properties: | enemy.types=aliens,monsters player.maximum-lives=5 user-interface.properties: | color.good=purple color.bad=yellow allow.textmode=true EOF kubectl create -f /data/yaml/configmap/configmap.yaml ### 查看ConfigMaps kubectl get cm -n default kubectl get cm game-demo -n default –oyaml ### 删除ConfigMaps kubectl delete -f /data/yaml/configmap/configmap.yaml
二、Deployment应用ConfigMaps
注意:
.spec.containers.env.name参数值名称(大写字母)与.sepc.containers.env.valueFrom. configMapKeyRef.key参数值名称一样(小写字母),Deployment与ConfigMaps必须在同一个namespace命名空间下。
1、基于env.valueFrom单个环境变量创建ConfigMaps
### 创建ConfigMaps cat > /data/yaml/configmap/configmap.yaml <<'EOF' apiVersion: v1 kind: ConfigMap metadata: name: game-demo namespace: default data: player_initial_lives: "3" ui_properties_file_name: "user-interface.properties" game.properties: | enemy.types=aliens,monsters player.maximum-lives=5 user-interface.properties: | color.good=purple color.bad=yellow allow.textmode=true EOF kubectl create -f /data/yaml/configmap/configmap.yaml ### 创建Deployment并应用ConfigMap变量 cat > /data/yaml/configmap/nginx-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: nginx-deploy template: metadata: labels: app: nginx-deploy spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26 name: nginx env: - name: NginxVersion value: "1.26" - name: PLAYER_INITIAL_LIVES valueFrom: configMapKeyRef: name: game-demo key: player_initial_lives - name: UI_PROPERTIES_FILE_NAME valueFrom: configMapKeyRef: name: game-demo key: ui_properties_file_name EOF kubectl create -f /data/yaml/configmap/nginx-deploy.yaml ### 查看ConfigMap和Deployment kubectl get cm -n default kubectl get cm game-demo -n default -oyaml kubectl get deploy -n default -owide kubectl get pod -n default kubectl get deploy -n default -oyaml ### 进入Pod容器内查看环境变量 kubectl exec -it nginx-deploy-55c4bcc476-qrmcr -- bash env echo $NginxVersion echo $PLAYER_INITIAL_LIVES echo $UI_PROPERTIES_FILE_NAME
2、基于envFrom批量生成环境变量创建ConfigMaps
### 创建ConfigMaps cat > /data/yaml/configmap/configmap.yaml <<'EOF' apiVersion: v1 kind: ConfigMap metadata: name: game-demo namespace: default data: player_initial_lives: "3" ui_properties_file_name: "user-interface.properties" game.properties: | enemy.types=aliens,monsters player.maximum-lives=5 user-interface.properties: | color.good=purple color.bad=yellow allow.textmode=true EOF kubectl create -f /data/yaml/configmap/configmap.yaml ### ### 创建Deployment并应用ConfigMap变量(.template.spce.containers.envFrom.prefix参数是固定批量导入的每个变量都有一个自定义前缀,用于区分变量来源) cat > /data/yaml/configmap/redis-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: redis-deploy name: redis-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: redis-pod template: metadata: labels: app: redis-pod spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/redis:6.2.16 name: redis envFrom: - configMapRef: name: game-demo prefix: GAME-DEMO_ EOF kubectl create -f /data/yaml/configmap/redis-deploy.yaml ### 查看ConfigMap和Deployment kubectl get cm -n default kubectl get cm game-demo -n default -oyaml kubectl get deploy -n default -owide kubectl get pod -n default kubectl get deploy -n default -oyaml ### 查看Pod容器环境变量ENV kubectl exec -n default redis-deploy-f74fd777b-zx97k -- env
3、基于文件形式挂载ConfigMaps
### 创建ConfigMaps cat > /data/yaml/configmap/nginx-configmaps.yaml << 'EOF' apiVersion: v1 kind: ConfigMap metadata: name: nginx-configmap namespace: default data: nginx.conf: | user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 4096; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; include /etc/nginx/conf.d/*.conf; } EOF kubectl create -f /data/yaml/configmap/nginx-configmaps.yaml ### 创建Deployment并应用ConfigMaps ### .spec.containers.volumeMounts.subPath参数允许Pod容器内部将卷挂载到特定子目录或者挂载特定根目录文件,而不是直接挂载到卷的根目录 cat > /data/yaml/configmap/nginx-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26 name: nginx ports: - containerPort: 80 volumeMounts: - name: nginx-cm mountPath: /etc/nginx/nginx.conf subPath: nginx.conf volumes: - name: nginx-cm configMap: name: nginx-configmap EOF kubectl create -f /data/yaml/configmap/nginx-deploy.yaml ### 查看ConfigMap和Deployment kubectl get cm -n default kubectl get cm nginx-configmap -n default -oyaml kubectl get deploy -n default -owide kubectl get pod -n default kubectl get deploy -n default -oyaml ### 查看Pod容器生成的配置文件nginx.conf kubectl exec nginx-deploy-758875fd9d-pvh8x -- cat /etc/nginx/nginx.conf
三、Secret创建形式
1、Secret常用类型
- Opaque【常用】:通用型Secret,默认类型
- kubernetes.io/service-account-token:作用于ServiceAccount,包含一个令牌,用于标识API服务账户
- kubernetes.io/dockerconfigison【常用】:下载私有仓库镜像使用的Secret,和宿主风的/root/.docker/config.ison一致,宿主机登录后即可产生该文件
- kubernetes.io/basic-auth:用于使用基本认证(账号密码)的secret,可以使用Opaque取代
- kubernetes.io/ssh-auth:用于存储ssh密钥的Secret
- kubernetes.io/tls【常用】:用于存储HTTPS域名证书文件的Secret,可以被Ingress使用
- bootstrap.kubernetes.io/token:一种简单的bearer token,用于创建新集群或将新节点添加到现有集群,在集群安装时可用于自动颁发集群的证书
2、基于文件创建Secret
### ### 创建Secret 配置信息 mkdir -p /data/yaml/secret/conf cat > /data/yaml/secret/conf/username << 'EOF' admin EOF cat > /data/yaml/secret/conf/password << 'EOF' 123456 EOF ### 基于文件创建Secret,其中generic是Secret Opaque类型 kubectl create secret generic db-user-pass -n default --from-file=/data/yaml/secret/conf/username --from-file=/data/yaml/secret/conf/password ### 查看Secret,username和password内容显示已经过软加密处理 kubectl get secret -n default kubectl get secret db-user-pass -n default -oyaml ### 通过以下命令以明文方式显示username和password的加密内容 echo "YWRtaW4K" | base64 -d echo "MTIzNDU2Cg==" | base64 -d ### 删除Secret kubectl delete secret db-user-pass -n defalut
3、基于literal创建Secret
kubectl create secret generic use-pass-literal -n default --from-literal=username=admin --from-literal=password='123456 kubectl get secret -n default kubectl get secret use-pass-literal -n default -oyaml kubectl delete secret use-pass-literal -n default
4、基于yaml文件创建Secret
### 创建Secret(yaml文件密文显示,创建后Secret是密文) echo -n 'admin' | base64 echo -n '123456' | base64 cat > /data/yaml/secret/secret-once.yaml <<'EOF' apiVersion: v1 kind: Secret metadata: name: secret-once type: Opaque data: username: YWRtaW4= password: MTIzNDU2 EOF kubectl create -f /data/yaml/secret/secret-once.yaml kubectl get secret -n default kubectl get secret secret-once -n default -oyaml ### 创建Secret(yaml文件明文显示,创建后Secret是密文) cat > /data/yaml/secret/secret-twice.yaml <<'EOF' apiVersion: v1 kind: Secret metadata: name: secret-twice type: Opaque stringData: username: admin password: '123456' EOF kubectl create -f /data/yaml/secret/secret-twice.yaml kubectl get secret -n default kubectl get secret secret-twice -n default -oyaml
四、Deployment应用Secret
1、创建Secret(Secret类型:kubernetes.io/dockerconfigison)
使用场景:使用Secret拉取需要认证登录的私有仓库镜像,registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7 这个镜像源是作者登录阿里云申请创建的私有仓库并设置需要认证登录才可以拉取
### 创建Deployment并应用Secret cat > /data/yaml/secret/mysql-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: mysql-deploy name: mysql-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: mysql-pod template: metadata: labels: app: mysql-pod spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7 name: mysql env: - name: MYSQL_ROOT_PASSWORD value: "123456" ports: - containerPort: 3306 EOF kubectl create -f /data/yaml/secret/mysql-deploy.yaml ### 查看Pod状态显示ImagePullBackOff镜像拉取失败 kubectl get pods -n default ### 查看Pod描述信息, kubectl describe pods -n default mysql-deploy-8678f9bb6c-428ds ### 以下错误提示说明拉取registry.cn-shenzhen.aliyuncs.com/dockerghost/alpine:latest镜像失败,需要授权才能拉取 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 87s default-scheduler Successfully assigned default/mysql-deploy-8678f9bb6c-428ds to k8s-node03 Normal BackOff 21s (x5 over 85s) kubelet Back-off pulling image "registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7" Warning Failed 21s (x5 over 85s) kubelet Error: ImagePullBackOff Normal Pulling 7s (x4 over 86s) kubelet Pulling image "registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7" Warning Failed 7s (x4 over 86s) kubelet Failed to pull image "registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7": failed to pull and unpack image "registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7": failed to resolve reference "registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed ### 基于命令方式创建docker-registry类型的Secret,自定义的Secret名称aliyunregistry kubectl create secret -n default docker-registry aliyunregistry --docker-username=sys1873515692 --docker-password='yes#123' --docker-email=1873515692@qq.com --docker-server=registry.cn-shenzhen.aliyuncs.com ### 基于yaml文件创建docker-registry类型的Secret,自定义的Secret名称aliyunregistry kubectl create secret -n default docker-registry aliyunregistry --docker-username=sys1873515692 --docker-password='yes#123' --docker-email=1873515692@qq.com --docker-server=registry.cn-shenzhen.aliyuncs.com --dry-run=client -oyaml > /data/yaml/secret/mysql-secret.yaml cat > /data/yaml/secret/mysql-secret.yaml << 'EOF' apiVersion: v1 data: .dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5jbi1zaGVuemhlbi5hbGl5dW5jcy5jb20iOnsidXNlcm5hbWUiOiJzeXMxODczNTE1NjkyIiwicGFzc3dvcmQiOiJ5ZXMjMTIzIiwiZW1haWwiOiIxODczNTE1NjkyQHFxLmNvbSIsImF1dGgiOiJjM2x6TVRnM016VXhOVFk1TWpwNVpYTWpNVEl6In19fQ== kind: Secret metadata: creationTimestamp: null name: aliyunregistry namespace: default type: kubernetes.io/dockerconfigjson EOF kubectl create -f /data/yaml/secret/mysql-secret.yaml kubectl get secret -n default kubectl get secret aliyunregistry -n default -oyaml ### 修改Deployment yaml文件添加.spec.imagePullSecrets参数加载已创建的Secret(aliyunregistry)并重新应用加载 cat > /data/yaml/alpine-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: mysql-deploy name: mysql-deploy namespace: default spec: replicas: 1 selector: matchLabels: app: mysql-pod template: metadata: labels: app: mysql-pod spec: imagePullSecrets: - name: aliyunregistry containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/mysql:5.7 name: mysql env: - name: MYSQL_ROOT_PASSWORD value: "123456" ports: - containerPort: 3306 EOF kubectl apply -f /data/yaml/secret/mysql-deploy.yaml ### 查看Pod已正常创建 kubectl get deploy -n default kubectl get pods -n default
2、创建Secret(Secret类型:kubernetes.io/tls)
使用场景:使用Secret管理HTTPS证书,通过Ingress Controller调用Service和Secret,访问HTTPS Nginx服务
### 生成SSL证书 mkdir -p /data/yaml/secret/ssl openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout=/data/yaml/secret/ssl/tls.key -out=/data/yaml/secret/ssl/tls.crt -subj "/CN=test.com" ### 创建Secret类型:kubernetes.io/tls kubectl create secret tls nginx-secret-tls -n default --key=/data/yaml/secret/ssl/tls.key --cert=/data/yaml/secret/ssl/tls.crt ### 查看Secret kubectl get secret -n default kubectl get secret nginx-secret-tls -n default -oyaml ### 创建Deployment并应用Secret cat > /data/yaml/secret/nginx-deploy.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy name: nginx-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26 name: nginx ports: - containerPort: 80 EOF kubectl create -f /data/yaml/secret/nginx-deploy.yaml kubectl get pods -n default ### 创建Service cat > /data/yaml/secret/nginx-service.yaml << 'EOF' apiVersion: v1 kind: Service metadata: labels: app: nginx-service name: nginx-service namespace: default spec: selector: app: nginx-pod type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 80 EOF kubectl create -f /data/yaml/secret/nginx-service.yaml kubectl get services -n default curl http://10.96.17.21 ### 创建Ingress ### 注意:需要K8s集群安装Ingress Controller才能配置Ingress使用,并且Deployment、Secret、Ingress都要在同一个namespace命名空间下 cat > /data/yaml/secret/nginx-ingress.yaml << 'EOF' apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress namespace: default spec: ingressClassName: nginx rules: - host: nginx.test.com http: paths: - backend: service: name: nginx-service port: number: 80 path: / pathType: ImplementationSpecific tls: - hosts: - nginx.test.com secretName: nginx-secret-tls EOF kubectl create -f /data/yaml/secret/nginx-ingress.yaml kubectl get ingress -n default ### 客户端的hosts文件需要解析,解析填写 172.20.235.204 nginx.test.com,客户端打开浏览器访问 https://nginx.test.com
五、ConfigMap&Secret热更新
方法一:使用kubectl edit命令方式
### ConfigMap使用kubectl edit configmap kubectl edit configmap nginx-configmap ### Secret使用kubectl edit secret kubectl edit secret nginx-secret
方法二:修改yaml文件配置方式
kubectl replace -f /data/yaml/configmap/nginx-configmap.yaml
方法三:命令方式更新已创建ConfigMap&Secret
kubectl create configmap nginx-configmap --from-file=/data/yaml/configmap/nginx.conf --dry-run=client -oyaml | kubectl replace -f -
六、禁止修改ConfigMap&Secret配置
### 创建ConfigMap,添加immutable参数设置为true,可以使用ConfigMap和Secret配置不可以通过kubectl edit进行修改 cat > /data/yaml/configmap/configmap.yaml <<'EOF' apiVersion: v1 kind: ConfigMap metadata: name: game-demo namespace: default data: player_initial_lives: "3" ui_properties_file_name: "user-interface.properties" game.properties: | enemy.types=aliens,monsters player.maximum-lives=5 user-interface.properties: | color.good=purple color.bad=yellow allow.textmode=true immutable: true EOF kubectl create -f /data/yaml/configmap/configmap.yaml kubectl get configmap -n default kubectl get configmap game-demo -oyaml -n default ### 使用kubectl edit 修改configmap无效 kubectl edit configmap game-dem -n default kubectl get configmap game-demo -oyaml -n default
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。