【レポート】AWSでDockerを動かそう #reinvent #CMP209

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

本記事はAWS re:Invent 2017のセッション「CMP209 - Getting Started with Docker on AWS」のレポートです。

概要

AWS is an elastic, secure, flexible, and developer-centric ecosystem that serves as an ideal platform for Docker deployments. AWS offers the scalable infrastructure, APIs, and SDKs that integrate tightly into a development lifecycle and accentuate the benefits of the lightweight and portable containers that Docker offers. In this session, you learn the benefits of containers, learn about the Amazon EC2 Container Service, and understand how to use Amazon ECS to run containerized applications at scale in production.

DockerをECS場で動かす際の、各要素の説明と、一般的な方針の紹介となるセッションでした。

登壇者

  • Abby Fuller - Sr. Technical Evangelist

レポート

Dockerとは?

Dockerはオープンソースの分散アプリケーション実行のためのプラットフォームである。 Docker内に構築されたアプリケーションは、あなたの選んだプラットフォーム上でビルド、管理、実行できる。

DockerコンテナはDockerFileと呼ばれる一連の命令からビルドされる。 Dockerコンテナをローカルで実行する場合、以下の様にすれば良い。

$ docker build -t app .
$ docker run app

しかし、AWS本番環境に置いてコンテナを使うには、どの様にすれば良いのだろう?

Amazon EC2 Container Service

スケーラブルでハイパフォーマンスなコンテナ管理システムであり、自分でインストールや管理、スケールをする必要をなくす。

※ セッション時はまだAmazon EC2 Container Serviceと呼んでいましたが、現在はAmazon Elastic Container Serviceとなっているようです。

ECSは、

  • クラスターの管理
  • コンテナのオーケストレーション
  • 深いAWSとの統合
    • Autoscaling
    • Load balancing
    • IAM
    • Networking
    • Logging

のための管理プラットフォームを提供する。

ECSの一般的な利用法

  • Cluster:1つ以上のEC2インスタンスで構成される
  • Instance:EC2であり、クラスタに登録する。タスクはここで実行する。
    • 1つ以上のサービスが実行される
  • Service:タスクの配置と管理のためのレイヤー
  • Task:コンテナのラッパーであり、インスタンス上で実行されるプロセス周りの設定

各クラスターの下に複数のインスタンスがぶら下がり、その中でタスクがそれぞれ実行される。

  • ロードバランサーは、クラスターインスタンスへトラフィックをルーティングする

サービス

実行したいだけのタスクのコピーをコントロールし、ロードバランサーにあなたのサービスを登録する。

タスク定義

コンテナのイメージ、環境変数、リソースの割り当て、ロガー、その他のパラメータをコントロールする。

やってみよう

クラスターの構築

コンソールもしくは以下のコマンドでクラスターを作成できる。

$ aws ecs create-clustr --cluster-name "your-cluster-name"

{
    "cluster":{
        "status":"ACTIVE",
        "clusterName":"reinvent",
        "registerdContainerInstanceCount":0,
        "pendingTasksCount":0,
        "runnningTaskCount":0,
        "activeServiceCount":0,
    }
}

#### ECSに置けるタスク定義
クラスタの作成が完了したら、タスク定義を作成する必要がある。
タスク定義はあなたのサービスに関するほとんどのことをコントロールする。

```shell
$ aws ecs register-task-definition
  --family <value>
  [--task-role-arn <value>]
  [--execution-role-arn <value>]
  [--network-mode <value>]
  --container-definitions <value>
  [--volumes <value>]
  [--placement-constraints <value>]
  [--requires-compatibilities <value>]
  [--cpu <value>]
  [--memory <value>]
  [--cli-input-json <value>]
  [--generate-cli-skeleton <value>]

JSONファイルから指定する例

$ aws ecs register-task-definition --cli-ipnut-json file://path/reinvent.json

JSON文字列を直接指定することも可能。

サービスを作成

$ aws ecs create-service --service-name meetup -task-definition meetup --desired-count 2

ここでさらに別のパラメータを指定することもできる。サービスをELB/ALBに登録することも可能。

Task placement policies

create-serviceの呼び出し時に、タスク配置の制約とストラテジーを設定できる。

デフォルトではECSスケジューラーは以下の様にタスクを配置する。

  1. ポート、メモリ、CPUの様な制約をチェック
  2. 一番タスクの実行数が少ないインスタンスにタスクを配置

Custom task placement strategies

  • Binpacking:リソースが残っているところにタスクを配置
  • インスタンス数が最小で済む
  • Spread:均等に配置
  • Affinity:サービスの組み合わせごとに配置
  • Distinct instance:各タスクを別のインスタンスに配置

    Custome task placement constraints

  • AMI ID
  • Availability Zone
  • Instance Type
  • Distinct Instances
  • Custom
    • 独自定義の属性

ロードバランサーについて

3つの種類がある。

  • ELB Classic:インスタンス間にトラフィックを分配する
  • Application Load Balancer:パスベースのルーティング。
    • マイクロサービスに合っている
    • L7で動作
  • Network Load Balancer:高いパフォーマンス、低いレイテンシー
    • 一般的でなかったり、スパイクのあるトラフィックパターンに合っている。
    • L4で動作

マイクロサービスやECSにはALBを強く推奨する。1つのALBで複数のサービスへのルーティングを行えるからである。 (例./web,/message,/api)

また、動的なポートの割り当てをサポートしている。

サービスの更新のよるデプロイやスケール

$ aws ecs update-service reinvent --desired-count 4 --task-definition reinvent:6

このupdate-serviceは、多くの機能を提供している。

  • --desired-countの変更は、サービスをスケールアップ、ダウンさせる
    • ただし、本番環境においてはAutoscalingによってハンドリングさせたい
  • --task-definitionの変更によって、事実上のデプロイができる

クラスターの状態をみる

$ aws ecs describe-services --service reinvent

サービスについての多くの情報が返却される。大切なのは、現在のデプロイの情報や、クラスターで何がが起きているかを見れることである。

"events":[
    {
        "message":"(service reinvent) has reached a steady state."

クラスターのイベントはCloudWatchにもストリーミングされる。

CloudWatch logsによるAmazon ECSのイベントストリーム

クラスター内のコンテナインスタンスの状態や、実行中のタスクの現在の状態がほぼリアルタイムで受信できる。

ALBのサービスディスカバリ

たくさんの方法がある。 パスによるコンテンツベースのルーティングが可能なので、ALBによる方法が簡単である。

新しいタスクがサービスに追加されると、ALBを通して実行可能な全てのサービスへリクエストのルーティングがハンドリングされる。

DNSのディスカバリ

新しいタスクが開始、終了した時に、CloudWatch eventをトリガーにLambdaによってRoute53へDNSレコードを追加/削除する。

シークレットについて

環境変数はタスク定義の一部分として設定できる。ただし、センシティブな情報についてはタスク定義によって設定すべきではない。

センシティブな値は、KMSによって暗号化した値をECS Systems Manager Parameter Storeによって管理すべきだる。

タスクはアクセス権限のあるパラメータへのみアクセスできる。 IAM Roleをタスクレベルで設定することで、細かいコントロールが可能である。

まとめ

Dockerの概要と、ECSによるDockerの利用に関する一連の流れについての紹介となるセッションでした。 コンテナ関連の新サービスはre:Invent2017でいくつか発表されていますが、そもそもDocker,ECSがよくわかっていなかったので勉強になりました。

re:Invent 2017で新たに発表されたコンテナ関連のサービスについての記事はこちら