73
85

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS上にDocker環境構築を、EC2に直で入れる方法とECS(マネジメントコンソール上で操作)の導入の2つの方法で入れてみた。

Last updated at Posted at 2016-06-22

Dockercon 16で今、Dockerの話題で盛り上がっています。
http://2016.dockercon.com/

AWS上にDocker環境をEC2上とECSの2つの方法で導入してみたのでメモ。
ECSはマネジメントコンソールからの操作で、2016年6月での地点での操作方法となります。
ECSを使用した場合はクラスタ管理から、負荷分散、スケーリングなどの面倒も見てくれます。

#EC2インスタンス上に直で入れる方法
DockerイメージはDocker Hubからpullしてきたものを使用する場合

$ sudo yum install -y docker
$ sudo service docker start

$ sudo docker pull '<Docker Hubユーザー名>/<イメージ名>:<Tag名>'
'<Tag名>': Pulling from '<Docker Hubユーザー名>/<イメージ名>'
efd26ecc9548: Pull complete
a3ed95caeb02: Pull complete
d1784d73276e: Pull complete
72e581645fc3: Pull complete
:
:
Digest: sha256:c8beee1a15bbc67edee9e4532a105d500ebc5935879557b020ba7dd1cfa0bdb1
Status: Downloaded newer image for '<Docker Hubユーザー名>/<イメージ名>:<Tag名>'

$ sudo docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
'<Docker Hubユーザー名>/<イメージ名>'   '<Tag名>'                 83602403dcba        10 weeks ago        856.4 MB

#コンテナを作成する
$ sudo docker run -d --name '<適当なコンテナ名>' -p '<Dockerで受け付けるポート番号>':'<アプリケーション側で受け付けるポート番号>' (-p '<Dockerで受け付けるポート番号>':'<アプリケーション側で受け付けるポート番号>') '<Docker Hubユーザー名>/<イメージ名>:<Tag名>'
65e1dd030dc25c46aa046c4daa5bac194931657e7188305df9723f77c2a9434f
# 又は docker run -ti タグ名(docker build -t タグ名 などで指定したもの)

$ sudo docker ps
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                                                      NAMES
65e1dd030dc2        '<Docker Hubユーザー名>/<名>:<Tag名>'   "~~~"   5 minutes ago       Up 5 minutes        0.0.0.0:'<Dockerで受け付けるポート番号>'->'<アプリケーション側で受け付けるポート番号>'/tcp, 0.0.0.0:'<Dockerで受け付けるポート番号>'->'<アプリケーション側で受け付けるポート番号>'/tcp, 8181/tcp   '<コンテナ名>'

#コンテナを起動する
$ sudo docker start <コンテナ(CONTAINER ID or NAMES)>
65e

#ホストからコンテナにログイン
$ sudo docker exec -it '<コンテナ名>' bash

http://'<IP address>':'<Dockerで受け付けるポート番号>'/'<PATH>' にアクセス。

#ECSを導入する方法
DockerイメージをDockerfileからビルドする場合

ECSで出てくるタスクとサービスの語句についてですが、
タスクはバッチ処理のような一回限りの処理、サービスは永続的な処理のものです。

ECSを導入する場合について、初めてのウォークスルーの場合と自分で構築する場合の2つのパターンを取り上げる。

##初めての場合
以下のURLから行うことでいつでも初めのウォークスルーの状態で設定を行うことができる。

Get Startedを選択する。

Deploy a sample application onto an Amazon ECS Cluster
Store container images securely with Amazon ECR

の2つにチェックを入れた状態でContinueを選択する。

###Step 1: Configure repository
Repository name: ecs-test
として、Next stepを選択する。

###Step 2: Build, tag, and push Docker image

ローカルで以下の作業を行う。OSはUbuntu14.04を使用した場合のものとなる。

$ mkdir docker-test
$ cd docker-test/
 $ aws ecr get-login --region us-west-2 
