2017年1月5日木曜日

Amazon EC2 Container Service (ECS) を使って docker コンテナを立ち上げてみた

概要

Amazon EC2 Container Server (ECS) はクラウド上でコンテナを動作させることができるサービスです
今回は ECS を初めて使って docker コンテナを動作させるところまでやってみました
コンテナ上では apache2 を動かしてブラウザで動作確認してみます

環境

  • Amazon EC2 Container Service (ECS) 2017/01/05 時点
  • CentOS 7.3 64bit
  • docker 1.12.5

事前準備

今回は手元の環境で動作していた docker コンテナをそのまま ECS 上で動作させます
なので、手元に docker build -> docker tag -> docker push できる環境は揃えておいてください
今回は CentOS7 + docker 環境を事前に構築しました
https://docs.docker.com/engine/installation/linux/centos/

また、AWS を操作するユーザですが IAM や CloudFormation を使って VPC や EC2 のリソースにアクセスします
一番簡単なのは IAM ユーザではなく管理者で操作するのですが、IAM ユーザを使う場合は、各種リソースに権限を付与するようにしてください
そして、今回作業するリージョンですがアジアパシフィック (シドニー) ap-southeast-2 を使用しました
基本的にどこでも問題ないですが、ECS がまだ提供されていないリージョンもあるので注意してください
ECS は AWS 上に環境を構築する中でいろいろな AWS リソースを作成します
自分が引っかかったのは EC2 のインターネットゲートウェイの作成上限で、これが 1 リージョンあたり 5 つしか作成できません
すでに 5 つ作成してあるリージョンで ECS の環境を構築しようとしていたためリソース作成時にエラーとなり進めないことがありました
この辺の他のリソースの作成と権限周りはハマりポイントでもあるので注意して作業してください

イメージ共有用のリポジトリの作成

ECS に初回アクセス時にはチュートリアルが表示されます
まずはそれ通りに操作してみたいと思います

https://ap-southeast-2.console.aws.amazon.com/ecs/home?region=ap-southeast-2

にアクセスするとチュートリアルの開始画面が表示されると思うので「今すぐ始める」を選択します
first_ecs1.png

すると開始画面が表示されるので「続行」を選択します
チェックボックスで何をするか選択できますが、今回は初回なので両方チェックしておきます
first_ecs2.png

リポジトリを作成します
リポジトリ名は好きなものを入力してください、今回は「test/repo」としました
リポジトリ名にはスラッシュを含めることができます
入力できたら次へ進みます
first_ecs3.png

リポジトリへのログイン

作成したリポジトリにログインします
ここでまた別のツールが出てくるのですが AWS CLI というツールを使ってログインします
インストールは python の 2.7 以上がインストールされていれば簡単です
すでに pip がインストールされているのであれば pip install のみで OK です

AWS CLI がインストールできたらまず AWS の認証情報を登録します

  • aws configure

これで AWS を操作するユーザの Access Key ID, Secret Access Key, region name が聞かれるので、それぞれ入力します
最後に output format を聞かれますが今回は入力しないで大丈夫です
first_ecs4.png

成功するとカレントディレクトリ配下に .aws/config と .aws/credentials が作成されていると思います

これで認証情報が作成できたので、docker コマンドを使ってリポジトリにログインするコマンドを取得します

  • aws ecr get-login --region ap-southeast-2

実行すると出力結果に docker コマンドが表示されるのでそれをそのまま実行しましょう

「Login Succeeded」と表示されれば OK です
これで AWS 上に作成した docker イメージ共有用のリポジトリへのログインができました

Docker イメージの作成

リポジトリが作成できたら手元の環境でイメージを作成します
おそらく画面に docker イメージを作成する手順が書かれていると思います
ただ、Dockerfile までは書かれていないのでここではサンプルの Dockerfile も含めてコマンドを紹介します

  • cat Dockerfile
FROM ubuntu:12.04

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

# Configure apache
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/apache2ctl", "-D",  "FOREGROUND"]
  • docker build -t test/repo .
  • docker tag test/repo:latest 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com/test/repo:latest

ビルドしてイメージを作成し、作成したイメージのタグ付しているだけです
タグの数字の部分はリポジトリの数字に適宜変更してください、念のため投稿時は変更しているだけです
これで docker images でイメージを作成すると以下のように表示されると思います

  • docker images
REPOSITORY                                                    TAG                 IMAGE ID            CREATED             SIZE
123456789012.dkr.ecr.ap-southeast-2.amazonaws.com/test/repo   latest              069192dbbba1        3 minutes ago       228.5 MB
test/repo                                                     latest              069192dbbba1        3 minutes ago       228.5 MB
ubuntu                                                        12.04               f0d07a756afd        2 weeks ago         103.6 MB
hello-world                                                   latest              c54a2cc56cbb        6 months ago        1.848 kB

