Kubernetes 配置管理 ConfigMap(十二)
一、背景
很多情況下我們為某一應用做好映象,當我們想修改其中的一些引數的時候,就變得比較麻煩,又要重新制作映象,我們是不是有一種方式,讓映象根據不同的場景呼叫我們不同的配置檔案呢,那我們就需要用到 k8s 的另外一種資源,那就是 ConfigMap。
我們知道,在幾乎所有的應用開發中,都會涉及到配置檔案的變更,比如說在web的程式中,需要連線資料庫,快取甚至是佇列等等。而我們的一個應用程式從寫第一行程式碼開始,要經歷開發環境、測試環境、預釋出環境只到最終的線上環境。而每一個環境都要定義其獨立的各種配置。如果我們不能很好的管理這些配置檔案,你的運維工作將頓時變的無比的繁瑣。為此業內的一些大公司專門開發了自己的一套配置管理中心,如360的Qcon,百度的disconf等。kubernetes也提供了自己的一套方案,即ConfigMap。kubernetes通過ConfigMap來實現對容器中應用的配置管理。
二、建立 ConfigMap
ConfigMap是用來儲存配置檔案的kubernetes資源物件,所有的配置內容都儲存在etcd中。
建立ConfigMap的方式有4種:
- 通過直接在命令列中指定configmap引數建立,即
--from-literal
; - 通過指定檔案建立,即將一個配置檔案建立為一個ConfigMap,
--from-file=<檔案>
; - 通過一個檔案內多個鍵值對,
--from-env-file=<檔案>
; - 事先寫好標準的configmap的yaml檔案,然後
kubectl create -f
建立。
2.1、通過 --from-literal
kubectl create configmap test-config1 --from-literal=db.host=172.18.8.200 --from-literal=db.port='3306'
檢視配置的內容。
[[email protected] ~]# kubectl get cm test-config1 -o yaml apiVersion: v1 data: db.host: 172.18.8.200 db.port: "3306" kind: ConfigMap metadata: creationTimestamp: "2018-12-16T04:32:42Z" name: test-config1 namespace: default resourceVersion: "3676" selfLink: /api/v1/namespaces/default/configmaps/test-config1 uid: a0ee762b-00eb-11e9-9fa7-000c291fb1b3
2.2、通過 --from-file
echo -n 172.18.8.200 > ./db.host
echo -n 3306 > ./db.port
kubectl create cm test-config2 --from-file=./db.host --from-file=./db.port
檢視配置內容:
[[email protected] ~]# kubectl get cm test-config2 -o yaml
apiVersion: v1
data:
db.host: 172.18.8.200
db.port: "3306"
kind: ConfigMap
metadata:
creationTimestamp: "2018-12-16T04:37:50Z"
name: test-config2
namespace: default
resourceVersion: "4107"
selfLink: /api/v1/namespaces/default/configmaps/test-config2
uid: 583ed4e7-00ec-11e9-9fa7-000c291fb1b3
每個檔案內容對應一個資訊條目。
2.3、通過--from-env-file
cat << EOF > env.txt
db.host=172.18.8.200
db.port=3306
EOF
kubectl create cm test-config3 --from-env-file=env.txt
檢視配置內容:
[[email protected] ~]# kubectl get cm test-config3 -o yaml
apiVersion: v1
data:
db.host: 172.18.8.200
db.port: "3306"
kind: ConfigMap
metadata:
creationTimestamp: "2018-12-16T04:43:02Z"
name: test-config3
namespace: default
resourceVersion: "4544"
selfLink: /api/v1/namespaces/default/configmaps/test-config3
uid: 12746e5f-00ed-11e9-9fa7-000c291fb1b3
2.4、YAML 配置檔案
配置檔案內容如下。
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config4
data:
db.host: 172.18.8.200
db.port: "3306"
建立並檢視其內容。
[[email protected] ~]# kubectl apply -f db.yaml
configmap/test-config4 created
[[email protected] ~]# kubectl get cm test-config4 -o yaml
apiVersion: v1
data:
db.host: 172.18.8.200
db.port: "3306"
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"db.host":"172.18.8.200","db.port":"3306"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test-config4","namespace":"default"}}
creationTimestamp: "2018-12-16T04:49:01Z"
name: test-config4
namespace: default
resourceVersion: "5045"
selfLink: /api/v1/namespaces/default/configmaps/test-config4
uid: e87cdafa-00ed-11e9-9fa7-000c291fb1b3
三、ConfigMap 使用
使用ConfigMap有二種方式:
- 第一種是通過環境變數的方式,直接傳遞給pod;
- 第二種是作為volume的方式掛載到pod內。
3.1、通過環境變數使用
使用valueFrom
、configMapKeyRef
、name
、key
指定要用的key。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
args: [ "/bin/sh", "-c", "sleep 3000" ]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: test-config4
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: test-config4
key: db.port
還可以通過envFrom
、configMapRef
、name
使得configmap中的所有key/value對都自動變成環境變數。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
args: [ "/bin/sh", "-c", "sleep 3000" ]
envFrom:
- configMapRef:
name: test-config3
3.2、作為volume掛載使用
把test-config4
所有key/value掛載進來:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
args: [ "/bin/sh", "-c", "sleep 3000" ]
volumeMounts:
- name: db
mountPath: "/etc/db"
readOnly: true
volumes:
- name: db
configMap:
name: test-config4
進入容器檢視,看到在db資料夾下以每一個key為檔名value為值建立了多個檔案。
[[email protected] ~]# kubectl exec -it mypod -- /bin/sh
/ # cd /etc/db
/etc/db # ls -al
total 0
drwxrwxrwx 3 root root 89 Dec 16 05:23 .
drwxr-xr-x 1 root root 16 Dec 16 05:23 ..
drwxr-xr-x 2 root root 36 Dec 16 05:23 ..2018_12_16_05_23_04.654058863
lrwxrwxrwx 1 root root 31 Dec 16 05:23 ..data -> ..2018_12_16_05_23_04.654058863
lrwxrwxrwx 1 root root 14 Dec 16 05:23 db.host -> ..data/db.host
lrwxrwxrwx 1 root root 14 Dec 16 05:23 db.port -> ..data/db.port
/etc/db # cat db.host
172.18.8.200/etc/db #
3.3、ConfigMap的熱更新
使用該 ConfigMap 掛載的 Env 不會同步更新;
使用該 ConfigMap 掛載的 Volume 中的資料需要一段時間(實測大概10秒)才能同步更新。
3.4、最佳使用方法
大多數情況下,配置資訊都以檔案形式提供,所以在建立 ConfigMap 時通常採用 --from-file 或 YAML 方式,讀取 ConfigMap 時通常採用 Volume 方式。
比如我們的 MySQL 配置檔案/etc/my.cnf
。
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
!includedir /etc/my.cnf.d
建立CongifMap。
kubectl create cm mysql-cm --from-file=/etc/my.cnf
檢視建立好的cm。
[[email protected] ~]# kubectl get cm mysql-cm -o yaml
apiVersion: v1
data:
my.cnf: |
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
!includedir /etc/my.cnf.d
kind: ConfigMap
metadata:
creationTimestamp: "2018-12-16T05:38:29Z"
name: mysql-cm
namespace: default
resourceVersion: "9273"
selfLink: /api/v1/namespaces/default/configmaps/mysql-cm
uid: d1201233-00f4-11e9-9fa7-000c291fb1b3
在 Pod 中使用此 ConfigMap,配置檔案為:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
args: [ "/bin/sh", "-c", "sleep 3000" ]
volumeMounts:
- name: mysql
mountPath: "/tmp"
volumes:
- name: mysql
configMap:
name: mysql-cm
items:
- key: my.cnf
path: mysql/my.cnf
建立 Pod 並讀取配置資訊:
[[email protected] ~]# kubectl exec -it mypod sh
/ # cat /tmp/mysql/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
!includedir /etc/my.cnf.d
/ # exit
關於掛在路徑大家可以自行進行修改。