AmazonRDS(MySQL), ElastiCache(Redis)と互換性のある環境をKubernetesに構築

# はじめに

AWSのマネージドサービスを活用してプログラム開発を行う時に、コスト面などを考慮しDevelop環境をlocalで用意する場合があります。

今回は、localのKubernetes環境上に、Amazon RDS, Amazon ElastiCacheと互換性のあるPodを作成します。



Amazon RDS の互換性のある MySQLのバージョン

- Aurora : 5.6.10a
- MySQL : 5.6.27 など



Amazon ElastiCache

- Redis : 4.0.10



# MySQL 事前準備

MySQLスキーマファイル作成のために、DockerImage起動

```
mkdir ~/sqldump
docker run --name pre --rm -d -it -v ~/sqldump/:/sqldump/ -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3306:3306 mysql:5.6.27 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
```



bash起動

```
docker exec -it pre bash
```



my.cnfファイルをコンテナからcopyする

```
mkdir ~/sqldump/
docker cp mysql:/etc/mysql/my.cnf ~/sqldump/
```



ファイルを編集し、文字コードをutf8にする

```
vim ~/mysql-local/my.cnf
```

```
[client]
default-character-set = utf8 #clientセクションを追加

[mysqld]
...
character-set-server = utf8 #mysqldセクションの末尾に追加
```



DockerImage作成

```
cat <<'EOF' > ~/sqldump/Dockerfile
FROM mysql:5.6.27

COPY my.cnf /etc/mysql/my.cnf
EOF

cd ~/sqldump/
docker build --tag=sugimount/temp:0.0.1 .
```



tempイメージの起動

```
docker run --name temp --rm -d -it -v ~/sqldump/:/sqldump/ -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3306:3306 sugimount/temp:0.0.1
```





外部からアクセス MySQLにアクセスするために、適当なサーバにClientをinstallします。

**DockerImageのMySQLバージョンと一致しているClientでないとアクセス出来ない場合がある**

```
yum localinstall http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm
yum -y install yum-utils
yum-config-manager --disable mysql57-community
yum-config-manager --enable mysql56-community
yum -y install mysql-community-client
```



clientのバージョン確認

```
[root@dockerhost ~]# mysql --version
mysql  Ver 14.14 Distrib 5.6.41, for Linux (x86_64) using  EditLine wrapper
```



スキーマやsampleデータを作成します 

**MySQLコンテナ上ではデフォルトでは入力出来ないので、マルチバイトを入力出来る外部のサーバからデータを格納します。**

```
mysql -h 127.0.0.1 -uroot -pmy-secret-pw -e "CREATE DATABASE qicoo;"

mysql -h 127.0.0.1 -uroot -pmy-secret-pw -e "CREATE TABLE qicoo.questions (
  id varchar(36) PRIMARY KEY,
  object text,
  event_id text,
  program_id text,
  username text,
  comment text,
  like_count int(10),
  created_at DATETIME,
  updated_at DATETIME,
  INDEX (event_id(40), program_id(40))
);"

mysql -h 127.0.0.1 -uroot -pmy-secret-pw -e "INSERT INTO qicoo.questions (
  id, object, event_id, program_id, username, comment, like_count, created_at, updated_at
)
VALUES(
  '00000000-0000-0000-0000-000000000000',
  'question',
  'jkd1812',
  '1',
  'sugimount',
  'KubernetesのRBACを教えてください',
  0,
  '2019-09-23 03:07:00',
  '2019-09-23 03:07:00'
);"

mysql -h 127.0.0.1 -uroot -pmy-secret-pw -e "INSERT INTO qicoo.questions (
  id, object, event_id, program_id, username, comment, like_count, created_at, updated_at
)
VALUES(
  '10000000-0000-0000-0000-000000000000',
  'question',
  'cndjp1902',
  '1',
  'hhiroshell',
  '世界を平和にする方法を教えてください',
  0,
  '2019-09-23 03:08:00',
  '2019-09-23 03:08:00'
);"


mysql -h 127.0.0.1 -uroot -pmy-secret-pw -e "CREATE TABLE qicoo.users (
  id varchar(37) PRIMARY KEY,
  user_session text,
  username text,
  type text,
  user_url text,
  created_at DATETIME,
  updated_at DATETIME
);"

mysql -h 127.0.0.1 -uroot -pmy-secret-pw -e "INSERT INTO qicoo.users (
  id, user_session, username, type, user_url, created_at, updated_at
)
VALUES(
  '00000000-0000-0000-0000-000000000000',
  'session_cokkie',
  'sugimount',
  'twitter',
  'https://twitter.com/sugimount',
  '2019-09-23 03:07:00',
  '2019-09-23 03:07:00'
);"

mysql -h 127.0.0.1 -uroot -pmy-secret-pw -e "INSERT INTO qicoo.users (
  id, user_session, username, type, user_url, created_at, updated_at
)
VALUES(
  '10000000-0000-0000-0000-000000000000',
  'session_cokkie',
  'hhroshell',
  'twitter',
  'https://twitter.com/hhroshell',
  '2019-09-23 03:08:00',
  '2019-09-23 03:08:00'
);"
```





