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
 
最後に、本投稿は私が個人的に行ったものであり、所属する企業や団体における公式見解ではございません。
  
  
  
  


コメント