例えばMySQLのDocker Hubイメージは/docker-entrypoint-initdb.dにあるファイルを起動時に読み込むようになっており、ここにSQLを書けばコンテナ起動と同時にデータベースやテーブルを作成したりできます。
ローカルのDockerで動かす場合、ローカルに書いたファイルをVolumeとしてマウントしてやれば良いですが、Kubernetesが実行される環境はローカルマシンではないのでそのようにファイルを渡すことができません。
一つの案として、mysqlイメージからFROMで派生した自作イメージのDockerfileを書くことでイメージにファイルを埋め込むことができます。
しかしイメージを作成するということはpushしてpullできる環境も用意しなきゃいけないということで若干めんどくなります。
オリジナルのmysqlイメージとKubernetesのシステムだけを使ってなんとかできないでしょうか。できます。
ConfigMap
ConfigMapはキーと値の対応を保存できるオブジェクトですが、値を「ファイルとして」コンテナにマウントすることができます。
以下はそれを使ってMySQLにコンテナ作成と同時にDB・テーブルを設定する例です。
Deployment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | apiVersion: apps/v1 kind: Deployment metadata: name: mysql-deployment spec: selector: matchLabels: component: mysql template: metadata: labels: component: mysql spec: # PodにVolumeを作ります volumes: - name: mysql-initdb-volume # ConfigMapから中身を作成します configMap: name: mysql-config # ConfigMapのkeyの中身をpathに配置します items: - key: init.sql path: init.sql containers: - name: mysql image: mysql:5.7 # mysqlコンテナに上で作ったVolumeをマウントします volumeMounts: - name: mysql-initdb-volume mountPath: /docker-entrypoint-initdb.d env: - name: MYSQL_ROOT_PASSWORD value: password # 実際はちゃんとsecret使ってください |
ConfigMap
1 2 3 4 5 6 7 8 9 10 11 12 13 | apiVersion: v1 kind: ConfigMap metadata: name: mysql-config data: init.sql: | CREATE DATABASE IF NOT EXISTS `app` DEFAULT CHARACTER SET utf8mb4; CREATE TABLE IF NOT EXISTS `app`.`users` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `name` varchar(255) NOT NULL ); |
こんな感じでConfigMapを使えば特定のファイルを読み込むことになっているイメージにファイルを与えることができます。