Dockerであそぶ(10)docker-machineを使ってAWS(EC2)にDockerホストを構築する
ここ1,2年で注目を集めている仮想化技術の1つ「Docker」について、今更感がありますが試していきたいと思います。
他の仮想化技術との違いや特徴、開発環境として使っていくにはどうすればいいかなどを紹介していきたいと考えています。
これまでの連載
- Dockerであそぶ(1)DockerToolboxのインストール
- Dockerであそぶ(2)Centos7を実行する
- Dockerであそぶ(3)Apacheを使う
- Dockerであそぶ(4)Apacheの設定を変える
- Dockerであそぶ(5)Apache-PHP連携
- Dockerであそぶ(6)Apache-PHP-Mariadb連携
- Dockerであそぶ(7)PhpMyAdminのインストール
- Dockerであそぶ(8)docker-composeでコンテナをまとめて管理
- Dockerであそぶ(9)AWS EC2でdocker-composeを使う
- Dockerであそぶ(10)docker-machineを使ってAWS(EC2)にDockerホストを構築する ← 本記事!
はじめに
前回はEC2インスタンスを作成し、そこにdockerツール群をインストールしてこれまでに作成してきたコンテナを動かしてみました。
しかしdockerにはこれらのdockerホストを自動で作成することができる仕組みが備わっています。前回も登場したdocker-machineというコマンドがそれに当たるのですが、このツールを使用することで複数のdockerホストを一元管理することが可能になり、管理コストの削減につなげていくことが可能です。
今回はこのdocker-machineコマンドを使用して、ローカルマシンからEC2上にdockerホストを構築、さらにコンテナを動作させるところまで行っていきたいと思います。
IAM (Identity and Access Management) Administratorユーザーの作成
ローカルマシンのdocker-machineコマンドでEC2上にアクセスするためには、Administorator権限を持たせたIAMユーザーのAWS Access Key IDおよびAWS Secret Access Keyが必要になります。
AWSの操作は本連載の趣旨ではないと考えますので詳細は割愛しますが、以下のサイトが非常に参考になりました。
AWSアカウント作ったらこれだけはやっとけ!IAMユーザーとAuthyを使ったMFAで2段階認証
IAMユーザーを作成する際に、アクセスキーおよびシークレットアクセスキーをCSVファイルでダウンロードできたと思います。
アクセスキーはAWS上から確認することが可能ですが、シークレットアクセスキーに関しては再ダウンロードできないようですので紛失してしまった方は以下の画面から新しいアクセスキーを作成しておいてください。
docker-machineを使ってEC2インスタンスを作成する
以下のオプションを指定してdocker-machineコマンドを実行します。
オプション | オプション値 | 概要 |
---|---|---|
–driver | amazonec2 | 使用するサービスを指定します。Supported Drivers |
–amazonec2-access-key | アクセスキーを指定 | 上記で取得したIAMアクセスキーを指定します |
–amazonec2-secret-key | シークレットキーを指定 | 上記で取得したIAMシークレットキーを指定します |
–amazonec2-region | ap-northeast-1 | インスタンスを作成するアベイラビリティーゾーンを指定します。値は東京リージョン |
–amazonec2-subnet-id | サブネットID | 作成するインスタンスのネットワークを設定します。どちらか一方のオプションのみ指定すればOKです。 |
–amazonec2-vpc-id | VPC-ID | |
–amazonec2-security-group | docker-machine | セキュリティグループを指定します。TCP2376ポートは必ず開放しておく必要があります。 |
$ docker-machine create --driver amazonec2 \ --amazonec2-access-key AKIXXXXXXXX \ --amazonec2-secret-key T3ZbtjDrVKFVXXXXXXXXXXXXXXXXXXXXXXXXX \ --amazonec2-region ap-northeast-1 \ --amazonec2-subnet-id subnet-acaa81d8 \ --amazonec2-security-group docker-machine \ aws-sandbox Running pre-create checks... Creating machine... Waiting for machine to be running, this may take a few minutes... Machine is running, waiting for SSH to be available... Detecting operating system of created instance... Provisioning created instance... Copying certs to the local machine directory... Copying certs to the remote machine... Setting Docker configuration on the remote daemon... To see how to connect Docker to this machine, run: C:\Program Files\Docker Toolbox\docker-machine.exe env aws-sandbox
これで作成できました。
AWSコントロールパネルを確認するとaws-sandboxというインスタンスが作成されているのがわかります。
サブコマンドのlsを使用すると登録されているdockerホストを確認することができます。
ACTIVE欄に「*」がついているホストが現在操作ターゲットになるdockerホストになります。
この状態でdocker-composeなどを実行するとdefault、つまりローカルマシンにインストールされたvirtualboxに対してコマンドが実行されることになります。
$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM aws-sandbox - amazonec2 Running tcp://52.193.xxx.xxx:2376 default * virtualbox Running tcp://192.168.99.100:2376
ACTIVEを切り替えるにはサブコマンドenvで出力される環境変数をそのままローカルマシンに設定すればOKです。
$ docker-machine env aws-sandbox export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://52.193.xxx.xxx:2376" export DOCKER_CERT_PATH="C:\Users\sudoy\.docker\machine\machines\aws-sandbox" export DOCKER_MACHINE_NAME="aws-sandbox" # Run this command to configure your shell: # eval "$(C:\Program Files\Docker Toolbox\docker-machine.exe env aws-sandbox)" $ eval "$(docker-machine env aws-sandbox)" $ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM aws-sandbox * amazonec2 Running tcp://52.193.xxx.xxx:2376 default - virtualbox Running tcp://192.168.99.100:2376
コンテナを作成/起動する
いよいよコンテナを作成/起動してみます。コマンドは前回登場したdocker-compose up -dでよいのですが、docker-compose.ymlは若干修正する必要があります。
my-mariadb: image: mariadb:latest environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=docker - MYSQL_USER=docker - MYSQL_PASSWORD=docker ports: - "3306:3306" my-php: # image: my-php build: ./php ports: - "80:80" volumes: # - /c/Users/sudoy/Documents/docker/techpjin-lamp/php/public-html:/var/www/html # - /home/ec2-user/techpjin-lamp/php/public-html:/var/www/html # 修正前 - /home/ubuntu/public-html:/var/www/html # 修正後 links: - my-mariadb my-phpmyadmin: image: phpmyadmin/phpmyadmin ports: - "8080:80" links: - "my-mariadb:db"
では、コンテナを作成/起動してみましょう。カレントディレクトリをdocker-compose.ymlファイルのあるフォルダに切り替えてから、docker-composeコマンドを実行します。
$ cd ~/Documents/docker/techpjin-lamp $ docker-compose up -d
以下のURLが正常に表示できることを確認しましょう。
- http://ec2-xxxxx.compute.amazonaws.com/
- http://ec2-xxxxx.compute.amazonaws.com/db.php
- http://ec2-xxxxx.compute.amazonaws.com:8080/
index.phpやdb.phpへのアクセスがうまくいかないかと思います(phpMyAdminへのアクセスはうまくいくと思います。)。これはdockerホスト側にソースファイルを持っているため、今作成したEC2ホストにはまだそれらのファイルが存在していないことが原因です。
docker-compose.ymlに記述した/home/ubuntu/public-htmlにローカルホスト上のファイルを転送しましょう。
docker-machineのサブコマンドscpを使うと転送することができます。
$ docker-machine scp -r php/public-html/ aws-sandbox:/home/ubuntu/public-html/ db.php 100% 601 0.6KB/s 00:00 index.php 100% 17 0.0KB/s 00:00
改めてindex.phpとdb.phpにアクセスしてみましょう。
今度は正しく表示することができたかと思います。
ソースファイル自体も本来はコンテナ(イメージ)の中に入れてしまうのがベターな気がしますが、仮にEC2を本番環境と見立てた場合にどのようにコンテナの中にそのソースを入れるのがよいのでしょうか。。。
開発環境と本番環境はできるだけコンテナ(イメージ)は共通のものにしておきたいですので、単にDockerfileを修正するというわけにはいかないのでないかと考えています。環境に依存するファイルとしてはdocker-compose.ymlがありますので、この中でコンテナ(イメージ)中にソースプログラムをダウンロードもしくはコピーする設定を記述できればいいのですが。(何かいい方法が思いついたらまた本連載の中で紹介していきたいと思います。)
補足:docker-compose up -dでエラーが発生する
「docker-compose up -d」時に以下のようなエラーが発生し、コンテナの作成に失敗してしまうことがあるかもしれません。
$ docker-compose up -d ・・・ 中略 ・・・ Failed: httpd.x86_64 0:2.4.6-40.el7.centos Complete! [31mERROR[0m: Service 'my-php' failed to build: The command '/bin/sh -c yum -y update && yum -y install httpd php' returned a non-zero code: 1
これはEC2(dockerホスト)で使用されているストレージドライバーのaufsに不具合があるからのようです。ストレージドライバーを変更するか、my-phpコンテナで使用しているイメージをcentos:latestからcentos:6に変更することで解決することができます。
ストレージドライバーを変更するには、docker-machine createするときに以下のオプションを追加します。
オプション | オプション値 | 概要 |
---|---|---|
–engine-storage-driver | devicemapper | 使用するストレージドライバーを指定します。 |
centos:6に変更するにはローカルマシンにあるtechpjin-lamp/php/Dockerfileを変更します。
# FROM centos:latest # 修正前 FROM centos:6 # 修正後 RUN yum -y update && \ yum -y install httpd php RUN yum -y install php-mysql EXPOSE 80 CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
変更が終わったらイメージの再作成を行いましょう。
$ docker-compose build $ docker-compose up -d
devicemapperはパフォーマンスに難があるという情報がありますので、centos6にした方が無難かもしれません。
↓参考にさせていただいたサイト
- Dockerのcentosでapacheインストール失敗する。rpmがうんちゃらとか言われる
- Ubuntu上のdocker build で error: unpacking of archive failed on file /usr/sbin/suexec: cpio: cap_set_file
今回はここまでにしておきます。