在正式環境中的產品開發中,大多人都會遇到不同環境的佈署,最簡單的會被分成開發環境(Development)以及正式環境(Production),這時區分這些環境的關鍵往往是連線的資料庫或是使用的 Token 、 ApiKey 或是初始化資料等等,這些被抽離出來的設定(Configuration)很好的降低了程式碼的耦合,讓我們只需要簡單的編輯一下相關設定檔即可創造出我們想要的相對環境,而 Kubernetes
提供了 ConfigMap
讓我們可以從最頂層方便的向下注入。
基本上 ConfigMap
可以理解為存放設定檔的功能,也就是說這個物件可以直接連接一個或多個檔案,在我們程式中需要的地方可以使其被取用。
ConfigMap
物件可以存入一個或多個設定檔。ConfigMap
即可切換不同環境。Kubernetes
中可以統一查看以及管理。簡單介紹建立一個 ConfigMap
的幾種方式:
# initdb.sql
DROP TABLE IF EXISTS posts CASCADE;
CREATE TABLE posts
(
id BIGSERIAL PRIMARY KEY,
uuid VARCHAR(36) NOT NULL UNIQUE,
user_id NUMERIC NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
comments_count NUMERIC DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP NULL
);
CREATE INDEX user_id_key ON posts (user_id);
COMMENT ON COLUMN posts.title IS '標題';
COMMENT ON COLUMN posts.content IS '內容';
COMMENT ON COLUMN posts.comments_count IS '評論數';
kubectl create configmap pg-initsql --from-file=initdb.sql
--------
configmap/pg-initsql createdg-initsql
利用 kubectl create
指令將整個檔案設定成一個 configMap
查看一下產生結果:
kubectl describe configmap pg-initdb
---------
Name: pg-initdb
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
initdb.sql:
----
DROP TABLE IF EXISTS posts CASCADE;
CREATE TABLE posts
(
id BIGSERIAL PRIMARY KEY,
uuid VARCHAR(36) NOT NULL UNIQUE,
user_id NUMERIC NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
comments_count NUMERIC DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP NULL
);
CREATE INDEX user_id_key ON posts (user_id);
COMMENT ON COLUMN posts.title IS '標題';
COMMENT ON COLUMN posts.content IS '內容';
COMMENT ON COLUMN posts.comments_count IS '評論數';
BinaryData
====
kubectl create configmap pg-connect \
--from-literal=host=127.0.0.1 \
--from-literal=port=5432
以上我們使用指令建立 host
port
兩組 key-value。
查看一下結果:
kubectl describe configmap pg-connect
----------
Name: pg-connect
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
host:
----
127.0.0.1
port:
----
5432
BinaryData
====
# initdb-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: initdb-yaml
labels:
app: db
data:
initdb.sql: |
DROP TABLE IF EXISTS posts CASCADE;
CREATE TABLE posts
(
id BIGSERIAL PRIMARY KEY,
uuid VARCHAR(36) NOT NULL UNIQUE,
user_id NUMERIC NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
comments_count NUMERIC DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP NULL
);
CREATE INDEX user_id_key ON posts (user_id);
COMMENT ON COLUMN posts.title IS '標題';
COMMENT ON COLUMN posts.content IS '內容';
COMMENT ON COLUMN posts.comments_count IS '評論數';
kubectl apply -f initdb-configmap.yaml
---------
configmap/post-initdb-yaml created
查看一下結果:
kubectl describe configmap initdb-yaml
---------
Name: initdb-yaml
Namespace: default
Labels: app=db
Annotations: <none>
Data
====
initdb.sql:
----
DROP TABLE IF EXISTS posts CASCADE;
CREATE TABLE posts
(
id BIGSERIAL PRIMARY KEY,
uuid VARCHAR(36) NOT NULL UNIQUE,
user_id NUMERIC NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
comments_count NUMERIC DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP NULL
);
CREATE INDEX user_id_key ON posts (user_id);
COMMENT ON COLUMN posts.title IS '標題';
COMMENT ON COLUMN posts.content IS '內容';
COMMENT ON COLUMN posts.comments_count IS '評論數';
BinaryData
====
# initdb-kv.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: initdb-kv-yaml
labels:
app: db
data:
PG_USER: postgres
PG_PASSWORD: postgres
查看一下結果:
kubectl describe configmap initdb-kv-yaml
--------
Name: initdb-kv-yaml
Namespace: default
Labels: app=db
Annotations: <none>
Data
====
PG_PASSWORD:
----
postgres
PG_USER:
----
postgres
BinaryData
====
# pg-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: db
labels:
app: db
spec:
containers:
- name: db
image: postgres:12.4-alpine
env:
# 使用 configmap 的 key-value 做為值傳入
- name: POSTGRES_USER
valueFrom:
configMapKeyRef:
name: initdb-kv-yaml
key: PG_USER
- name: POSTGRES_PASSWORD
valueFrom:
configMapKeyRef:
name: initdb-kv-yaml
key: PG_PASSWORD
- name: PGDATA
value: '/var/lib/postgresql/data/pgdata'
- name: POSTGRES_DB
value: 'posts'
ports:
- containerPort: 5432
volumeMounts:
# 使用 configmap 做為 file 當作初始化設定
- mountPath: /docker-entrypoint-initdb.d
name: initdb
volumes:
- name: initdb
configMap:
name: initdb
---
apiVersion: v1
kind: ConfigMap
metadata:
name: initdb
labels:
app: db
data:
initdb.sql: |
DROP TABLE IF EXISTS posts CASCADE;
CREATE TABLE posts
(
id BIGSERIAL PRIMARY KEY,
uuid VARCHAR(36) NOT NULL UNIQUE,
user_id NUMERIC NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
comments_count NUMERIC DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP NULL
);
CREATE INDEX user_id_key ON posts (user_id);
COMMENT ON COLUMN posts.title IS '標題';
COMMENT ON COLUMN posts.content IS '內容';
COMMENT ON COLUMN posts.comments_count IS '評論數';
---
apiVersion: v1
kind: ConfigMap
metadata:
name: initdb-kv-yaml
labels:
app: db
data:
PG_USER: PG_USER
PG_PASSWORD: PG_USER
kubectl apply -f pg-pod.yaml,initdb-kv.yaml
-----------
pod/db created
configmap/initdb created
configmap/initdb-kv-yaml unchanged
在上面的設定中我們同時利用的 ConfigMap
的檔案掛載以及 key-value 掛載,設定了我們的 postgres
初始化資料表以及使用者帳號密碼。
接下來我們來驗證一下是否設定都已成功注入到 postgres
中:
kubectl exec -it db -- sh
ls
---------
bin etc media proc sbin tmp
dev home mnt root srv usr
docker-entrypoint-initdb.d lib opt run sys var
成功進入 postgres
即可使用 psq cli 操作。
cat docker-entrypoint-initdb.d/initdb.sql
---------
DROP TABLE IF EXISTS posts CASCADE;
CREATE TABLE posts
(
id BIGSERIAL PRIMARY KEY,
uuid VARCHAR(36) NOT NULL UNIQUE,
user_id NUMERIC NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
comments_count NUMERIC DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP NULL
);
CREATE INDEX user_id_key ON posts (user_id);
COMMENT ON COLUMN posts.title IS '標題';
COMMENT ON COLUMN posts.content IS '內容';
COMMENT ON COLUMN posts.comments_count IS '評論數';
成功獲得 ConfigMap
檔案。
在剛剛的 postgres
容器中,使用 psql cli 登入:
psql -U PG_USER -d posts
-------
psql (12.4)
Type "help" for help.
posts=#
成功以我們設定的帳號名稱 PG_USER
以及資料庫 posts
登入。
posts=# \d posts
Table "public.posts"
Column | Type | Collation | Nullable | Default
----------------+-----------------------------+-----------+----------+-----------------------------------
id | bigint | | not null | nextval('posts_id_seq'::regclass)
uuid | character varying(36) | | not null |
user_id | numeric | | not null |
title | character varying(255) | | not null |
content | text | | not null |
comments_count | numeric | | | 0
created_at | timestamp without time zone | | not null | now()
updated_at | timestamp without time zone | | not null | now()
deleted_at | timestamp without time zone | | |
Indexes:
"posts_pkey" PRIMARY KEY, btree (id)
"posts_uuid_key" UNIQUE CONSTRAINT, btree (uuid)
"user_id_key" btree (user_id)
大功告成~
今天我們實作了 ConfigMap
最常見的兩種使用方式,在官方文件中 ConfigMap
還有其他更進階的操作方式,這裡就先簡單介紹可以應付多數應用場景的方法。
千呼萬喚始出來!鐵人賽系列「從異世界歸來發現只剩自己不會 Kubernetes」同名改編作品出版了!
感謝所有交流指教的各路英雄,也感謝願意點閱文章的各位,如果能幫助到任何人都將會是我的榮幸。
本書內容改編自第 14 屆 iThome 鐵人賽 DevOps 組的優選系列文章《從異世界歸來發現只剩自己不會 Kubernetes》。此書是一本綜合性的指南,針對想要探索認識 Kubernetes 的技術人員而生。無論是初涉此領域的新手,還是已有深厚經驗的資深工程師,本書都能提供你所需的知識和技能。
「這本書不僅提供了豐富的範例程式碼和操作指南,讓身為工程師的我們能實際操作來加深認知;更重要的是,它教會我如何從後端工程師的角度去思考和應用 Kubernetes。從容器的生命週期、資源管理到部署管理,每一章都與我們的日常開發工作息息相關。」
──── 雷N │ 後端工程師 / iThome 鐵人賽戰友
天瓏連結: 從異世界歸來發現只剩自己不會 Kubernetes:初心者進入雲端世界的實戰攻略!
相關文章:
相關程式碼同時收錄在:
https://github.com/MikeHsu0618/2022-ithelp/tree/master/Day18
Reference
[Day 18] 高彈性部署 Application - ConfigMap
Kubernetes 那些事 — ConfigMap 與 Secrets
在"建立 ConfigMap", "1. 用指令匯入整個檔案 :",執行"kubectl create configmap pg-initsql --from-file=initdb.sql", 但是第二行kubectl describe configmap pg-initdb,不是"kubectl describe configmap pg-initsql"?
kubectl describe configmap initdb-kv-yaml 裏name: initdb-kv-yaml initdb-kv-yaml 是不是重複了?
請問pg-initdb, pg-connect, initdb-yaml到最後,是在那裏使用?
請問"實際應用 Config" 裏的"pg-pod.yaml":
apiVersion: v1
kind: ConfigMap
metadata:
name: initdb-kv-yaml
labels:
app: db
data:
PG_USER: PG_USER
PG_PASSWORD: PG_USER
這裏是引用initdb-kv-yaml 的使用名稱和密碼在create Pod和 ConfigMap裏使用?
在"4. 使用 yaml 檔建立 key-value:"漏了執行"kubectl apply -f initdb-kv-configmap.yaml" 去create configmap 指令
這裡主要介紹實務使用場景,感謝指正~initdb-kv-yaml
是用來將環境變數透過 configmap keyref 注入到容器當中。
env:
# 使用 configmap 的 key-value 做為值傳入
- name: POSTGRES_USER
valueFrom:
configMapKeyRef:
name: initdb-kv-yaml
key: PG_USER
- name: POSTGRES_PASSWORD
valueFrom:
configMapKeyRef:
name: initdb-kv-yaml
key: PG_PASSWORD