【AWS】ECR + ECS + RDSを利用したDocker環境構築手順

インフラ

こんにちは。Enjoy IT Life管理人の仁科(@nishina555)です。

先日、自作したDockerイメージをECRにpushする方法についてAWS CLIをインストールし、ECRへDockerイメージをpushする手順で紹介しました。

AWS CLIをインストールし、ECRへDockerイメージをpushする手順

今回はDockerコンテナをAWS環境で実行するためのサービス『ECS』の利用方法について紹介します。
検証で利用するDockerイメージはWordPressを用意しているので、ECRやECSの使い方だけでなく、RDSとの連携方法についても紹介します。

なお、ECSの実行環境はEC2を利用します。

検証で利用するDockerfileについて

今回の検証ではWordPressのDockerイメージを利用します。

CocoonというWordPressのテーマが事前にインストールされたWordPressイメージを作成するDockerfileを用意しました。
ベースイメージはwordpress:5.4.2-php7.3-apacheを利用し、ビルド後のDockerイメージはwp-sampleとしています。

Dockerfile

FROM wordpress:5.2.2-php7.3-apache

RUN apt-get update
RUN apt-get -y install wget unzip

# テーマのダウンロード
WORKDIR /tmp/wp-themes
RUN wget https://wp-cocoon.com/download/791/cocoon-master-2.1.9.1.zip

# テーマを配置
RUN unzip './*.zip' -d /usr/src/wordpress/wp-content/themes

