k8s實踐8:容器應用配置文件管理利器configmap

1.
configMap的作用理解

configMap起什麼作用的呢?
舉個例子,啓用一個mysql容器.mysql容器重要的文件有兩部分,一部分爲存儲數據文件,一部分爲配置文件my.cnf.
存儲數據可以用pv pvc實現和容器的分離解耦,後面測試.
配置文件也能夠實現和容器的分離解耦,也就是說mysql容器能夠直接讀取並使用預先配置好的配置文件(而不是使用容器中默認自帶的配置文件).這就是configMap的功能.

kubernetes使用configMap來實現對容器中應用配置文件管理和分離解耦.

2.
創建configMap

有兩種方式:1.通過yaml文件創建
                    2.執行kubectl create命令,直接命令行創建.

示例:

命令行直接創建

[root@k8s-master1 configmap]# cat mysqld.cnf
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql

[mysqld_safe]
log-error= /var/log/mysql/mysql_oldboy.err
pid-file = /var/run/mysqld/mysqld.pid
[root@k8s-master1 configmap]#

創建configMap,使用mysqld.cnf的數據

[root@k8s-master1 configmap]# kubectl create configmap mysql-config --from-file=mysqld.cnf
configmap "mysql-config" created
[root@k8s-master1 configmap]# kubectl describe configmap mysql-config
Name:         mysql-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
mysqld.cnf:
----
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql

[mysqld_safe]
log-error= /var/log/mysql/mysql_oldboy.err
pid-file = /var/run/mysqld/mysqld.pid

Events:  <none>
[root@k8s-master1 configmap]#

yaml文件創建

[root@k8s-master1 configmap]# cat mysql-config2.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config2
data:
  mysqld.cnf: |
    [client]
    port = 3306
    socket = /var/run/mysqld/mysqld.sock
    [mysql]
    no-auto-rehash

    [mysqld]
    user = mysql
    port = 3306
    socket = /var/run/mysqld/mysqld.sock
    datadir = /var/lib/mysql

    [mysqld_safe]
    log-error= /var/log/mysql/mysql_oldboy.err
    pid-file = /var/run/mysqld/mysqld.pid
[root@k8s-master1 configmap]#

注意直接寫入文件內容的格式   mysqld.cnf: |

[root@k8s-master1 configmap]# kubectl apply -f mysql-config2.yaml
configmap "mysql-config2" created
[root@k8s-master1 configmap]# kubectl describe configmap mysql-config2
Name:         mysql-config2
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","data":{"mysqld.cnf":"[client]\nport = 3306\nsocket = /var/run/mysqld/mysqld.sock\n[mysql]\nno-auto-rehash\n\n[mysqld]\nuser = mysql...

Data
====
mysqld.cnf:
----
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql

[mysqld_safe]
log-error= /var/log/mysql/mysql_oldboy.err
pid-file = /var/run/mysqld/mysqld.pid

Events:  <none>
[root@k8s-master1 configmap]#

3.

configmap的使用

有兩種方式
   1.環境變量方式
   2.volume掛載方式(一般都是用這個,支持熱更新)

4.
環境變量方式

configmap支持key/value形式,一個條目一條數據,環境變量方式,用的是這個特性.
比如想在容器裏,預設環境變量.
示例:

創建configmap

[root@k8s-master1 configmap]# kubectl apply -f my-config.yaml
configmap "my-config" created
[root@k8s-master1 configmap]# cat my-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  v1: am
  v2: am123456
[root@k8s-master1 configmap]#

在容器中引用configmap裏的key當作變量

[root@k8s-master1 test]# cat configmap-test1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: t1
  namespace: default
spec:
  containers:
  - name: t1
    image: nginx
    env:
      - name: user
        valueFrom:
          configMapKeyRef:
            name: my-config
            key: v1
      - name: password
        valueFrom:
          configMapKeyRef:
            name: my-config
            key: v2
[root@k8s-master1 test]#

進pod,顯示變量

[root@k8s-master1 test]# kubectl exec -it t1 /bin/bash
root@t1:/# echo $user
am
root@t1:/# echo $password
am123456

5.
volume掛載方式

應用配置文件,使用這種方式.支持動態更新
用mysql示例,啓用一個mysql容器pod,通過configmap讀取預先配置好的配置文件.

configmap

用上面的mysql-config2

[root@k8s-master1 ~]# kubectl describe configmap mysql-config2
Name:         mysql-config2
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","data":{"mysqld.cnf":"[client]\nport = 3306\nsocket = /var/run/mysqld/mysqld.sock\n[mysql]\nno-auto-rehash\n\n[mysqld]\nuser = mysql...

Data
====
mysqld.cnf:
----
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql

[mysqld_safe]
log-error= /var/log/mysql/mysql_oldboy.err
pid-file = /var/run/mysqld/mysqld.pid

Events:  <none>
[root@k8s-master1 ~]#

volume方式使用configmap,見下:

[root@k8s-master1 test]# cat configmap-test2.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-t
spec:
  ports:
  - port: 3306
  selector:
    app: mysql-t
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: mysql-t
spec:
  selector:
    matchLabels:
      app: mysql-t
  template:
    metadata:
      labels:
        app: mysql-t
    spec:
      containers:
      - image: mysql:5.7
        name: mysql-t
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: v2
        volumeMounts:
        - name: mysql-t1
          mountPath: /etc/mysql/mysql.conf.d
      volumes:
      - name: mysql-t1
        configMap:
          name: mysql-config2
