Dockerは docker run する時に、-P フラグを立てると、Dockerホストの、自動的にランダムにエフェメラルポートレンジの中のhigh port(well knownじゃないヤツ)に割り当てを行います。
これはDockerのドキュメントの Linking Containers Together(https://docs.docker.com/userguide/dockerlinks/) に書いてあって、
↓のようにDockerコンテナの5000番ポートが、Dockerホストの49155番ポートにマッピングされてる例とか。
$ sudo docker ps nostalgic_morse CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
Amazon ECSでは、DockerホストであるEC2と、Dockerコンテナのポートのマッピングに関しては、
↓のドキュメントのようにTaskのパラメータとして定義します。タスクって?って感じですが、要はコンテナの定義のことです。
http://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html
"portMappings": [ { "containerPort": integer, "hostPort": integer } ... ]
EC2上に複数のDockerのコンテナを立ち上げて、例えばそれらがxxポートをリスンするものだったとして、
ユーザーとしてはホスト側のポートは上記のように、よしななポートをマッピングして欲しいですね、と。
コチラに関しては、上記のドキュメントの中には↓のように記載されています。
If you want an automatically assigned host port, use the following syntax: "portMappings": [ { "containerPort": integer } ... ]
ただ、書かなければ良いって話なのですね、と。
ということで、さっそく試してみたいと思います。
■ Docker Imageの作成とDocker Hubへのアップロード
ECSのドキュメントのDocker Basicsの”To create a Docker image of a PHP web application”に沿って
やっていきたいと思います。
まずはギッハブからコピってきます。
$ git clone https://github.com/awslabs/ecs-demo-php-simple-app Cloning into 'ecs-demo-php-simple-app'... remote: Counting objects: 71, done. remote: Total 71 (delta 0), reused 0 (delta 0), pack-reused 71 Unpacking objects: 100% (71/71), done. Checking connectivity... done.
Dockerfileを見ると、UbuntuにApacheとかPHPとかインストールして、80番ポートでリスン的なのが分かります。
$ 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 # Install app RUN rm -rf /var/www/* ADD src /var/www # 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/apache2", "-D", "FOREGROUND"]
私のMacの環境でDocker imageを作ります。
boot2docker startで仮想マシンを立ち上げて、環境変数をホゲホゲって話は
↓この辺を参考になさっていただければ、と。
https://docs.docker.com/installation/mac/
しばらくボケっとしながらビルドが終わるのを待ちます。
$ docker build -t shinodogg/amazon-ecs-sample . Sending build context to Docker daemon 363.5 kB Sending build context to Docker daemon Step 0 : FROM ubuntu:12.04 Pulling repository ubuntu 〜略〜 tep 11 : CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"] ---> Running in d855e0fc614e ---> adfdd9bcf446 Removing intermediate container d855e0fc614e Successfully built adfdd9bcf446 $ echo $? 0
では走らせてみましょう。
$ docker run -p 80:80 shinodogg/amazon-ecs-sample
アドレスは↓よん、って事ですので、、
$ boot2docker ip The VM's Host only interface IP address is: 192.168.59.103
↓のように、良さ気でございます。
ってことで、Docker ImageをDocker Hubへ。コマンドラインでログインして、
$ docker login Username: shinodogg Password: Email: xxxx@gmail.com Login Succeeded
Docker Hubにpushします。貧弱な回線だとちょいちょい時間かかりますね。。
$ docker push shinodogg/amazon-ecs-sample The push refers to a repository [shinodogg/amazon-ecs-sample] (len: 1) Sending image list Pushing repository shinodogg/amazon-ecs-sample (1 tags) 〜略〜 adfdd9bcf446: Image successfully pushed Pushing tag for rev [adfdd9bcf446] on {https://cdn-registry-1.docker.io/v1/repositories/shinodogg/amazon-ecs-sample/tags/latest}
■ ECS用のEC2インスタンスを起動
MarketplaceからAMIを持ってくるのも良いのですが、実際にどんなものか知りたいので、
EC2をAmazon Linuxで普通に立てて、そこに諸々インストールしていきたいと思います。
↓に沿ってやっていきます。
Installing the Amazon ECS Container Agent
EC2はt2.mediumにしてみます。
EC2からECSをホゲホゲ出来るようにIAM Roleを付けてあげます。↓をまんまです。
http://docs.aws.amazon.com/AmazonECS/latest/developerguide/IAM_policies.html#instance_IAM_role
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:CreateCluster", "ecs:RegisterContainerInstance", "ecs:DeregisterContainerInstance", "ecs:DiscoverPollEndpoint", "ecs:Submit*", "ecs:Poll" ], "Resource": [ "*" ] } ] }
ポートはアレがアレで、一旦、自分のIPで全開放してみます。
EC2が立ち上がったら、dockerコマンドをインストールして、Dockerのサービスを立ち上げます。
$ sudo yum install docker -y $ sudo service docker start Starting cgconfig service: [ OK ] Starting docker: [ OK ]
ECSエージェントをインストールします。
ココでクラスタ名(shinodoggって書いてある太字のところ)が聞かれるのは理由があって、
この時点でClusterが起動していないと↓のようなエラーが出て止まってしまうので、
ECSのクラスタを作ってから叩きましょう。
msg=”Error registering” module=main err=”Cluster not found.”
$ sudo docker run --name ecs-agent -d > -v /var/run/docker.sock:/var/run/docker.sock > -v /var/log/ecs/:/log -p 127.0.0.1:51678:51678 > -v /var/lib/ecs/data:/data > -e ECS_LOGFILE=/log/ecs-agent.log > -e ECS_LOGLEVEL=info > -e ECS_DATADIR=/data > -e ECS_CLUSTER=shinodogg > amazon/amazon-ecs-agent:latest Unable to find image 'amazon/amazon-ecs-agent:latest' locally Pulling repository amazon/amazon-ecs-agent 68db83900ab7: Download complete 86ae36d94914: Download complete b39579a0c13b: Download complete 36d93670e9b5: Download complete Status: Downloaded newer image for amazon/amazon-ecs-agent:latest ac73fd6a55f02a6c0b7251d09cdc8700d4c89a7e00aae4ff42bf7575dd90bddc
■ ECSを使ってEC2上にコンテナを2つデプロイ
ココからは、Management Consoleを使っていきます。
まずはTaskの定義からしていきます。タスクって用語がややこしいのですが、そのDockerインスタンスに
どんなリソース(CPUとかメモリとか)割り当てるか〜とか、ポートどうするー?とか、そういうヤツです。
タスクの定義自体はECSのドキュメントのDocker Basicsにあるので、それをそのまま使います。
JSONタブにそのままコピペすると、
Builderタブでイイ感じに見えます。ついでなのでCPUとメモリの値をイジったりしつつ、
意図的にホスト側のポートの設定を削除します。
で、このTaskからServiceを作ります。これも名前がややこしいですが、
Scheduling Amazon ECS Tasksのページをみると(スケジューリングって言葉も慣れない人にはアレですね、、笑)
・Create Service: The service scheduler is ideally suited for long running stateless services and applications.
・Run Task: The RunTask action is ideally suited for processes such as batch jobs that perform work and then stop.
って事なので、今回はWebなアプリケーションなので、Create Serviceの方で、Clusterを shinodogg という名前で作ります。
この状態で上記のECSエージェントを走らせると、ログがイイ感じにズコズコ流れるかな、と。
あ、ちなみにECSエージェントのログファイルは /var/log/ecs/ecs-agent.log にあります。
マネージメントコンソールではServiceのStatusがActiveになっていてTaskが2つRUNNINGになっています。
(Taskのリビジョンが3に上がってるのは気にしないでください…笑)
EC2で docker ps を叩くと、ちょーっと見づらいですが、
↓のようにホストの49155番ポートと49156番ポートがそれぞれ立ち上げたDockerコンテナの
80番ポートにマッピングされているのが分かります
・0.0.0.0:49156->80/tcp
・0.0.0.0:49155->80/tcp
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 43280236f478 busybox:buildroot-2014.02 ""sh -c '/bin/sh -c 4 minutes ago Up 4 minutes ecs-console-sample-app-3-busybox-e8b18898b7af93ddaa01 4137bedb3bcd shinodogg/amazon-ecs-sample:latest "/usr/sbin/apache2 - 4 minutes ago Up 4 minutes 0.0.0.0:49156->80/tcp ecs-console-sample-app-3-simple-app-c2da8c81ccb3f2cbdf01 ae6d023c81ba busybox:buildroot-2014.02 ""sh -c '/bin/sh -c 4 minutes ago Up 4 minutes ecs-console-sample-app-3-busybox-d488f69e80a6d59edd01 4a7bc27d9de1 shinodogg/amazon-ecs-sample:latest "/usr/sbin/apache2 - 4 minutes ago Up 4 minutes 0.0.0.0:49155->80/tcp ecs-console-sample-app-3-simple-app-dadb83dae896d2afbc01 2d6ea464a2c4 amazon/amazon-ecs-agent:4023248 "/agent" 10 minutes ago Up 10 minutes 127.0.0.1:51678->51678/tcp ecs-agent
では、ブラウザからアクセスしてみましょう。
・49155番ポート
・49156番ポート
無事に、よしなにホスト側のポートとマッピングされていることが確認できました(´▽`)ノ
ってことで、検証環境はキレイにお掃除しておきます、と。
お仕事でいろんな人とお話させていただいている中でも、最近Dockerがすごい来てる感ありますが、
↓はプロダクションでDockerを使っている方の記事とかありますね。
技術評論社
売り上げランキング: 902
最後に、本投稿は私が個人的に行ったものであり、所属する企業や団体における公式見解ではございません。
コメント