ElasticBeanstalk w/ multi-container docker 最新事情

こんにちは、神崎(@tknzk) です。先日公開したブログ からアップデートがありましたので、まとめておきます。 変更点としては、EBのBase Platformの変更と mackerel-agentの alpineベース化、ECRのセカンダリDocker Registryとしてのセットアップになります。

EB Base platformの変更

Elastic Beanstalkのbase platformを最新の 64bit Amazon Linux 2016.03 v2.1.3 running Multi-container Docker 1.11.1 へ移行しました。 これにより、container側のdocker も 1.11系を利用することができるようになりました。hostとcontainerのdocker versionの差異により、containerが起動できない問題が改善出来ました。 しかし、先日 1.12 がリリースされているので、またhostとcontainerのversionがずれる状況が起きる可能性がありますが、適宜最新にアップデートをしていきたいと思います。。

mackerel-agent のalpineベース化

課題であった host側のdocker versionとの組み合わせ問題と、alpine:3.3で起きていたmackerel-agent-plugin-linuxが起動できない問題が alpine:3.4で解決されたことから mackerel-agentのimageもalpineをベースにしたものをbuildしてproductionへ投入しています。 動かしているpluginは下記のとおりで、他のpluginでは問題が起きる可能性があるので、alpine linuxベースでmackerel-agentを動かす場合は、検証の上設定してください。

  • mackerel-agent
  • mackerel-plugin-linux
  • mackerel-plugin-nginx
  • mackerel-plugin-docker

Docker RegistryのSPOF問題への対応

以前のブログや、先日登壇した AWSUGコンテナ支部 でも発表させていただきましたが、過去に一度オペレーションミスによる障害をおこしており、オペレーションミスはできるだけ防ぐとともに、利用しているDocker Registryのquay.ioが万が一ダウンしてしまった場合に備えての冗長化を行いました。 セカンダリのDocker RegistryとしてAmason ECRを採用し、適当なタイミングで Docker imageをpushしておく仕組みを作りました。

f:id:tknzk:20160829172921j:plain

以下のリンクにもあるとおり、東京リージョンにもECRがやってきたので、採用するには良いタイミングかと思います。

https://aws.amazon.com/jp/about-aws/whats-new/2016/08/amazon-ec2-container-registry-region-expansion/

必要なdocker imageは EBの設定ファイルである Dockerrun.aws.jsonに集約してあるので、そこから tagを含めたimage名を取得し docker pullして imageを取得 docker tag コマンドで tagを付け替えを行い、 docker push で Amazon ECRへpushする簡易的なscriptを作りました。

# Docker image sync quay.io to Amazon ECR
# require docker login over aws cli
# command here :
#   aws ecr get-login --region ap-northeast-1
#   and exec display docker login command
#   $(aws ecr get-login --region ap-northeast-1)
#
require 'json'

def targets
  # Dockerrun.aws.json
  json = open('./Dockerrun.aws.json') do |file|
    JSON.load(file)
  end
  images = []
  json['containerDefinitions'].each do |caontainer|
    images << caontainer['image']
  end
  images
end

def docker_pull(image)
  puts image
  `docker pull #{image}`
end

def tag_change(image)
  new_tag = replace_repository(image)
  puts new_tag
  `docker tag #{image} #{new_tag}`
end

def docker_push(image)
  new_tag = replace_repository(image)
  `docker push #{new_tag}`
end

def replace_repository(image)
  repository, tag = image.split(':')
  repository.gsub!(%r{quay.io/vasilyjp}, ecr_host)
  return "#{repository}:latest" if ARGV[0] == 'latest'
  "#{repository}:#{tag}"
end

def ecr_host
  'xxxxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com'
end

targets.each do |image|
  docker_pull(image)
  tag_change(image)
  docker_push(image)
end

上記のscriptを適当なタイミング(imageに変更があったタイミング)で手動で実行して Amazon ECRに docker imageをpushしておき、プライマリなDocker Registryに事故が発生した際には、 Dockerrun.aws.jsonの 各ContainerDefinitionsのimageの部分と、認証情報の部分を書き換えるだけで、ElasticBeanstalkをデプロイすることできる状態を確保することができました。 切り替えのデプロイは手動による対応が必要になりますが、最低限の冗長化を行うことができました。

参考までにテストでECRのimageからデプロイした時の状態です

[ec2-user@ip-xx-xx-xx-xx ~]$ sudo docker ps
CONTAINER ID        IMAGE                                                                COMMAND                  CREATED              STATUS              PORTS                         NAMES
33783cbab565        xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/mackerel-agent:latest   "/startup.sh"            About a minute ago   Up About a minute                                 ecs-awseb-ad-server-stg-ammpxnj9ag-362-mackerel-agent-f6f3b99ddbb2baddee01
cc1018ff8e35        xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/nginx:latest            "nginx -g 'daemon off"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, 443/tcp   ecs-awseb-ad-server-stg-ammpxnj9ag-362-nginx-proxy-f28e9092c5d9dba2ee01
f65afdb19efb        xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/ad_server:latest        "supervisord"            About a minute ago   Up About a minute   3000/tcp                      ecs-awseb-ad-server-stg-ammpxnj9ag-362-ad-server-c4e7d395e5d28abe9c01
94b3bf57a71a        xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/td-agent:latest         "td-agent --log /var/"   About a minute ago   Up About a minute   0.0.0.0:24224->24224/tcp      ecs-awseb-ad-server-stg-ammpxnj9ag-362-fluentd-84e2a5e6b58c84e36400
aa66d70ad211        amazon/amazon-ecs-agent:latest                                       "/agent"                 About a minute ago   Up About a minute   127.0.0.1:51678->51678/tcp    ecs-agent

まとめ

EB Base platformが docker 1.11 に対応したことで、docker imageの alpineベース化をすすめ、ECRを使うことで、Docker RegistryのSPOFの改善をおこいました。

以上、 ElasticBeanstalk w/ multi-container docker の最新事情でした。

最後に

VASILYでは、一緒に開発をしてくれる仲間を募集しています。 Dockerを使った開発/運用をしてみたい方は以下のリンクをご確認ください!