ようへいの日々精進XP

よかろうもん

(ショロカレ 1 日目)Elastic Beanstalk と Docker コンテナで Worker Tier する

これは「初老丸の独り Advent calendar 2015」の一日目の記事です。

初老丸洋平

tl;dr

初老丸の独り Advent calendar 2015...略してショロカレの一日目。 引き続き、Elastic Beanstalk を弄る。今回は Docker コンテナで作った簡単 Worker を Deploy してみる。


memo

参考

アプリケーション

github.com

シンプルに Hello World をログに出力するだけの Sinatra アプリケーションと Dockerfile と Elastic Beanstalk で利用する Dockerrun.aws.json 等のセット。こちらの記事を参考にさせて頂いた。有難うございます。

  • アプリケーション
require 'sinatra'
require 'logger'

logger = Logger.new('/tmp/sinatra.log')

post '/' do
  logger.info "Hello World!"
end
  • Dockerfile
FROM ruby
MAINTAINER inokappa

RUN mkdir /opt/worker
ADD Gemfile /opt/worker/
ADD helloworld.rb /opt/worker/
ADD config.ru /opt/worker/

WORKDIR /opt/worker
RUN bundle install --path vendor/bundle

EXPOSE 4567
CMD bundle exec rackup config.ru -p 4567 -s thin -o 0.0.0.0
{
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "sinatra",
    "Update": "true"
  },
  "Ports": [
    {
      "ContainerPort": "4567"
    }
  ],
  "Volumes": [
    {
      "HostDirectory": "/tmp",
      "ContainerDirectory": "/tmp"
    }
  ],
  "Logging": "/var/log/nginx"
}

今回の肝となる Dockerrun.aws.json についての詳細はこちらを読む。ちょっと気になったのが、ドキュメント中には...

Dockerfile を使用するときは、Dockerrun.aws.json ファイルで Image キーを指定しないでください。Elastic Beanstalk は、存在する場合は Dockerfile に示されているイメージを常に構築して使用します。

とあるが、今回 Dockerrun.aws.json に Image キーがある状態でも特にエラーも出ることなくデプロイが終わった点。おそらく、Dockerfile がある場合には Image キーは無視されるようだ。

eb local

まずは eb local を使ってローカル環境で docker run してみる。

$ eb local
usage: eb local (sub-commands ...) [options ...]

Runs commands on your local machine.

commands:
  logs             Prints where logs are locally saved.
  open             Opens the application URL in a browser.
  printenv         Shows local environment variables.
  run              Runs the Docker container on your local machine.
  setenv           Sets local environment variables.
  status           Gets container information and status.

optional arguments:
  -h, --help            show this help message and exit
  --debug               toggle debug output
  --quiet               suppress all output
  -v, --verbose         toggle verbose output
  --profile PROFILE     use a specific profile from your credential file
  -r REGION, --region REGION
                        use a specific region
  --no-verify-ssl       do not verify AWS SSL certificates

ローカル環境でのコンテナ実行には eb local run を利用する。

$ eb local run
latest: Pulling from library/ruby
Digest: sha256:ae9eac85869550292bd3a5be2fd14db6c0a67f59a2fca465fb2176f6f7269c52
Status: Image is up to date for ruby:latest
Sending build context to Docker daemon 10.64 MB
Step 1 : FROM ruby
 ---> a930a50e60f8
Step 2 : MAINTAINER inokappa
 ---> Using cache
 ---> 9f11145561d2
Step 3 : RUN mkdir /opt/worker
 ---> Using cache
 ---> 970ba9f6e590
Step 4 : ADD Gemfile /opt/worker/
 ---> Using cache
 ---> e4e48ab1df83
Step 5 : ADD helloworld.rb /opt/worker/
 ---> Using cache
 ---> 3704de005b3e
Step 6 : ADD config.ru /opt/worker/
 ---> Using cache
 ---> 805d5434a600
Step 7 : WORKDIR /opt/worker
 ---> Using cache
 ---> 9a80323966ce
Step 8 : RUN bundle install --path vendor/bundle
 ---> Using cache
 ---> 2b843e5fa3e0
Step 9 : EXPOSE 4567
 ---> Using cache
 ---> 2cf9a853a648
Step 10 : CMD bundle exec rackup config.ru -p 4567 -s thin -o 0.0.0.0
 ---> Using cache
 ---> 88ab4a2ac880
Successfully built 88ab4a2ac880
Thin web server (v1.6.4 codename Gob Bluth)
Maximum connections set to 1024
Listening on 0.0.0.0:4567, CTRL+C to stop

パッと見 docker build が実行されているっぽい。更にデタッチはできなさそうなので別端末を開いてアクセスしてみる。

$ curl localhost:4567

以下のようにログが eb local run した端末に残る。

172.17.0.1 - - [30/Nov/2015:22:52:18 +0000] "GET / HTTP/1.1" 200 - 0.0097
172.17.0.1 - - [30/Nov/2015:22:52:20 +0000] "GET / HTTP/1.1" 200 - 0.0003
172.17.0.1 - - [30/Nov/2015:22:52:21 +0000] "GET / HTTP/1.1" 200 - 0.0007

