Kubernetes JobでMySQLへデータをロードする

[ICPにMySQLに接続するLibertyアプリケーションをデプロイ](https://qiita.com/sotoiwa/items/8ff88d1742e2b6443835)

の記事では、データのロードを`kubectl exec`でMySQLコンテナの中に入って実施したが、Kubenetes Jobでやる方法を確認したメモ。

以下の記事と同じようなことをやる。

[Kubernetes環境でCronJobでMySQLを定期的にバックアップ](https://qiita.com/sotoiwa/items/c33ed5c60e3fcadbd359)

## 初期化用コンテナの作成

実行するSQLはConfigMapに入れてもよいが、今回はイメージの中に含める。この例ではユーザーを作る部分でパスワードがsqlに入ってしまっているのであまりよろしくない。テンプレートとsecretで渡した環境変数からsqlを生成するか、MySQLのコンテナは環境変数`MYSQL_DATABASE`や`MYSQL_USER`と`MYSQL_PASSWORD`により、コンテナの初回起動時にデータベースを1つ作成したり、ユーザーをひとり作ることができるので、そちらでやるようにするのがよいと思う。

```sql:init.sql
create database mydb;
create user 'liberty' identified by 'liberty';
grant all privileges on mydb.* to 'liberty';
use mydb;
DROP TABLE IF EXISTS member;
CREATE TABLE `member` (
  id int NOT NULL AUTO_INCREMENT,
  name varchar(255) NOT NULL,
  created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
INSERT INTO member (name) VALUES ('user1'),('user2'),('user3');
INSERT INTO member (name) VALUES ('user4'),('user5'),('user6');
```

Dockerfileを作成する。

```dockerfile:Dockerfile
FROM mysql:5.7
COPY init.sql /
```

イメージをビルドしてDockerHubにPushする。

```
docker build -t sotoiwa540/hellomysql-init:1.0 .
docker push sotoiwa540/hellomysql-init:1.0
```

## Jobの作成

SQLを実行するJobを作成する。`command`と`args`の書き方が難しい。

```yaml:mysql-init-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: mysql-init
spec:
  template:
    spec:
      containers:
      - image: sotoiwa540/hellomysql-init:1.0
        name: init-hellomysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: root-password
        command: ["sh", "-c"]
        args: ["mysql -u root -p${MYSQL_ROOT_PASSWORD} -h mysql < init.sql"]
      restartPolicy: OnFailure
```

Jobを実行。

```
kubectl apply -f mysql-init-job.yaml -n sugi
```

Jobが作成したPodが完了したことを確認。

```shell-session
ubuntu@icp31-single:~/hellomysql$ kubectl get po -n sugi
NAME                     READY     STATUS      RESTARTS   AGE
mysql-7c47657796-bkc67   1/1       Running     0          2m
mysql-init-b9kqc         0/1       Completed   0          17s
ubuntu@icp31-single:~/hellomysql$
```

データがロードされていることを確認。

```shell-session
ubuntu@icp31-single:~/hellomysql$ kubectl exec -it mysql-7c47657796-bkc67 -n sugi bash
root@mysql-7c47657796-bkc67:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.23 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, 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> use mydb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT * from member;
+----+-------+---------------------+---------------------+
| id | name  | created             | updated             |
+----+-------+---------------------+---------------------+
|  1 | user1 | 2018-10-24 12:02:52 | 2018-10-24 12:02:52 |
|  2 | user2 | 2018-10-24 12:02:52 | 2018-10-24 12:02:52 |
|  3 | user3 | 2018-10-24 12:02:52 | 2018-10-24 12:02:52 |
|  4 | user4 | 2018-10-24 12:02:52 | 2018-10-24 12:02:52 |
|  5 | user5 | 2018-10-24 12:02:52 | 2018-10-24 12:02:52 |
|  6 | user6 | 2018-10-24 12:02:52 | 2018-10-24 12:02:52 |
+----+-------+---------------------+---------------------+
6 rows in set (0.01 sec)

mysql> quit
Bye
root@mysql-7c47657796-bkc67:/# exit
exit
ubuntu@icp31-single:~/hellomysql$
```