Kubernetes学习笔记(六):使用ConfigMap和Secret配置应用程序

概述#

本文的核心是:如何处理应用程序的数据配置。
配置应用程序可以使用以下几种途径:

  • 向容器传递命令行参数
  • 为每个容器配置环境变量
  • 通过特殊的卷将配置文件挂载到容器中

向容器传递命令行参数#

在Kubernetes中定义容器时,镜像的ENTRYPOINT和CMD都可以被覆盖(但是在Docker中,镜像的ENTRYPOINT是不能覆盖的)。仅需在容器定义中设置command和args的值。

构建一个镜像#

loopechodate.sh:接收一个时间间隔的参数,追加输出当前时间到 /tmp/a.txt

Copy
#! /bin/sh trap "exit" SIGINT echo "interval is : $1" while : do echo -e "$(date)" >> /tmp/a.txt sleep $1 done

Dockerfile

Copy
FROM alpine COPY loopechodate.sh /bin/ ENTRYPOINT ["/bin/loopechodate.sh"] CMD ["5"]

构建、推送

Copy
-> [root@kube0.vm] [~] docker build -t registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate . -> [root@kube0.vm] [~] docker push registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate

运行Pod#

Copy
# cat config-cli.yaml apiVersion: v1 kind: Pod metadata: name: config-cli spec: containers: - name: config-cli image: registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate args: ["2"] # 间隔时间2s

创建这个pod,然后查看一下logs

Copy
-> [root@kube0.vm] [~] k create -f config-cli.yaml pod/config-cli created -> [root@kube0.vm] [~] k exec -it config-cli cat /tmp/a.txt Sun May 24 15:49:37 UTC 2020 Sun May 24 15:49:39 UTC 2020

为容器设置环境变量#

Kubernetes中通过容器的env属性定义环境变量,采用$(VAR)语法在环境变量值中引用其他变量。

定义了两个环境变量FIRST_VAR,和引用了FIRST_VAR的SECOND_VAR。

Copy
# config-env.yaml apiVersion: v1 kind: Pod metadata: name: config-env spec: containers: - name: config-env image: nginx:alpine env: - name: FIRST_VAR value: "Hello" - name: SECOND_VAR value: "$(FIRST_VAR) World!"

创建查看

Copy
-> [root@kube0.vm] [~] k create -f config-env.yaml pod/config-env created -> [root@kube0.vm] [~] k exec config-env env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=config-env FIRST_VAR=Hello SECOND_VAR=Hello World! .......

ConfigMap#

ConfigMap本质上是一个键值对,值可以使短字面量,也可以是文件

创建ConfigMap#

kubectl create configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run] [options]

kubectl create命令支持从字面量(--from-literal),文件、目录(--from-file)、以及环境变量文件(--from-env-file)创建。而且不同选项可以合并,但是--from-env-file不能与--from-literal和--from-file一起指定。

下面是使用字面量、文件、目录合并创建。

Copy
-> [root@kube0.vm] [~] k create configmap mycm --from-literal=interval=3 --from-file=Dockerfile --from-file=/root/configdir configmap/mycm created -> [root@kube0.vm] [~] k describe cm mycm Name: mycm Namespace: default Labels: <none> Annotations: <none> Data ==== Dockerfile: ---- FROM alpine COPY loopechodate.sh /bin/ ENTRYPOINT ["/bin/loopechodate.sh"] CMD ["5"] a.txt: ---- this is configdir/a.txt b.txt: ---- this is configdir/b.txt interval: ---- 3 Events: <none>

使用环境变量文件创建

Copy
-> [root@kube0.vm] [~] echo -e "env1=1111\nenv2=2222" | tee test.env env1=1111 env2=2222 -> [root@kube0.vm] [~] k create cm envcm --from-env-file=test.env configmap/envcm created -> [root@kube0.vm] [~] k describe cm envcm Name: envcm Namespace: default Labels: <none> Annotations: <none> Data ==== env1: ---- 1111 env2: ---- 2222 Events: <none>

传递ConfigMap条目作为环境变量#

定义一个Pod,引用了mycm中的两个key。

Copy
# config-env-cm.yaml apiVersion: v1 kind: Pod metadata: name: config-env-cm spec: containers: - name: config-env-cm image: nginx:alpine env: - name: INTERVAL valueFrom: configMapKeyRef: # 引用configMap中的内容 name: mycm # configMap的名字 key: interval # 引用哪个键 - name: ATXT valueFrom: configMapKeyRef: name: mycm key: a.txt

