Getting started ECS

前提知識

必要なもの

  • AWS アカウント
  • AWS CLIのインストール
  • Docker環境の構築

概要と用語集

Amazon Elastic Container Service とは - Amazon Elastic Container Service

  • コンテナ起動タイプが2つ

    • Fargate launch type: サーバーレスにコンテナをデプロイできる

      • docker hubのpublic imageか、ECRしか利用できない
    • EC2 launch type: EC2にコンテナインスタンスを構築してからそこにコンテナをデプロイする

      • コンテナエージェントの設定なども可能
      • ファイルをvolume マウントする必要が出てきたら必要になるかもしれない

用語集

  • コンテナ / イメージ: Dockerのそれと同じ
  • タスク定義: アプリケーションを実行するのに必要な設定を記述したJSON

    • 起動タイプ、使用するimage指定、ポートやボリューム設定など
  • タスクとサービス: タスク定義をインスタンス化したのがタスク

    • サービスはタスクの数や実行タイミングをスケジューリングできる
  • クラスタ: リソースの論理グループ化

    • クラスタ内にタスク / サービスを配置していく
  • コンテナインスタンス

  • コンテナエージェント: タスクの起動や停止 / リソース利用状況をECSに送信etc..

    • コンテナインスタンスで動作しているもの
  • ECR

    • フルマネージドなプライベートDockerレジストリ
    • ECSではコンテナイメージのビルドはできないので、ECRにイメージをpushしておく

ECRの利用方法

  • リポジトリの作成 - Amazon ECR
  • ECRリポジトリのデフォルトアクセス権限は自分のみ(リポジトリURLに自分のAWSアカウントIDが含まれている)

タスク実行までの流れ

  • クラスタ作成
  • タスク定義
  • タスク実行

クラスタ作成

タスク定義

機密情報を扱う

  • 環境変数でECS上のコンテナに機密情報を設定することは推奨されていない

    • Dockerfileで定義するのもよくない

However, those methods may not provide the desired level of security because environment variables can be shared with any linked container, read by any process running on the same Amazon EC2 instance, and preserved in intermediate layers of an image and visible via the Docker inspect command or ECS API call. You could also bake secrets into the container image, but someone could still access the secrets via the Docker build cache.

How to Manage Secrets for Amazon EC2 Container Service–Based Applications by Using Amazon S3 and Docker | AWS Security Blogより

上記の理由以外にも、JSONのタスク定義だと平文の機密情報がコンソールから閲覧可能になってしまっていて、 しかもタスク定義を削除することができないのでそれが残ってしまう。

S3とVPCエンドポイントの注意点

KMSとパラメータストアの概要

RUN apt-get update && apt-get install -y \
    python-dev \
    zip \
    jq
    
RUN curl -O https://bootstrap.pypa.io/get-pip.py

RUN python get-pip.py

RUN pip install awscli

タスク用のIAMロールを利用する場合の注意点

  • Node.jsのSDKの認証情報がタスク用のIAMロールになってしまった

    • タスク用のIAMロールが優先される仕組みらしい
    • 参考: タスク用の IAM ロール - Amazon Elastic Container Service

      注記 タスク用の IAM ロールを指定すると、そのタスクのコンテナ内の AWS CLI または他の SDK は、タスクロールによって提供された AWS 認証情報を排他的に使用し、コンテナインスタンスから IAM アクセス権限を継承しなくなります。

エントリーポイント用のシェルを用意

#!/bin/bash
#This is simple bash script that is used to test access to the EC2 Parameter store.

set -e

# Getting region
PARAMETER_STORE_PREFIX=${PARAMETER_STORE_PREFIX:-}

if [ -n "$PARAMETER_STORE_PREFIX" ]; then
  # NOTE: May be Fargate backend not return availability zone
  EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
  EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9][0-9]*\)[a-z]*\$:\\1:'`"
  # Trying to retrieve parameters from the EC2 Parameter Store
  SECRET_1=`aws ssm get-parameters --names ${PARAMETER_STORE_PREFIX}.secret-1 --with-decryption --region $EC2_REGION --output text 2>&1`
  SECRET_2=`aws ssm get-parameters --names ${PARAMETER_STORE_PREFIX}.secret-2 --with-decryption --region $EC2_REGION --output text 2>&1`
fi

exec "$@"

(ブログでパラメータストアから機密情報を設定するスクリプトをS3に保存している理由がよく分かっていない)

docker-composeと組み合わせてサービスを起動

Amazon ECS コマンドラインインターフェースの使用 - Amazon Elastic Container Service

tips / つまずいたポイント

ecs-cli psが便利

  • タスクが終了した原因も出力してくれる

ファイルのマウント

コンテナインスタンスにファイルを用意する必要がでてきそうだったので mysqlの設定ファイルを利用しないようにdocker-compose.ymlを修正した。

(どうやるのがいいのか分かっていない)

linksを使う

  • network / aliasには対応していない

コンテナインスタンスのタイプ見積もり

ローカルでコンテナを起動させたあとに docker stats でメモリ使用量を確認してから コンテナインスタンスのタイプを決めるとスムーズになる。

docker-comose.ymlで指定したmemory上限を超えるとOut of Memoryになってタスクが終了する。

logging設定

ALBとの接続

今後のTodo

  • スケールアウト / 可用性の調査

    • ALBの動的ポートマッピング利用
  • Fargate

    • ネットワークモード