docker login -u AWS -p '<Password>' -e none https://~~~.ecr.us-west-2.amazonaws.com

Dockerをインストールしていない場合はインストールする。

$ wget -qO- https://get.docker.com/ | sh
$ sudo usermod -aG docker $USER
$ su - $USER
#先ほどaws ecrコマンドで生成されたdockerログインコマンドをコピペする。
$ docker login -u AWS -p '<Password>' -e none https://~~~.ecr.us-west-2.amazonaws.com
Warning: '-e' is deprecated, it will be removed soon. See usage.
Login Succeeded

Login Succeededと出ればログイン成功である。
次にDockerfileを作成する。

$ vim Dockerfile

例えば、以下のように作成する。

FROM ubuntu:14.04

RUN apt-get update -y
RUN apt-get install -y git curl apache2 php5 libapache2-mod-php5 php5-mcrypt php5-mysql

RUN rm -rf /var/www/*
ADD src /var/www

RUN a2enmod rewrite
RUN chown -R www-data:www-data /var/www
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2

EXPOSE 80

CMD ["/usr/sbin/apache2", "-D",  "FOREGROUND"]

コマンドはroot権限で実行される。

Dockerfileと同じ階層にsrcディレクトリを作成し、デプロイ対象となるファイルを用意する。

mkdir src && cd src
vim index.php
index.php
<html>
    <body>Hello, world!</body>
</html>

作成したDockerfileを元にイメージファイルをビルドする。

$ docker build -t ecs-test .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM php:5.6-apache
 ---> 306370e37ec1
Step 2 : RUN a2enmod rewrite
 ---> Using cache
 ---> e1523614a754
Step 3 : RUN docker-php-ext-install pdo_mysql mbstring
 ---> Using cache
 ---> 320d68c3ce69
Step 4 : RUN echo 'date.timezone = Asia/Tokyo' >> /usr/local/etc/php/conf.d/99_myconf.ini
 ---> Using cache
 ---> c404ecfa957f
:
:
Successfully built 4b0569678402

タグ付けをする。

$ docker tag ecs-test:latest ~.ecr.us-west-2.amazonaws.com/ecs-test:latest

ECSにPUSHする。

$ docker push ~.ecr.us-west-2.amazonaws.com/ecs-test:latest
The push refers to a repository [~.ecr.us-west-2.amazonaws.com/ecs-test]
4a7543f178f3: Pushed 
40da234f8043: Pushed 
749b6ec33d91: Pushed 
293489163a1e: Pushed 
61cd28b6b81d: Pushed 
7e9e746ecede: Pushed 
63e87343ae05: Pushed 
98fe2d81486b: Pushed 
0dcf6f5af493: Pushed 
8f86eea0e277: Pushed 
358d48af1ad0: Pushed 
72a004f2419f: Pushed 
f1c36d11715d: Pushed 
2f141c453bd9: Pushed 
ee63decf49d1: Pushed 
42755cf4ee95: Pushed 
latest: digest: sha256:5fa6532df8ee23369ee533afbc1cfdd53897839775c6c6d7207abc2e4486d7a6 size: 18332

Next Stepを押す

###Step 3: Create a task definition

Task definition name: console-sample-app-static-ecs-test

Container name: sample-app-ecs-test
Image: ~~.ecr.us-west-2.amazonaws.com/ecs-test:latest(デフォルト値)
Maximum memory (MB)*: 300(デフォルト値)
Port mapping: Host port 80, Container port 80, Protocol tcp

Next stepを選択する。

###Step 4: Configure service

Configure serviceの項目を以下のように入力する。

Service name: sample-webapp-ecs-test
Desired number of tasks*: 2

Elastic load balancingの項目を以下のように入力する。

Configure service: sample-app-ecs-test:80
ELB listener protocol*: HTTP
ELB listener protocol*: 80
ELB health check: http:80/

Service IAM roleの項目が以下のようになっていることを確認する。

Select IAM role for service: ecsServiceRole

Next stepを選択する。

###Step 5: Configure cluster

Configure clusterの項目を以下のように入力する。

Cluster name: default
EC2 instance type: t2.micro
Number of instances: 2
Key pair : '<EC2のネットワーク&セキュリティの項目中のキーペアで作成するなどして所持しているキーペア>'

Security groupの項目は以下のようになっていることを確認する。

Allowed ingress source(s)*: Anywhere, 0.0.0.0/0

Container instance IAM roleの項目が以下のようになっていることを確認する。

Container instance IAM role: Create new role

Review & launchを選択する。

###Step 6: Review
Launch instance & run serviceを選択する。

###Launch status
ECS statusが4項目の内すべてが"pending"から"created"の状態になり、
EC2 instance statusが15項目の内すべてが"pending"から"created"の状態になったら、ECS clusterの準備が完了である。

View serviceを選択する。

###動作確認
EC2のロードバランサの項目から先ほど作成したロードバランサを選択する。

説明というタブのDNS名を確認して、ブラウザからアクセスする。
Dockerで作成した通りのものがでれば動作確認ができたことになる。

##自分で構築する場合
###リポジトリの作成
画面左のリポジトリを選択し、[リポジトリの作成]を選択。

####ステップ 1: リポジトリの設定
例えば、以下のようにリポジトリ名を入力して、[次のステップ]を選択。

リポジトリ名: sample-ecr

####ステップ 2: Docker イメージの構築、タグ付け、プッシュ
以下のコマンドを入力して[次のステップ]

docker-machine start default
eval $(docker-machine env default)
$ aws ecr get-login --region us-east-1 --profile private
$ docker login -u AWS -p XXXXXXXXXX -e none https://<AWSアカウント番号>.dkr.ecr.us-east-1.amazonaws.com\n
$ docker build -t sample-ecr .
$ docker tag sample-ecr:latest <AWSアカウント番号>.dkr.ecr.us-east-1.amazonaws.com/sample-ecr:latest
$ docker push <AWSアカウント番号>.dkr.ecr.us-east-1.amazonaws.com/sample-ecr:latest

--profileに注意

###タスク定義の作成
画面左のタスク定義を選択し、[新しいタスク定義の作成]を選択。

タスク定義名: sample-task

コンテナの定義から[コンテナの追加]を選択。

以下のように情報を入力して、[追加]を選択。
コンテナ名: sample-container
イメージ: arn:aws:ecr:us-east-1::repository/sample-repository:latest
メモリ制限(MB): ハード制限 128
ポートマッピング: ホストポート 80, コンテナポート 80, プロトコル tcp

[作成]を選択。

以降、イメージに変更がある時は[新しいリビジョンの作成]からリビジョンを作成してサービスの方も関連づけるリビジョンを更新する。

#クラスターの作成
クラスターを作成する前に、ECSに最適化されたAMIでEC2インスタンスを作成する。もしくはエージェントをインストールする方法 (http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-install.html )もある。

####EC2インスタンスの作成
マネジメントコンソールからEC2を選択。
[インスタンスの作成]を選択。

#####1. AMI の選択
コミュニティAMIを選択し、検索ウィンドウからecs-optimizedと入力し出てくる以下のAMIを選択。

amzn-ami-2016.09.a-amazon-ecs-optimized - ami-1924770e

#####2. インスタンスタイプの選択
t2.microを選択し、[次の手順: インスタンスの詳細の設定]を選択。

#####3. インスタンスの設定
IAMロール: ecsInstanceRole
(※ Amazon EC2 Container Service Role中のAmazonEC2ContainerServiceRoleのロールを割り当てる。)

自動割り当てパブリックIP: [サブネット設定を使用(有効)]もしくは[有効化]で有効にしておく。

[次の手順: ストレージの追加]を選択。

#####4. ストレージの追加
[次の手順: インスタンスのタグ付け]を選択。

#####5. インスタンスのタグ付け
[次の手順: セキュリティグループの設定]を選択。

#####6. セキュリティグループの設定
[ルールの追加]を選択し、HTTP TCP 80 0.0.0.0を追加しておく。
[次の手順: 確認]を選択。
#####7. 確認
内容を確認したら、インスタンスの作成をする。鍵は適切なものを選択しておく。

画面左のクラスターを選択し、[クラスターの作成]を選択。
クラスター名を以下のように入力し、[作成]を選択。

EC2の起動が完了すると、ECSのクラスターに登録済みコンテナインスタンス: 1の状態でdefaultという名前で追加される。

####クラスターの作成
クラスターから先ほどのdefaultを選択。

[サービス]タブから[作成]を選択し、以下のように入力。

タスク定義: sample-task
クラスター: default
サービス名: sample-service
タスクの数: 1
最小ヘルス率: 50
最大率: 200

[サービスの作成]を選択。
ELBやAuto Scalingの設定も可能だが、ここでは省略。

[タスク]タブから[新しいタスクの実行]を選択。
以下のように入力して、[タスクの実行]を選択。

タスク定義: sample-task
クラスター: default
タスクの数: 1

以上で完了。

#Amazon ECS CLI 一覧

create-cluster
create-service
delete-cluster
delete-service
deregister-container-instance
deregister-task-definition
describe-clusters
describe-container-instances
describe-services
describe-task-definition
describe-tasks
discover-poll-endpoint
list-clusters
list-container-instances
list-services
list-task-definition-families
list-task-definitions
list-tasks
register-container-instance
register-task-definition
run-task
start-task
stop-task
submit-container-state-change
submit-task-state-change
update-container-agent
update-service
wait

#Dockerfile命令 一覧

FROM
MAINTAINER
RUN
CMD
LABEL
EXPOSE
ENV
ADD
COPY
ENTRYPOINT
VOLUME
USER
WORKDIR
ARG
ONBUILD
STOPSIGNAL

#Dockerコマンド 一覧

#管理系
daemon
info
inspect
version

#イメージ系
build
commit
export
history
images
import
load
rmi
save
tag

#コンテナ系
attach
cp
create
diff
events
exec
kill
logs
pause
port
ps
rename
restart
rm
run
start
stats
stop
top
unpause
wait

#Hub ・レジストリ系
login
logout
pull
push
search

#ネットワーク・接続系
network_connect
network_create
network_disconnect
network_inspect
network_ls
network_rm

#共有データ・ボリューム系
volume_create
volume_inspect
volume_ls
volume_rm

例えば、以下のように操作する。

$ sudo docker start 65e
65e
$ sudo docker stop 65e
65e
$ sudo docker restart 65e
65e

$ sudo docker rm 65e
Error response from daemon: You cannot remove a running container 65e1dd030dc25c46aa046c4daa5bac194931657e7188305df9723f77c2a9434f. Stop the container before attempting removal or use -f

$ sudo docker stop 65e
65e
$ sudo docker rm 65e
65e

#コマンドチートシート
http://qiita.com/voluntas/items/68c1fd04dd3d507d4083
http://qiita.com/suzukihi724/items/961112f6578a60dd6266

#ユースケース
##PHPの場合のDockerサンプル
src/以下にアプリケーション本体を置く。

FROM ubuntu:14.04

RUN apt-get update -y
RUN apt-get install -y git curl apache2 php5 libapache2-mod-php5 php5-mcrypt php5-mysql

RUN rm -rf /var/www/*
ADD src /var/www

RUN a2enmod rewrite
RUN chown -R www-data:www-data /var/www
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2

EXPOSE 80

CMD ["/usr/sbin/apache2", "-D",  "FOREGROUND"]

##PHPの場合のDocker Composeによるサンプル
Dockerfileを作成。

FROM php:5.6-apache

# Configuration of Redis
ENV PHP_REDIS_VERSION 2.2.7

RUN docker-php-source extract \
      && curl -L -o /tmp/redis.tar.gz https://github.com/phpredis/phpredis/archive/$PHP_REDIS_VERSION.tar.gz \
      && tar xfz /tmp/redis.tar.gz \
      && rm -r /tmp/redis.tar.gz \
      && mv phpredis-$PHP_REDIS_VERSION /usr/src/php/ext/redis \
      && docker-php-ext-install redis

RUN usermod -u 1000 www-data \
    && groupmod -g 1000 www-data

RUN echo 'date.timezone = Asia/Tokyo' >> /usr/local/etc/php/conf.d/99_myconf.ini
RUN echo 'error_reporting = E_ALL' >> /usr/local/etc/php/conf.d/99_myconf.ini

RUN apt-get update
RUN apt-get install -y libmysqlclient-dev mysql-client libpng12-dev libjpeg-dev libmagickwand-dev

# Install PHP GD
RUN docker-php-ext-configure gd --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j $(nproc) gd

# Install PHP Imagick
RUN pecl install imagick
RUN docker-php-ext-install pdo_mysql mbstring
RUN docker-php-ext-enable imagick

RUN a2enmod rewrite

WORKDIR /var/www
USER root

EXPOSE 80

# Update the default apache site with the config we created.
ADD docker-etc/apache-config.conf /etc/apache2/sites-enabled/000-default.conf

docker-compose.ymlを以下のように作成。

docker-compose.yml
web:
  build: .
  ports:
    - "80:80"
  volumes:
    - .:/var/www
  links:
    - db
    - redis
db:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD: root
redis:
  image: redis

docker-etc/apache-config.conf

<VirtualHost *:80>

DocumentRoot /var/www

<Directory /var/www>
   Options FollowSymLinks
   AllowOverride All
   Require all granted
</Directory>

ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>

##Railsを動かす場合のDocker composeによるサンプル

FROM ruby:2.3.1

ENV APP_ROOT /app

RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       libmysqld-dev \
                       libmysqlclient-dev \
                       mysql-client \
                       --no-install-recommends && \
    rm -Rf /var/lib/opt/lists/*

RUN mkdir $APP_ROOT
WORKDIR $APP_ROOT

ADD . /app
RUN bundle install
docker-compose.yml
version: '2' 
services:
  app:
    build: .
    command: bundle exec rails s -b 0.0.0.0
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    links:
      - db
  db: 
    image: mysql:5.6.30
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root

##Node.jsを動かす場合のDockerfileサンプル

FROM ubuntu:14.04

RUN apt-get update -y
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
RUN apt-get install -y nodejs npm build-essential

RUN update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10

RUN rm -rf /var/www/*
ADD src /var/www

WORKDIR /var/www
RUN npm install

RUN chown -R www-data:www-data /var/www

EXPOSE 3000
CMD ["node", "index.js"]

サービスを作成してタスクを実行すると、Node.jsが実行される。

##注意点

  • RUN update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10を追加することが重要。
  • タスクの定義でコンテナ定義時にポートマッピング設定でDockerfile中のポート番号と合わせることを忘れないようにする。
    • EXPOSEで設定したポート番号とコンテナ側のポート番号を一致させ、ホスト側のポート番号で実際に公開に使用するポート番号を設定する。WebSocketなどを使用するときはホスト側のポート番号で指定する。

#参考
http://qiita.com/toshihirock/items/dfd42314158aff073e9d
http://qiita.com/con_mame/items/1df441d86c703a0e6fa6

ECSのデプロイサンプル
https://github.com/awslabs/ecs-demo-php-simple-app

Dockerコマンド 一覧
https://docs.docker.com/v1.11/engine/reference/run/
Docker 公式
https://www.docker.com/
Docker Hub
https://hub.docker.com/

Amazon ECS CLI
http://docs.aws.amazon.com/cli/latest/reference/ecs/

Node.js Dockerfile
https://gist.github.com/thom-nic/724a2af410e90a654e35

73
85
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
73
85

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?