创建查看

Copy
-> [root@kube0.vm] [~] k create -f config-env-cm.yaml pod/config-env-cm created -> [root@kube0.vm] [~] k exec config-env-cm env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=config-env-cm INTERVAL=3 ATXT=this is configdir/a.txt ....

一次性传递ConfigMap所有条目作为环境变量#

Copy
# config-env-cmall.yaml apiVersion: v1 kind: Pod metadata: name: config-env-cmall spec: containers: - name: config-env-cmall image: nginx:alpine envFrom: - prefix: CONFIG_ configMapRef: name: mycm

创建查看

Copy
-> [root@kube0.vm] [~] k create -f config-env-cmall.yaml pod/config-env-cmall created -> [root@kube0.vm] [~] k exec config-env-cmall env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=config-env-cmall CONFIG_interval=3 CONFIG_Dockerfile=FROM alpine COPY loopechodate.sh /bin/ ENTRYPOINT ["/bin/loopechodate.sh"] CMD ["5"] CONFIG_a.txt=this is configdir/a.txt CONFIG_b.txt=this is configdir/b.txt ........

传递ConfigMap条目作为命令行参数#

containers.args无法直接引用ConfigMap,但是可以通过$(ENV_VAR_NAME)引用环境变量,间接引用ConfigMap。

Copy
# config-cli-cm.yaml apiVersion: v1 kind: Pod metadata: name: config-cli-cm spec: containers: - name: config-cli-cm image: registry.cn-hangzhou.aliyuncs.com/orzi/loopechodate env: - name: INTERVAL valueFrom: configMapKeyRef: name: mycm key: interval args: ["$(INTERVAL)"]

创建查看

Copy
-> [root@kube0.vm] [~] k create -f config-cli-cm.yaml pod/config-cli-cm created -> [root@kube0.vm] [~] k logs config-cli-cm interval is : 3 -> [root@kube0.vm] [~] k exec config-cli-cm cat /tmp/a.txt Mon May 25 05:11:14 UTC 2020 Mon May 25 05:11:17 UTC 2020 Mon May 25 05:11:20 UTC 2020

将ConfigMap条目暴露为卷#

环境变量和命令行参数作为配置值通常适用于变量值较短的场景。如果想暴露ConfigMap中配置文件,可以将ConfigMap或者其条目通过卷的形式挂载到容器。

Copy
# config-volume-cm.yaml apiVersion: v1 kind: Pod metadata: name: config-volume-cm spec: containers: - name: config-volume-cm image: nginx:alpine volumeMounts: - name: config mountPath: /tmp/mycm readOnly: true volumes: - name: config configMap: name: mycm

创建查看

Copy
-> [root@kube0.vm] [~] k create -f config-volume-cm.yaml pod/config-volume-cm created -> [root@kube0.vm] [~] k exec config-volume-cm ls /tmp/mycm Dockerfile a.txt b.txt interval

如果只想暴露指定的条目,可以指定volumes.configMap.items

Copy
volumes: - name: config configMap: name: mycm items: - key: interval path: interval2

输出结果是:

Copy
-> [root@kube0.vm] [~] k exec config-volume-cm ls /tmp/mycm interval2

configMap.defaultMode设置访问权限

挂载文件夹会隐藏该文件夹中已存在的文件,挂载ConfigMap的单独条目不会隐藏其他文件

Secret#

Secret与ConfigMap一样都是键值对,也可以作为环境变量传递给容器,条目也能暴露称为卷中的文件。但是为了安全起见,请始终使用Secret卷暴露Secret。Secret只会存储在内存中,永不写入物理存储。Secret条目的内容会被进行Base64编码。

默认令牌#

每个pod默认都会挂载一个Secret,该Secret包含ca.crt、namespace、token,包含了从Pod内部安全访问Kubernetes Api服务器所需的全部信息。
先随便找一个pod查看。

Copy
-> [root@kube0.vm] [~] k describe pod config-volume-cm Name: config-volume-cm Namespace: default ...... Mounts: /tmp/mycm from config (ro) /var/run/secrets/kubernetes.io/serviceaccount from default-token-5g447 (ro) ...... Volumes: ...... default-token-5g447: Type: Secret (a volume populated by a Secret) SecretName: default-token-5g447 Optional: false ......

再查看一下详情

Copy
-> [root@kube0.vm] [~] k describe secrets default-token-5g447 Name: default-token-5g447 Namespace: default Labels: <none> Annotations: kubernetes.io/service-account.name: default kubernetes.io/service-account.uid: bd92a729-ed0a-491d-b600-0f86824ad588 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1025 bytes namespace: 7 bytes token: eyJhbGciOiJSUzI1....