これでイメージの作成ができました
イメージから正常にコンテナが動作するか手元で確認する場合は以下を実行してください

  • docker run -d -p 1080:80 --name test 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com/test/repo

でコンテナがで起動してサーバの 1080 番ポートにアクセスして apache2 のはじめの画面が表示されればコンテナとして正常に動作していることになります

Docker イメージのプッシュ

作成したイメージをリポジトリにプッシュしましょう
以下のコマンドを実行するだけです

  • docker push 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com/test/repo:latest

イメージのアップロードが始まるので完了するまで待ちましょう
すべてのアップロード完了すれば OK です

念のため記載しておきますが、アップロードがすべて完了する前に ECS のチュートリアルを先に進んでしまうとリポジトリにイメージがないと怒られるので注意してください

タスクの作成

次にタスクと呼ばれるものを作成します
タスクはイメージをどうやってコンテナ化するか、どう扱うかのルールみたいなものです
デフォルトでいろいろと値が入っているので特に変更する点はありませんが、今回は「ポートマッピング」のホストポートだけ 80 -> 1080 に変更しました
first_ecs5.png

サービスの作成

次のサービスと呼ばれるものを作成します
サービスはタスクからいくつコンテナを起動するかのルールになります
起動後のコンテナを ELB にぶら下げることもできます
今回は特に設定することはないので確認して次にいきます
first_ecs6.png

クラスタの作成

クラスタは実際に docker コンテナが ECS 上で動作するためのコンテナホストをまとめて管理するためのものになります
コンテナホストの実体はただの EC2 のインスタンスでありこの上に「Amazon ECS Container Agent」がインストールされることでコンテナホストとして ECS のクラスタにジョインすることができます
(実は Agent もただの docker コンテナです)

クラスタの作成ではコンテナホストに割り当てる SSH キーやセキュリティグループ、IAM の権限を割り当てます
これも基本はデフォルトで問題ないですが、コンテナホストへの SSH が必要なのであれば SSH キーを有効にし、セキュリティグループも変更したいのであれば適宜変更してください
また、最後に IAM のロールの設定をしますが、これは Agent が API をコールするためであり Agent には適切な権限が割り当てられている必要があります
よくわからなければ「新しいロールの作成」を選択しておけば「ecsInstanceRole」というロールを作成してくれるので大丈夫です
first_ecs7.png

これで設定は完了です
内容を確認して起動すると ECS 環境の構築がはじまります
first_ecs8.png

EC2 のインスタンスを作成したりするので数分かかります
問題なく完了したら「サービスの表示」を選択します

動作確認

実はここまで完了すればすでにコンテナが起動しているはずです
起動したタスクの画面になると思うのでそこでタスクのステータスが RUNNING になっていることを確認します
first_ecs9.png

ECS ではコンテナはタスクとして実行されます
タスクを実行することでコンテナを起動することができます
逆にタスクを停止することでコンテナを停止することもできます

今回は apache2 のデフォルト画面が表示されるコンテナをデプロイしたので画面も確認してみます
左メニュー「クラスター」->「default」->「ECS インスタンス」タブ->「コンテナインスタンス」を選択すると docker コンテナが動作しているインスタンスの情報が表示されます
first_ecs10.png

そこに表示されるパブリック DNS or IP の 1080 ポートにアクセスしてみましょう
すると以下のような画面が表示されると思います
first_ecs11.png

最後に

Amazon ECS 上で docker コンテナを 1 つ動作させてみました
コンテナを 1 つ動作させるだけでしたが、操作や概念の理解をしなければならないなど、やはりかなり yakshaving な感じにはなりました

他に軽く触った感じだと

  • サービスで指定したタスクの「必要数」になるまでタスクを自動で起動しようとするのでうまく起動しないイメージを push してしまうとタスクが永遠に失敗し続けてしまう
  • 今回の場合手動でタスクをもう一つ起動しようとしてもコンテナインスタンスの 1080 ポートがすでに使われているためエラーとなる
  • コンテナインスタンスのリソース監視機能がデフォルトで使える
  • クラスタを削除すると ECS 作成時に自動で作成してくれた他の AWS リソースも削除してくれる (全部は削除していないっぽい?料金が発生するリソースのみ削除してくれているかも)

といった感じです
今回一番ハマったのは操作するユーザの権限周りでした
IAM の情報を取得したり VPC を作成したりすることができるユーザでないとダメだったので結局自分は管理者権限を付与して実施しました

docker swam や kubernetes を使って自分でコンテナクラスタを管理する必要がなくなるのが一番のメリットかなと思いました
勝手にスケールアウトしてくれるし負荷分散もしてくれるので、コンテナを管理したことある人には嬉しいサービスかと思います

docker-compose が使えるらしいのでそれも後々試してみたいと思います
SSH ができるので手動で docker run した場合にどうなるのとかも見てみたかなと思います

0 件のコメント:

コメントを投稿