PHP Slim 環境構築(14) ECS(手動で設定するEC2編)
Introduction
前回は、EC2上にNginxとPHP-FPMの両方を格納したDockerコンテナを構築し、AWSの各種サービス(RDB、DynamoDB、S3)とアクセスさせてみました。
今回は、同じDockerコンテナをECS上に構築します。
この一連のシリーズは、自分への備忘録が第一目的のため、だいぶ不親切です。
申し訳ございません。
変更点
ソースコードの変更は、Dockerfileのみです。
このシリーズで構築した環境では、Dockerfileのパス(/compose/web_hoge)とソースコード(/src/hogeや/src/vendor)が離れており、docker-composeのvolumesを使ってコンテナにソースを組み込んでいます。
$(PROJECTROOT)
/compose
/web_hoge
Dockerfile
/src
/hoge
/vendor
web_hoge:
build:
context: ./web_hoge
volumes:
- ../src/hoge:/var/www/hoge
- ../src/vendor:/var/www/vendor
- ../credentials:/usr/local/etc/myapp/credentials
Dockerfileの変更
Dockerfileでは、作業ディレクトリよりも親への参照ができません。(例: COPY ../../src/web_hoge など)
したがって、 docker build -f compose/web_hoge/Dockerfile .
のように-fオプションで子ディレクトリ内のDockerfileを指定することになります。これに伴い、Dockerfile内のファイル参照のパスも変更されます。
具体的な変更箇所は、COPYコマンドのコピー元が$(PROJECTROOT)からの相対パスで記述されるようになったことと、docker-composeのvolumesの代わりにソースをコピーするようになったことです。
FROM alpine:3.10.2
ARG environment
..(略)..
# supervisord
RUN mkdir -p /etc/supervisor.d
COPY compose/web_hoge/supervisord.conf /etc/supervisord.conf
# settings
COPY compose/web_hoge/settings-${environment}.yml /usr/local/etc/myapp/settings.yml
# PHP
COPY compose/web_hoge/php.ini /php.ini
COPY compose/web_hoge/php-fpm.conf /php-fpm.conf
COPY compose/web_hoge/php-fpm-supervisor.conf /php-fpm-supervisor.conf
RUN cp /php-fpm.conf /etc/php7/php-fpm.d/z-php.conf \
&& cp /php.ini /etc/php7/conf.d/config.ini \
&& cp /php-fpm-supervisor.conf /etc/supervisor.d/php-fpm.conf
# Nginx
COPY compose/web_hoge/nginx.conf /nginx.conf
COPY compose/web_hoge/nginx-server.conf /nginx-server.conf
COPY compose/web_hoge/nginx-supervisor.conf /nginx-supervisor.conf
RUN cp /nginx.conf /etc/nginx/nginx.conf \
&& cp /nginx-server.conf /etc/nginx/conf.d/default.conf \
&& cp /nginx-supervisor.conf /etc/supervisor.d/nginx.conf
..(略)..
# ソース追加(以下三行追加)
COPY src/hoge /var/www/hoge
COPY src/vendor /var/www/vendor
COPY credentials /usr/local/etc/myapp/credentials
EXPOSE 3128
ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
AWS
ECR
今回はDockerリポジトリとして、Amazon ECRを使用することにします。
ECRサービスメニューから、リポジトリの作成を選びます。
パラメータ | 値 |
---|---|
リポジトリ名 | hoge-repo |
このリポジトリのURIは、<<AWS-ACCOUNT-ID>>.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo
になります。
ビルド
適当なEC2上でビルドすることにします。なお、以下の条件が整っているものとします。
- aws configureで接続設定済み (regionはap-northeast-1)
- dockerコマンドがインストール済み
- gitコマンドやファイルコピーなどで最近のソースが取得可能
- ECRへの操作権限を持っている
# $(aws ecr get-login --no-include-email)
# ACCOUNT_ID=$(aws sts get-caller-identity | grep Account | grep -oE '[0-9]+')
# cd <<PROJECT_ROOT>>
# docker build -t hoge-repo:latest --build-arg environment=devaws -f compose/web_hoge/Dockerfile .
# docker tag hoge-repo:latest $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo:latest
# docker push $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo:latest
IAM(ロールの作成)
Dockerコンテナの持つロールを定義しておきます。
RDS、DynamoDBなどにアクセスすることからそれらを操作する権限が必要です。
(接続確認を優先したため、権限が大きい(FullAccess)です! 本番注意)。
パラメータ | 値 |
---|---|
ロール名 | hoge-ecs-user |
AWSサービス | Elastic Container Service Task |
ポリシー | AmazonRDSFullAccess, AmazonDynamoDBFullAccess, AmazonS3FullAccess |
EC2(ターゲットグループ)
ロードバランサの設定前に、そのターゲットグループを設定しておきます。
ポートは、nginxへのアクセスポートである3128です。
パラメータ | 値 |
---|---|
名前 | hoge-target |
ターゲットの種類 | インスタンス |
ポート | 3128 |
ヘルスチェック | http /favicon.ico |
EC2(セキュリティグループ)
以下の二種類のアクセスに対するセキュリティグループを定義します。
- ロードバランサへのアクセス
外部からのhttp(s)のアクセスです。
パラメータ | 値 |
---|---|
名前 | hoge-http-sg |
インバウンド | 80(0.0.0.0/0), 443(0.0.0.0/0) |
- Dockerコンテナへのアクセス
ECSのインスタンスへ直接SSHアクセスするための定義(ポート22)と、ALBからのアクセス(動的ポートマッピングを使用するのでその範囲)。
パラメータ | 値 |
---|---|
名前 | hoge-instance-sg |
インバウンド | 22(SSH接続可能なIP), 32768-65535(ロードバランサのVPC) |
AWS Certificate Manager
SSLを使う場合は、こちらで証明書を発行します。発行後、承認されるまでは最大72時間かかるので注意が必要です
(詳細は本筋と外れるので省略)。
EC2(ロードバランサ)
ALBの設定を行います。
パラメータ | 値 |
---|---|
名前 | hoge-alb |
スキーム | インターネット向け |
リスナー | 80, 443(証明書が必要です) |
AZ | ap-northeast-1a, 1c, 1d全部 |
セキュリティグループ | hoge-http-sg |
ターゲットグループ | hoge-target |
ECS(クラスター)
ECS用のクラスターを作成します。なお、この設定を行った際に、自動的にEC2(Auto Scalingグループ)とEC2(起動設定)が作成されます。
パラメータ | 値 |
---|---|
クラスターテンプレート | EC2 Linux + ネットワーキング |
クラスター名 | hoge-cluster |
プロビジョニングモデル | オンデマンド |
EC2インスタンス | t2.micro |
インスタンス数 | 1 |
キーペア | 直接インスタンスにアクセスする場合は設定する。本番環境等ではなし |
VPC | 既存のVPC |
サブネット | ap-northeast-1a, 1c, 1dの全部 |
セキュリティグループ | hoge-instance-sg |
コンテナインスタンスIAMロール | ecsInstanceRole(自動生成される) |
EC2(起動設定)
クラスターを生成したときに自動生成された起動設定をコピーし、修正します。
ユーザーデータでは、サーバに必要な設定の変更なども行います (ここに示しているのはあくまでサンプルです)。
クラスター名を変更する場合は、ユーザーデータ内のECS_CLUSTERを変えないと動作しないので注意です(はまったことあります・・)。
パラメータ | 値 |
---|---|
名前 | hoge-launch-config |
IAMロール | ecsInstanceRole |
モニタリング | 詳細モニタリングを無効に |
ユーザーデータ | (下記参照) |
IPアドレスタイプ | 直接インスタンスにアクセスする場合は割り当てる。本番環境等では割り当てない |
#!/bin/bash
cat <<'ECS_EOF' >> /etc/ecs/ecs.config
ECS_CLUSTER=hoge-cluster
ECS_BACKEND_HOST=
#ECS_LOGLEVEL=debug
ECS_EOF
cat <<'SYS_EOF' >> /etc/sysctl.conf
net.core.somaxcon=65535
SYS_EOF
sysctl -p /etc/sysctl.conf
cat <<'FLIMIT_EOF' > /etc/security/limits.d/filelimits.conf
* soft nofile 32768
* hard nofile 32768
FLIMIT_EOF
ulimit -n 32768
EC2(Auto Scalingグループ)
クラスターを生成したときに自動生成されたオートスケールグループ設定をコピーし、修正します。
パラメータ | 値 |
---|---|
グループ名 | hoge-asg |
起動設定 | hoge-launch-config |
作成した後、ターゲットグループを"hoge-target"に指定します。
ECS(タスク定義)
ECSで生成されたインスタンスにDockerコンテナを載せるためのタスク定義を行います。
下のメモリ・CPU数は、t2.micro(vCPU=1, memory=約1000MB)で二個のタスクが動作する設定です。
パラメータ | 値 |
---|---|
起動タイプ | EC2 |
タスク定義名 | hoge-task |
タスクロール | hoge-ecs-user |
ネットワークモード | <default> |
タスク実行ロール | ecsTaskExecuteRole(自動生成される) |
タスクメモリ | 400 (本当はちゃんと設定する) |
タスクCPU | 512 (本当はちゃんと設定する) |
コンテナ名 | hoge-container |
イメージ | <<AWS-ACCOUNT-ID>>.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo:latest |
メモリ制限 | ハード/400MB, ソフト/300MB (本当はちゃんと設定する) |
CPUユニット数 | 512 (本当はちゃんと設定する) |
ポートマッピング | ホスト(0) : コンテナ(3128) (自動ポートマッピングを使用するのでホストポートは0) |
ECS(サービス追加)
タスクを元にECSにサービスを追加します。
パラメータ | 値 |
---|---|
起動タイプ | EC2 |
タスク定義 | hoge-task |
クラスタ | hoge-cluster |
サービス名 | hoge-service |
サービスタイプ | REPLICA |
タスクの数 | 1 |
デプロイ | ローリングアップデート |
ロードバランサー | hoge-alb |
サービス用IAMロール | AWSServiceRoleForECS |
ロードバランス用コンテナ | hoge-container:0:3128 |
サービスの検出の統合の有効性 | 無効 |
ロードバランス用のコンテナターゲット | hoge-target |
AutoScaling | 無効 |
接続確認
ここまで完了すれば、うまく動いている(はず)です。
うまくいっていれば、以下のURLにアクセスすれば"BEFORE:Hello, World!:AFTER"が表示されます。
SSL接続するケースや、独自ドメインを使用するケースはここでは割愛します。
http://hoge-alb-<<ALBに割り当てられたID>>.ap-northeast-1.elb.amazonaws.com/