使nginx支持https#

创建私钥和证书#

Copy
-> [root@kube0.vm] [~/cert] openssl genrsa -o https.key 2048 -> [root@kube0.vm] [~/cert] openssl req -new -x509 -key https.key -out https.cert -days 3650 -subj /CN=www.mysecret.com

创建Secret#

创建一个类型为generic的Secret,其他两个类型是docker-registry、tls。

Copy
-> [root@kube0.vm] [~/cert] echo bar > foo # 后面会用到 -> [root@kube0.vm] [~/cert] k create secret generic mysecret --from-file=./ secret/mysecret created

将ssl.conf放入ConfigMap中#

Copy
# ssl.conf server { listen 80; listen 443 ssl; server_name www.mysecret.com; ssl_certificate certs/https.cert; ssl_certificate_key certs/https.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; location / { root /usr/share/nginx/html; index index.html index.htm; } }
Copy
-> [root@kube0.vm] [~] k create configmap sslcm --from-file=ssl.conf configmap/sslcm created

创建查看#

先看一下描述文件

Copy
# https-nginx.yaml apiVersion: v1 kind: Pod metadata: name: https-nginx spec: containers: - name: https-nginx image: nginx:alpine env: - name: FOO valueFrom: secretKeyRef: name: mysecret key: foo volumeMounts: - name: sslcm mountPath: /etc/nginx/conf.d/ readOnly: true - name: mysecret mountPath: /etc/nginx/certs/ readOnly: true ports: - containerPort: 80 - containerPort: 443 volumes: - name: sslcm configMap: name: sslcm items: - key: ssl.conf path: https.conf - name: mysecret secret: secretName: mysecret

创建、设置端口转发

Copy
-> [root@kube0.vm] [~] k create -f https-nginx.yaml pod/https-nginx created -> [root@kube0.vm] [~] k port-forward https-nginx 443:443 Forwarding from 127.0.0.1:443 -> 443

新开窗口,发送请求

Copy
-> [root@kube0.vm] [~] curl -k https://localhost <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> .....

查看Secret通过环境变量暴露的条目

Copy
-> [root@kube0.vm] [~] k exec https-nginx env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=https-nginx FOO=bar .......

使用私有的镜像仓库#

使用方法:创建一个docker-registry类型的secret,然后

创建一个docker-registry类型的secret。 --docker-server 用于指定仓库服务的地址。

Copy
k create secret docker-registry dockerregsecret --docker-username=zhangsan --docker-password=123 --docker-email=zhangsan@163.com

在Pod中的containers.imagePullSecrets.name中引用。

Copy
apiVersion: v1 kind: Pod metadata: name: private-pod spec: imagePullSecrets: - name: dockerregsecret containers: - image: username/private:tag name: main

StringData与二进制数据#

采用Base64编码,使Secret也能存储二进制数据,而纯文本值可以在secret.StringData中定义,但StringData字段是只写的,kubectl get -o yaml查看时会被Base64编码显示在data下。

注意事项#

  • 在Kubernetes中定义容器时,镜像的ENTRYPOINT和CMD都可以被覆盖。但是在Docker中,镜像的ENTRYPOINT是不能覆盖的。
  • 可以将configMapKeyRef.optional设置为true,这样即使ConfigMap不存在,容器也能启动。

小结#

  • 对于环境变量:使用valueFrom.configMapKeyRef引用一个ConfigMap条目;使用envFrom.configMapRef引用全部,envFrom.prefix设置前缀。
  • 对于命令行参数:containers.args无法直接引用ConfigMap,但是可以通过$(ENV_VAR_NAME)引用环境变量,间接引用了ConfigMap。
  • 挂载文件夹会隐藏该文件夹中已存在的文件,挂载ConfigMap的单独条目不会隐藏其他文件
  • 将ConfigMap暴露为卷可以达到热更新的效果。
  • 每个pod默认都会挂载一个Secret,该Secret包含ca.crt、namespace、token,包含了从Pod内部安全访问Kubernetes Api服务器所需的全部信息。
  • 采用Base64编码,使Secret也能存储二进制数据,而纯文本值可以在secret.StringData中定义,但StringData字段是只写的,kubectl get -o yaml查看时会被Base64编码显示在data下。
posted @   虾敏四把刀  阅读(785)  评论(0编辑  收藏  举报
编辑推荐:
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示
CONTENTS