bash起動

```
docker exec -it temp bash
```





mysqldumpを取得

```
mysqldump -uroot -pmy-secret-pw qicoo > /sqldump/qicoo-localdump.sql
exit
```



dumpファイルの編集

```
vim ~/sqldump/qicoo-localdump.sql
```



databasesの作成と使用を定義

```
-- MySQL dump 10.13  Distrib 5.6.27, for Linux (x86_64)
--
-- Host: localhost    Database: qicoo
-- ------------------------------------------------------
-- Server version   5.6.27

create database `qicoo`;
use `qicoo`;
```



DockerImage作成

```
cat <<'EOF' > ~/sqldump/Dockerfile
FROM mysql:5.6.27

COPY my.cnf /etc/mysql/my.cnf
COPY qicoo-localdump.sql /docker-entrypoint-initdb.d/qicoo-localdump.sql
EOF

cd ~/sqldump/
docker build --tag=sugimount/qicoo-local-mysql:0.0.1 .
```



DockerImageをUpload

```
docker login
docker push sugimount/qicoo-local-mysql:0.0.1
```



run

```
docker run --name mysql --rm -d -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3306:3306 sugimount/qicoo-local-mysql:0.0.1
docker exec -it mysql bash
```



# MySQL

KubernetesのSecretを作成するために、パスワード文字列を base64 で encode します

```
root@qicoo-k8s-master01(default kubernetes-admin):~# echo -n 'my-secret-pw' | base64
bXktc2VjcmV0LXB3
```



MySQLのパスワードを指定するSecretの作成。エンコードした文字列を使用します

```
cat <<'EOF' > ~/manifests/mysql_secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: dbsecret
type: Opaque
data:
  root_password: bXktc2VjcmV0LXB3
EOF
kubectl apply -f ~/manifests/mysql_secret.yaml
```



KubernetesにMySQL Deploymentを作成する

```
mkdir ~/manifests/
cat <<'EOF' > ~/manifests/mysql-local.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-local
spec:
  selector:
    matchLabels:
      app: mysql-local
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql-local
    spec:
      containers:
      - name: mysql-local
        image: sugimount/qicoo-local-mysql:0.0.1
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: dbsecret
              key: root_password
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 3306
      restartPolicy: Always
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: mysql-local
  name: mysql-local
spec:
  type: NodePort
  ports:
  - port: 3306
    targetPort: 3306
    nodePort: 30000
  selector:
    app: mysql-local
EOF
kubectl apply -f ~/manifests/mysql-local.yaml
```



作成したPodに入ると、環境変数がSETされていることがわかります

```
root@mysql-local-7848c8c777-458b4:/# env | grep PASS
MYSQL_ROOT_PASSWORD=my-secret-pw
```



外部からNodePort経由でMySQLに接続します

```
mysql -h 10.44.67.21 -P 30000 -u root -p
my-secret-pw
```





# Redis

Manifestファイルを作成

```
cat <<'EOF' > ~/manifests/redis-master.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-master
spec:
  selector:
    matchLabels:
      app: redis
      role: master
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: redis:4.0.10
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    app: redis
    role: master
    tier: backend
spec:
  type: NodePort
  ports:
  - port: 6379
    targetPort: 6379
    nodePort: 30001
  selector:
    app: redis
    role: master
    tier: backend
EOF
kubectl apply -f ~/manifests/redis-master.yaml
```



Kuberntes外部からRedisPodにアクセスします。そのために、client をinstallします

```
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```





remi repositoryをinstallします

```
vim /etc/yum.repos.d/remi.repo
```

```
enable = 1
```



installします

```
yum install redis-4.0.10-1.el7.remi
```





Kubernetes外部からPodにアクセスします

```
redis-cli -h 10.44.67.21 -p 30001
```



動作確認

```
10.44.67.21:30001> set a test
OK
10.44.67.21:30001> get a
"test"
```





# 参考URL

MySQL

https://qiita.com/hhiroshell/items/5e81cac3e9c059029837#1-1-mysql%E3%81%AEdocker%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E6%BA%96%E5%82%99



```
mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
```