docker ps してみると以下の通り。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
5aa16760011b        88ab4a2ac880        "/bin/sh -c 'bundle e"   2 minutes ago       Up 2 minutes        0.0.0.0:4567->4567/tcp   d1c5addd7344920470b94b3a12638aa3693fe531

デプロイの準備(eb init)

eb init 使ってアプリケーションを登録する。

$ eb init

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-southeast-1 : Asia Pacific (Singapore)
7) ap-southeast-2 : Asia Pacific (Sydney)
8) ap-northeast-1 : Asia Pacific (Tokyo)
9) sa-east-1 : South America (Sao Paulo)
10) cn-north-1 : China (Beijing)
(default is 3): 8

Select an application to use
1) oreno-eb-sinatra-worker
2) oreno-worker
3) eb-sinatra
4) [ Create new Application ]
(default is 4):

Enter Application Name
(default is "oreno-eb-worker"):
Application oreno-eb-worker has been created.

It appears you are using Docker. Is this correct?
(y/n): y

Select a platform version.
1) Docker 1.7.1
2) Docker 1.6.2
(default is 1): 1
Do you want to set up SSH for your instances?
(y/n): y

Select a keypair.
1) key1
2) key2
3) key3
4) key4
5) [ Create new KeyPair ]
(default is 16): 3

Docker バージョンが古い...。

初めてのデプロイ(eb create)

今回も Worker Tier なので以下のように。すでに作成済みの IAM role を利用する。

$ eb create --tier worker --instance_profile aws-elasticbeanstalk-ec2-worker-role
Enter Environment Name
(default is oreno-eb-worker-dev):
Creating application version archive "app-7fe7-151201_080204".
Uploading oreno-eb-worker/app-7fe7-151201_080204.zip to S3. This may take a while.
Upload Complete.
Environment details for: oreno-eb-worker-dev
  Application name: oreno-eb-worker
  Region: ap-northeast-1
  Deployed Version: app-7fe7-151201_080204
  Environment ID: e-swye9p9ddh
  Platform: 64bit Amazon Linux 2015.09 v2.0.4 running Docker 1.7.1
  Tier: Worker-SQS/HTTP
  CNAME: UNKNOWN
  Updated: 2015-11-30 23:02:07.663000+00:00
Printing Status:

(snip)

cron.yaml を追加

前回の記事と同様に cron.yaml を置いておく。

version: 1
cron:
 - name: "test"
   url: "/"
   schedule: "*/5 * * * *"

そして eb deploy する。

$ eb deploy
Creating application version archive "app-b97a-151201_084145".
Uploading oreno-eb-worker/app-b97a-151201_084145.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.
INFO: Deploying new version to instance(s).
WARN: Environment health has transitioned from Ok to Degraded. Command is executing on all instances. Impaired services on all instances.
INFO: Successfully built aws_beanstalk/staging-app
INFO: Docker container f8c1fb664f1c is running aws_beanstalk/current-app.
INFO: Successfully loaded 1 scheduled tasks from cron.yaml.

(snip)

cron.yaml が読み込まれている。

しばらくするとアプリケーションのログが吐かれているのが確認できる。

$ eb ssh
INFO: Attempting to open port 22.
INFO: SSH port 22 open.
Last login: Mon Nov 30 23:35:52 2015 from p19107-ipngnfx01fukuokachu.fukuoka.ocn.ne.jp
 _____ _           _   _      ____                       _        _ _
| ____| | __ _ ___| |_(_) ___| __ )  ___  __ _ _ __  ___| |_ __ _| | | __
|  _| | |/ _` / __| __| |/ __|  _ \ / _ \/ _` | '_ \/ __| __/ _` | | |/ /
| |___| | (_| \__ \ |_| | (__| |_) |  __/ (_| | | | \__ \ || (_| | |   <
|_____|_|\__,_|___/\__|_|\___|____/ \___|\__,_|_| |_|___/\__\__,_|_|_|\_\
                                       Amazon Linux AMI

This EC2 instance is managed by AWS Elastic Beanstalk. Changes made via SSH
WILL BE LOST if the instance is replaced by auto-scaling. For more information
on customizing your Elastic Beanstalk environment, see our documentation here:
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html
[ec2-user@ip-xx-xxx-xx-xx ~]$ tail /tmp/sinatra.log
# Logfile created on 2015-11-30 23:27:33 +0000 by logger.rb/47272
I, [2015-11-30T23:45:00.318483 #10]  INFO -- : Hello World!
I, [2015-11-30T23:49:59.916522 #10]  INFO -- : Hello World!
I, [2015-11-30T23:54:59.867460 #10]  INFO -- : Hello World!
I, [2015-11-30T23:59:59.903278 #10]  INFO -- : Hello World!

5 分毎にログが記録されている。


以上

ショロカレ一日目は Beanstalk と Docker で Worker Tier をやってみた。これを役立てる環境には居ないけどなんかしっくりきた。

以上。