Kubernetes ConfigMap 整理

2018/09/20 Kubernetes

前言

许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。这些配置信息需要与 docker image 解耦,你总不能每修改一个配置就重做一个 image 吧?ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。

官方用一句话描述了 ConfigMap 的作用

ConfigMap holds configuration data for pods to consume.

ConfigMap为pods保存配置数据

创建 ConfigMap

创建 ConfigMap 的方式有两种,一种是通过 yaml 文件来创建,另一种是通过kubectl 直接在命令行下创建。

我们先来看第一种,在 yaml 文件中,配置文件以 key-value 键值对的形式保存,当然也可以直接放一个完整的配置文件,在下面的示例中定义了一个名为 web-configmap.yaml,其中 server_port、server_name、server_home 就是 key-value 的键值对。

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-configmap
data:
  server_port: "80"
  server_name: codegreen.cn
  server_home: /data/web/html

创建 ConfigMap

$ kubectl apply -f web-configmap.conf 
configmap/web-configmap created

查看 ConfigMap 的信息

$ kubectl get configmap
NAME            DATA      AGE
web-configmap   3         6s

# 查看详细信息
$ kubectl describe configmap web-configmap
Name:         web-configmap
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","data":{"server_home":"/data/web/html","server_name":"codegreen.cn","server_port":"80"},"kind":"ConfigMap","metadata":{"annotations"...

Data
====
server_home:  # 这个就是我们定义的 key
----
/data/web/html # 这个是 server_home 的 value
server_name:
----
codegreen.cn
server_port:
----
80
Events:  <none>

第二种方式是直接使用 kubectl 在命令行创建 ConfigMap

直接将一个配置文件创建为一个ConfigMap:

# 我们先创建一个 www.conf 的文件作为 nginx 的配置文件
$ vim  www.conf 
server {
    listen 80;
    server_name myapp.codegreen.cn;
    index index.html;

    location / {
        root /data/web/html;
    }
}

将 www.conf 创建为 ConfigMap:

$ kubectl create configmap nginx-config --from-file=./www.conf
configmap/nginx-config created

# 查看 ConfigMap
$ kubectl get configmap
NAME            DATA      AGE
nginx-config    1         5s
web-configmap   3         34m

# 查看详细信息
$ kubectl describe configmap nginx-config
Name:         nginx-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
www.conf:
----
server {
    listen 80;
    server_name myapp.codegreen.cn;
    index index.html;

    location / {
        root /data/web/html;
    }
}

Events:  <none>

**注意:在将文件创建为 ConfigMap 时,如果没有给 key 的名字,那么文件的名字将作为 key 文件内部的内容将作为 value。在上面的例子中 www.conf 就是 key **

在使用 kubectl 创建的时候,通过在命令行直接传递键值对创建:

$ kubectl create configmap db-info --from-literal=db.host=192.168.1.10 --from-literal=db.port="3306"
configmap/db-info created

$ kubectl get configmap
NAME            DATA      AGE
db-info         2         9s
nginx-config    1         5m
web-configmap   3         40m

$ kubectl describe configmap db-info
Name:         db-info
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
db.host:
----
192.168.1.10
db.port:
----
3306
Events:  <none>

使用 ConfigMap

使用 ConfigMap 有两种方式,一种是通过环境变量的方式,直接传递pod,另一种是使用 volume 的方式挂载入到 pod 内。

第一种方式示例:

创建 ConfigMap :

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-configmap
data:
  server_port: "80"
  server_name: codegreen.cn
  server_home: /data/web/html

示例使用环境变量的方式将 ConfigMap 传递给 Pod:

$ vim pod-env-configmap.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-env-configmap
spec:
  containers:
  - name: nginx 
    image: nginx:1.8.1 
    imagePullPolicy: IfNotPresent
    env:
    - name: NGINX_SERVER_PORT # 定义的环境变量名
      valueFrom:
        configMapKeyRef:
          name: web-configmap # 这个是我们创建 ConfigMap 的名字
          key: server_port # ConfigMap 中的一个 key
    - name: NGINX_SERVER_NAME
      valueFrom:
        configMapKeyRef:
          name: web-configmap
          key: server_name
    - name: NGINX_SERVER_HOME
      valueFrom:
        configMapKeyRef:
          name: web-configmap
          key: server_home

创建 Pod

$ kubectl apply -f pod-env-configmap.yaml 
pod/pod-env-configmap created

# 我们进入到Pod内打印我们定义的三个环境变量看看 value 是否是 ConfigMap 中定义的
$ kubectl exec -it pod-env-configmap bash
root@pod-env-configmap:/# echo ${NGINX_SERVER_PORT} ${NGINX_SERVER_HOME} ${NGINX_SERVER_NAME}
80 /data/web/html codegreen.cn

第二种方式示例

这次直接将文件创建成为 ConfigMap

$ cat www.conf 
server {
    listen 80;
    server_name myapp.codegreen.cn;
    index index.html;

    location / {
        root /data/web/html;
    }
}

创建 ConfigMap

$ kubectl create configmap nginx-www --from-file=./www.conf 
configmap/nginx-www created

$ kubectl get configmap
NAME        DATA      AGE
nginx-www   1         5s

$ kubectl describe configmap nginx-www
Name:         nginx-www
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
www.conf:
----
server {
    listen 80;
    server_name myapp.codegreen.cn;
    index index.html;

    location / {
        root /data/web/html;
    }
}

Events:  <none>

创建 Pod 里面运行 Nginx 程序,并将上面的 ConfigMap 以 Volume 的方式挂载至容器内,作为 Nginx 的虚拟主机配置:

$ pod-volume-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-configmap
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.8.1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: nginxconf
      mountPath: /etc/nginx/conf.d/
  volumes:
  - name: nginxconf
    configMap:
      name: nginx-www

创建 Pod

$ kubectl apply -f pod-volume-configmap.yaml 
pod/pod-volume-configmap created

我们进入到容器内看看我们定义 ConfigMap 是否被注入到容器内并且为虚机主机的配置文件:

$ kubectl exec -it pod-volume-configmap bash
root@pod-volume-configmap:/# cd /etc/nginx/conf.d/
root@pod-volume-configmap:/etc/nginx/conf.d# ls
www.conf
root@pod-volume-configmap:/etc/nginx/conf.d# cat www.conf 
server {
    listen 80;
    server_name myapp.codegreen.cn;
    index index.html;

    location / {
        root /data/web/html;
    }
}

# 为这个虚拟主机创建一个默认首页
root@pod-volume-configmap:/etc/nginx/conf.d# mkdir -p /data/web/html
root@pod-volume-configmap:/etc/nginx/conf.d# echo "My Volume ConfigMap" > /data/web/html/index.html

退出容器然后配置 /etc/hosts 添加 myapp.codegreen.cn 的解析到 Pod IP 上去

-w1187

接下来我们请求这个域名

-w891

Search

    Table of Contents