文章目錄
將 ConfigMap 做為 Helm volume mount 的來源
有用過 container 的朋友相信對於 volume mount 有一定的了解,如果有用過 db 類型的 container (mysql、mongodb…) 對於透過 docker-entrypoint-initdb.d
來建立初始資料應該也不陌生,但相同機制在 Helm 中該如何實現呢?!
因為 Helm 只是用來管理 Kubernetes service 的工具,我才疏學淺不知道該如何正確將初始資料用的檔案隨著 Helm 部署,後來查到可以將設定內容存至 ConfigMap 中,再 mount 至 container 中,趁著印憶猶新趕緊紀錄一下,不然本來就沒有很了解前因後果,一定很快就忘了
基本環境說明
- macOS Mojave 10.15.2
- docker desktop community 2.2.0.0(42247)
- Docker Engine 19.03.5
- Kubernetes v1.15.5
- Helm v2.16.1
原始 helm (以 mysql 為例)
templates/deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "yowkochart.fullname" . }} labels: {{ include "yowkochart.labels" . | indent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app.kubernetes.io/name: {{ include "yowkochart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} template: metadata: labels: app.kubernetes.io/name: {{ include "yowkochart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 3306 protocol: TCP env: - name: MYSQL_ROOT_PASSWORD value: {{.Values.mysql.password}}
templates/service.yaml
apiVersion: v1 kind: Service metadata: name: {{ include "yowkochart.fullname" . }} labels: {{ include "yowkochart.labels" . | indent 4 }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: mysql selector: app.kubernetes.io/name: {{ include "yowkochart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }}
values.yaml
replicaCount: 1 image: repository: mysql tag: 5.7.28 pullPolicy: IfNotPresent service: type: ClusterIP port: 3306 mysql: password: pass.123
Chart.yaml
apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: yowkochart version: 0.1.0
僅有預設資料庫
設定方式
建立
ConfigMap
-templates/initial-configmap.yaml
sql script 內容請依實際需求自行調整
apiVersion: v1 kind: ConfigMap metadata: name: "mysql-init-configmap" data: init.sql: |- create database if not exists yowkodb; USE yowkodb; CREATE TABLE IF NOT EXISTS Users ( Id int auto_increment primary key, Name varchar(20) not null default '', Gender bool default 1 not null, DateUpdated datetime default current_timestamp() not null, DateCreated datetime default current_timestamp() not null ); ALTER TABLE Users AUTO_INCREMENT = 1001; INSERT INTO yowkodb.Users (Name, Gender) VALUES ('yowko', 1); INSERT INTO yowkodb.Users (Name, Gender) VALUES ('ann', 0);
修改
Deployment
-templates/deployment.yaml
以下是我多方嘗試得到的結果,如果有錯敬請指教
containers.volumeMounts.name
需要與volume.name
相同containers.volumeMounts.mountPath
需要指定到 file namecontainers.volumeMounts.subPath
與containers.volumeMounts.mountPath
的 file name 相同volumes.configMap.name
與templates/initial-configmap.yaml
的metadata.name
相同apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "yowkochart.fullname" . }} labels: {{ include "yowkochart.labels" . | indent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app.kubernetes.io/name: {{ include "yowkochart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} template: metadata: labels: app.kubernetes.io/name: {{ include "yowkochart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 3306 protocol: TCP env: - name: MYSQL_ROOT_PASSWORD value: {{.Values.mysql.password}} volumeMounts: - name: init-scripts mountPath: /docker-entrypoint-initdb.d/init.sql subPath: init.sql volumes: - name: init-scripts configMap: name: mysql-init-configmap
安裝測試
kubectl 指令中的 pod name 請依實際狀況調整
databases
語法
kubectl exec -it {pod name} -- mysql -h {mysql ip} -P {mysql port} -u root -p{密碼} -e "show databases"
範例
kubectl exec -it pod/mysql-yowkochart-5474d9dd57-hg2qg -- mysql -h 127.0.0.1 -P 3306 -u root -ppass.123 -e "show databases"
data
語法
kubectl exec -it {pod name} -- mysql -h {mysql ip} -P {mysql port} -u root -p{密碼} -e "select * from {db name}.{table name}"
範例
kubectl exec -it pod/mysql-yowkochart-5474d9dd57-hg2qg -- mysql -h 127.0.0.1 -P 3306 -u root -ppass.123 -e "select * from yowkodb.Users"
心得
雖然東拼西湊有達成想要的目標,但還是有些做法搞不清來龍去脈:
- 為什麼
mountPath
要加上 filename - 為什麼需要
subPath
另外我也不確定這是不是個好的方式,畢竟需要調整 initial script 的內容就變成要改 Helm Chart,我個人覺得 Helm Chart 只是簡化管理的工具,不適合把頻繁異動的內容往裡頭塞,如果後續異動頻率較高可能就得考慮其他做法了
參考資源
文章作者 Yowko Tsai
上次更新 2020-01-29
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。