[root@k8s-master1 test]#

一些參數解釋:
volumeMounts/mountPath:    pod容器裏掛載目錄,這個目錄其實很重要,你要使用個容器的應用,需熟悉這個應用的配置文件存放目錄並且掛載到正確目錄.掛載目錄錯了容器應用無法讀取到配置文件.
volumes:  使用的卷
name: mysql-t1  注意volumes和volumeMounts的這個名字是相對應的.

[root@k8s-master1 test]# kubectl apply -f configmap-test2.yaml
service "mysql-t" created
deployment.apps "mysql-t" created
[root@k8s-master1 test]#

pod裏操作,可以看到讀取的就是mysql-config2,密碼已經生效.

[root@k8s-master1 test]# kubectl exec -it mysql-t-6fb9d4764d-rz8hv /bin/bash
root@mysql-t-6fb9d4764d-rz8hv:/# mysql -uroot -pam123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.25 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

看看pod的詳細信息

[root@k8s-master1 test]# kubectl describe pod mysql-t-6fb9d4764d-rz8hv
Name:               mysql-t-6fb9d4764d-rz8hv
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               k8s-master1/192.168.32.128
Start Time:         Thu, 28 Mar 2019 16:32:03 +0800
Labels:             app=mysql-t
                    pod-template-hash=6fb9d4764d
Annotations:        <none>
Status:             Running
IP:                 172.30.32.3
Controlled By:      ReplicaSet/mysql-t-6fb9d4764d
Containers:
  mysql-t:
    Container ID:   docker://fdf0631a4bc8b612ed0b3eea8b81106d497b5f8f39ee7e2ea1ce3d7f016a290a
    Image:          mysql:5.7
    Image ID:       docker-pullable://mysql@sha256:dba5fed182e64064b688ccd22b2f9cad4ee88608c82f8cff21e17bab8da72b81
    Port:           3306/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 28 Mar 2019 16:32:03 +0800
    Ready:          True
    Restart Count:  0
    Environment:
      MYSQL_ROOT_PASSWORD:  <set to the key 'v2' of config map 'my-config'>  Optional: false
    Mounts:
      /etc/mysql/mysql.conf.d from mysql-t1 (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-qmjrc (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  mysql-t1:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      mysql-config2
    Optional:  false
  default-token-qmjrc:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-qmjrc
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                  Message
  ----    ------     ----  ----                  -------
  Normal  Scheduled  3m    default-scheduler     Successfully assigned default/mysql-t-6fb9d4764d-rz8hv to k8s-master1
  Normal  Pulled     3m    kubelet, k8s-master1  Container image "mysql:5.7" already present on machine
  Normal  Created    3m    kubelet, k8s-master1  Created container
  Normal  Started    3m    kubelet, k8s-master1  Started container
[root@k8s-master1 test]#

具體用到的configmap,參考見下:

Environment:
      MYSQL_ROOT_PASSWORD:  <set to the key 'v2' of config map 'my-config'>  Optional: false
    Mounts:
      /etc/mysql/mysql.conf.d from mysql-t1 (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-qmjrc (ro) 

進這個目錄檢索看看

root@mysql-t-6fb9d4764d-rz8hv:/etc/mysql/mysql.conf.d# cat mysqld.cnf
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql

[mysqld_safe]
log-error= /var/log/mysql/mysql_oldboy.err
pid-file = /var/run/mysqld/mysqld.pid
root@mysql-t-6fb9d4764d-rz8hv:/etc/mysql/mysql.conf.d# pwd
/etc/mysql/mysql.conf.d

讀取的就是這個文件,configmap的掛載目錄.

6.

測試熱更新

更新mysql-config2
加上以下內容:
log_bin=mysql_bin
binlog-format=Row
server-id=1

用edit命令

[root@k8s-master1 configmap]# kubectl edit configmap mysql-config2
configmap "mysql-config2" edited
[root@k8s-master1 configmap]#
[root@k8s-master1 configmap]# kubectl describe configmap mysql-config2
Name:         mysql-config2
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","data":{"mysqld.cnf":"[client]\nport = 3306\nsocket = /var/run/mysqld/mysqld.sock\n[mysql]\nno-auto-rehash\n\n[mysqld]\nuser = mysql...

Data
====
mysqld.cnf:
----
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
log_bin=mysql_bin
binlog-format=Row
server-id=1

[mysqld_safe]
log-error= /var/log/mysql/mysql_oldboy.err
pid-file = /var/run/mysqld/mysqld.pid

Events:  <none>
[root@k8s-master1 configmap]#

pod裏查看結果

[root@k8s-master1 configmap]#  kubectl exec -it mysql-t-6fb9d4764d-rz8hv /bin/bash
root@mysql-t-6fb9d4764d-rz8hv:/# cat /etc/mysql/mysql.conf.d/mysqld.cnf
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
log_bin=mysql_bin
binlog-format=Row
server-id=1

[mysqld_safe]
log-error= /var/log/mysql/mysql_oldboy.err
pid-file = /var/run/mysqld/mysqld.pid
root@mysql-t-6fb9d4764d-rz8hv:/#

實現了熱更新.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章