# 不要ファイル削除
RUN apt-get clean
RUN rm -rf /tmp/*

# 所有者の変更
RUN chown -R www-data:www-data /usr/src/wordpress/wp-content/themes

WORKDIR /var/www/html

docker-compose

version: '3'
services:
  wordpress:
    build: . # カレントディレクトリのDockerfileでイメージをビルド
    image: wp-sample # イメージ名はwp-sampleとする
    ports:
      - '80:80' # ローカルのport80でコンテナのport80にアクセスできるようにする
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db # データベースコンテナ名と一致させる
      WORDPRESS_DB_NAME: wordpress # MYSQL_DATABASEと一致させる
      WORDPRESS_DB_USER: wp_user # MYSQL_USERと一致させる
      WORDPRESS_DB_PASSWORD: wp_pass # MYSQL_PASSWORDと一致させる
  db:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root_pass
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: wp_pass
volumes:
  mysql_data:

Dockerを利用したWordPress環境の構築方法についてはMAMP・XAMPはもう古い?DockerでWordPressのローカル開発環境を一瞬で作成する方法を参考にしてください。

MAMP・XAMPはもう古い?DockerでWordPressのローカル開発環境を一瞬で作成する方法

ECRにDockerイメージをpushする

ECRとはElastic Container Resistoryの略で、Dockerイメージを管理する機能です。
ECRを利用することにより自作のDockerイメージをAWS上で管理できます。

下記のコマンドを実行し、ローカルでビルドしたDockerイメージをECRへpushします。

### 認証トークンを取得し、レジストリに対して Dockerクライアントを認証
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxx.dkr.ecr.ap-northeast-1.amazonaws.com

### DockerfileがあるディレクトリでDockerイメージのビルドを実行
$ docker build -t wp-sample .
# -t: イメージのタグ

### ローカルの「wp-sample:latest」イメージを、ECRの「wp-sample」リポジトリの「latest」とタグ付け
$ docker tag wp-sample:latest xxx.dkr.ecr.ap-northeast-1.amazonaws.com/wp-sample:latest

### タグ付けされたイメージの確認
$ docker images

REPOSITORY                                           TAG        IMAGE ID            CREATED             SIZE
wp-sample                                            latest     997228f38b59        About an hour ago   598MB
xxx.dkr.ecr.ap-northeast-1.amazonaws.com/wp-sample   latest     997228f38b59        About an hour ago   598MB
→ ECRのリポジトリが登録されていればOK

### ECRにイメージをpush
$ docker push xxx.dkr.ecr.ap-northeast-1.amazonaws.com/wp-sample:latest

ECRへDockerイメージをpushする手順の詳細についてはAWS CLIをインストールし、ECRへDockerイメージをpushする手順で紹介をしていますので、そちらを参照してください。

AWS CLIをインストールし、ECRへDockerイメージをpushする手順

ECSの環境を構築する

ECSとはElastic Container Serviceの略で、フルマネージド型のコンテナオーケストレーションサービスです。

ECSには『クラスター』『タスク』『サービス』という3つの概念が登場します。
『クラスター』『タスク』『サービス』の設定が完了するとAWS上でDockerコンテナを実行する環境が整います。

以下ではそれぞれの設定方法について紹介します。

クラスターの作成

クラスターとはECSでDockerコンテナを動かすときのホストマシンの論理グループで、ECSの一番大枠の概念にあたります。

Amazon ECSの『クラスター』→『クラスターの作成』を選択します。

『EC2 Linux + ネットワーキング』を選択します。

『空のクラスターの作成』にチェックを入れ、クラスター名を入力します。今回はsample-wordpressというクラスター名にします。

これでクラスターの作成はOKです。

ECSインスタンスをクラスターに追加する

クラスターの作成が完了したので、次にECSインスタンスをクラスターに登録します。ECSインスタンスとはDockerエージェントが起動しているEC2のことです。

ECSインスタンスの作成はAmazon ECS コンテナインスタンスの起動で掲載されている手順をベースに行っていきます。

『AWS Marketplace』を選択し、検索バーに『ecs-optimized』と入力して表示されるAMIを利用します。1
今回はAmazon ECS-optimized AMIで推奨されている『Amazon ECS-optimized Amazon Linux 2 AMI 』を利用します。

IAMロールは『ecsInstanceRole』を選択してください。適切なIAMロールが設定されていないと、ECSエージェントがクラスターに接続できないので注意しましょう。

『高度な詳細』→ 『ユーザーデータ』の『テキストで』にチェックを入れ、テキストボックスに下記を入力します。

#!/bin/bash
echo ECS_CLUSTER=[クラスタ名] >> /etc/ecs/ecs.config

そのほかの項目に関しては通常のEC2インスタンス作成時同様の手順で進めてください。

【AWS環境構築手順】VPCとEC2を作成し、実際にアクセスしてみる

ECSインスタンス作成後、先ほど作成したクラスターの『ECSインスタンス』の一覧にインスタンスが表示されていればOKです。

タスク定義を作成する

タスクとはアプリケーションを構成する1つ以上のコンテナ(群)のことをいいます。
タスク定義とは、タスク内でのコンテナ間のやりとりの方法やコンテナ数、使用ポートといったコンテナ情報を明記したものです。

Amazon ECSの『タスク定義』→『新しいタスク定義の作成』を選択します。

EC2を選択します。

『タスクロール』は他のAWSサービスとコンテナを連携させる場合に必要になります。今回は不要ですのでタスクロールは『なし』にします。

『ネットワークモード』とはホストとコンテナの接続方法に関する項目です。
『host』を利用するとホスト側で指定したポートがコンテナでも利用されるようになります。ポートマッピングを利用する場合は『default(bridge)』を利用します。
『awsvpc』を利用するとタスクごとにENIが割り当てられ、VPCのIPアドレスでコンテナへアクセスできるようになります。今回はdefaultにします。

次にタスク定義にコンテナを追加します。『コンテナの追加』を選択するとコンテナの設定画面が表示されます。

『イメージ』にはDockerイメージのリポジトリURLを記入します。今回はECRにpushしたDockerイメージを利用するため、ECRのレジストリを指定しています。

『メモリ制限』はAWSで推奨されている300MBを『ソフト制限』で設定しました。使用メモリが超えたら強制的にコンテナを終了させたい場合は『ハード制限』にしてください。

『ポートマッピング』は80:80にしました。

次に環境変数を設定します。
docker-compose等に記載されている、Dockerコンテナで利用される環境変数はこちらに記載をします。

今回はRDSを利用するため、WordPressのデータベースホスト名はRDSのエンドポイントを指定しています。Dockerコンテナの環境変数でRDSのエンドポイントを指定することでECSとRDSの連携ができます。

タスク定義にコンテナが追加されていればコンテナの設定はOKです。

なお、今回は利用しませんがデータボリュームを利用する際は『ボリュームの追加』の項目から行ってください。

作成後、タスク定義一覧に先ほど作成したタスク定義が表示されていればOKです。

サービスを作成する

サービスとはクラスター内で実行されるタスク数やタスクの配置方法を制御する機能です。

クラスターの『サービス』タブの『作成』を選択します。

『起動タイプ』はEC2にします。

『タスク定義』はファミリー名に先ほど作成したタスク定義名、リビジョンにlatestを指定します。

『サービスタイプ』はホストの増減に合わせてタスク数を制御するのであれば『DAEMON』、クラスター内でのタスク数を指定するのであれば『REPLICA』を指定します。今回はREPLICAにしました。

『タスクの数』はクラスター内で起動させるタスクの数を指定します。今回は1にしました。

『最小ヘルス率』はクラスターで実行されるべきタスク数のうち、どれくらいのhealty率を担保するかの率です。タスク数2・最小ヘルス率50であればタスクは少なくとも1つ起動していればOKという意味になります。

『最大率』は最小率とは逆です。タスク数2で最大率200であればタスク数4までhealty状態のタスクができることを許容します。

最小ヘルス率・最大率は主にデプロイ時にタスクが入れ替わるときの挙動を制御するために設定するものです。

『デプロイメントタイプ』は『ローリングアップデート』にします。

『配置テンプレート』は、『スプレッド(spread)』にすると均一性を重視した配置戦略、『ビンパック(binpack)』にするとコンテナインスタンスの数を最小限に抑える配置戦略となります。詳細はAmazon ECS タスク配置戦略を参照してください。
今回は『AZバランススプレッド』を選択します。

サービスを作成後、クラスターのサービス一覧にサービスが表示されていればOKです。

なお、今回作成したサービスではロードバラインシングとAuto Scalingの設定は行っておりません。

動作確認

サービスの作成が完了するとサービスの設定をもとに、クラスターにタスクの配置が行われます。サービスのイベントログはサービスの『イベント』タブで確認できます。

サービスが実行され、クラスターにタスクが配置されたことを確認してみます。クラスターの『タスク』を確認し、タスクが追加されていればOKです。

WordPress用のデータベースが必要ですので、EC2にログインしてデータベースとユーザーの作成を行います。

$ sudo yum update
$ sudo yum install -y mysql
$ mysql -h database-1.cnn4sy0jl2si.ap-northeast-1.rds.amazonaws.com -u root -p

> create database wordpress;
> create user wp_user@'%' identified by 'wp_pass';
> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'wp_user'@'%' WITH GRANT OPTION;


$ mysql -h database-1.cnn4sy0jl2si.ap-northeast-1.rds.amazonaws.com -u wp_user -p

EC2のパブリックIPアドレスにアクセスし、WordPressの管理画面が表示されればOKです。

WordPress言語選択

まとめ

以上で、ECR・ECS・RDSを組み合わせた環境の構築手順について紹介を終わります。

ECR・ECS・RDSを組み合わせた環境構築方法
  1. ECRにイメージをpushする
  2. クラスターの作成
  3. ECSインスタンスをクラスターへ登録する
  4. タスク定義でECRのイメージから生成されたコンテナを追加する
  5. サービスでクラスターとタスクを紐づける
  6. コンテナの環境変数を利用してRDSと接続する

この記事がいいなと思いましたらTwitter(@nishina555)のフォローもよろしくお願いします!

AWSオススメ参考書