configmap是kubernetes的标准资源之一,有两种使用方式,第一种:以环境变量的方式,同secret。第二种:为应用创建配置文件,并以volume的方式挂载为文件到Pod中,应用程序可以像读普通文件一样读取挂载的配置文件。


变量的方式


以环境变量的方式注入到Pod中:

kubectl create configmap nginx-www \
--from-literal=server_port=80 \
--from-literal=server_name=www.app.com --dry-run -o yaml

--from-literal=变量名=变量值

yaml:

apiVersion: v1
data:
  server_name: www.app.com
  server_port: "80"
kind: ConfigMap
metadata:
  name: nginx-www

创建Pod:

apiVersion: v1
kind: Pod
metadata:
  name: config-key-val
  labels:
    tag1: key-val-test
spec:
  containers:
  - name: busybox
    image: busybox:1.12
    command: ["/bin/sh","-c","sleep 3600;"]
    env:
    - name: NGINX_SERVER_PORT
      valueFrom:
        configMapKeyRef:  # 引用configmap中的值
          name: nginx-www
          key: server_port
    - name: NGINX_SERVER_NAME
      valueFrom:
        configMapKeyRef:
          name: nginx-www
          key: server_name

        有些变量是可选的,可以加上这个选项来说明 spec.containers.env.valueFrom.configMapKeyRef.optional 值为true时表示必选,false表示可选。

查看变量:

[root@master configmap-key-val]# kubectl exec config-key-val -it -- /bin/sh
/ # env
NGINX_SERVER_PORT=80
NGINX_SERVER_NAME=www.app.com



文件的方式


以文件的方式挂载到Pod中:

kubectl create configmap nginx-config --from-file=nginx.conf --dry-run -o yaml

--from-file=配置文件名称=配置文件

--from-file=配置文件

yaml:

apiVersion: v1
data:
  nginx.conf: |
    server {
        server_name www.app.com;
        listen 80;
        root /data/web/html/;
    }
kind: ConfigMap
metadata:
  name: nginx-conf

创建Pod资源文件:将configmap资源挂载到 /conf/ 目录中。

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    command: ["sleep","3600"]
    volumeMounts:
    - name: nginx-conf
      mountPath: /conf/
  volumes:
  - name: nginx-conf
    configMap:
      name: nginx-conf

进入Pod中查看 /conf/ 目录可以看到挂载的配置文件

kubectl exec -it pod-configmap -- sh
~ # cat /conf/nginx.conf 
server {
    server_name www.app.com;
    listen 80;
    root /data/web/html/;
}

配置文件支持动态修改:修改configmap资源后过一段时间后可以看到挂载在Pod中配置文件也修改了。


将变量挂载成配置文件:

configmap资源文件:文件中定义了两个变量

apiVersion: v1
data:
  server_name: www.app.com
  server_port: "80"
kind: ConfigMap
metadata:
  name: nginx-conf

在Pod中挂载该configmap:

apiVersion: v1
kind: Pod
metadata:
  name: configmap
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    command: ["sleep","3600"]
    volumeMounts:
    - name: conf
      mountPath: /conf/  # 挂载到Pod中的这个目录
  volumes:
  - name: conf
    configMap: 
      name: nginx-conf

进入Pod查看配置文件:可以看到变量名称就是配置文件的名称,变量的值就是文件内容。

kubectl exec -it configmap -- sh
/ # ls /conf/
server_name  server_port
/ # cat /conf/server_name 
www.app.com

提示:如果修改了configmap资源中的配置过一会会自动更新到Pod中来实现动态修改配置文件。

修改配置:修改了server_name的值

kubectl edit configmaps nginx-conf

查看Pod中的配置:过一会后值已经被修改,且不用退出Pod。

/ # cat /conf/server_name 
www.app1.com/


subPath:如果直接将配置文件挂载到目录的话,挂载的目录会将原有目录中的内容都替换掉,subPath的作用就是只挂载这么一个文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
  labels:
    service: staging-nginx
  name: staging-nginx
  namespace: prod
spec:
  replicas: 1
  selector:
    matchLabels:
      service: staging-nginx
  strategy:
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        service: staging-nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: staging-nginx
        volumeMounts:
        - name: nginx-conf
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf # 挂载到这个文件
        ports:
        - containerPort: 80
          protocol: TCP
        resources:
          limits:
            cpu: "0"
            memory: 512Mi
          requests:
            cpu: "0"
            memory: 256Mi
      volumes:
      - name: nginx-conf
        configMap:
          name: staging-nginx-conf
---
apiVersion: v1
kind: Service
metadata:
  name: staging-nginx
  namespace: prod
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    service: staging-nginx
  sessionAffinity: None
  type: ClusterIP

获取Pod中自带的变量:可以获取PodIP、nodeIP等Pod字段的变量。

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
          printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
  restartPolicy: Never

官方文档:

https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/environment-variable-expose-pod-information/