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

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