Atsushi2022の日記

データエンジニアリングに関連する記事を投稿してます

読書メモ~AWSで学ぶクラウドネイティブ実践入門

概要

AWSで学ぶクラウドネイティブ実践入門」を読んで大事そうなところをメモしておく。

今回は第2章「AWSで構築するクラウドネイティブサービス」と第3章「コンテナサービスの構築」のみ読んだ。

第4章「CI/CDの構築」は今度時間があるときに読む。

ECRについて

  • ECR (Elastic Container Registry)はVPC上には存在せず、AWSリージョンサービスとして存在する
  • ECRへのアクセスはインターネット経由か、VPCエンドポイント経由で行う
  • VPCエンドポイント経由でECRにアクセスするには3種類のVPCエンドポイントが必要になる
    • ECR向けのインターフェース型VPCエンドポイント 2種類
      • com.amazonaws.[region].ecr.api
        • awsecrloginコマンドなどのECRAPIの呼び出しに利用される
      • com.amazonaws.[region].ecr.dkr
        • docker pushコマンドなどのDockerクライアントコマンドの呼び出しに利用される
    • S3向けのゲートウェイVPCエンドポイント 1種類
      • com.amazonaws.[region].s3
        • Dockerイメージ取得に利用される
  • インターフェース型VPCエンドポイントとは、ENI(Elastic Network Interface)経由で個別のAWSサービスにプライベート接続できるエンドポイントのこと。ENIにはIPアドレスが割り振られれるため、VPCエンドポイント作成時にVPCサブネットを指定する必要がある。
  • ゲートウェイVPCエンドポイントは、インターネットゲートウェイのようなもの。ネットワークインターフェースは存在せず、ルートテーブルにゲートウェイ型エンドポイントへの宛先を追加するだけで、AWSリソースにプライベート接続できる。
  • VPCエンドポイントは、AWSサービスごとに作成が必要。さらに、S3とDynamoDBを除くインターフェイスVPCエンドポイントごとに時間+処理データの重量課金が発生。利用するサービスが多くなると高くなりがちなので、コストバランスとセキュリティ要件のバランスを見ながら、NATゲートウェイを採用するのも有効
  • ECR作成時に下記オプションを指定できる
    • タグのイミュータブル
      • Dockerイメージの世代管理を表すタグについて、同じタグでの登録を許可しない(上書きさせない)
    • プッシュ時のスキャン
      • Dockerイメージがプッシュされた際にセキュリティの脆弱性チェックを実行する
  • ECRではDockerイメージの保存サイズに応じて料金が発生する
  • ライフサイクル定義を設定し、古い世代のイメージを削除することが可能
  • リポジトリごとに最大10,000イメージまで保存可能
  • ECRにプッシュされたDockerイメージは、S3バケットに暗号化されて保存される。このバケットAWS側で管理されているため、ユーザー側のS3一覧からは確認することはできない。しかし、ECRからDockerイメージをプッシュ、プルしたい場合、S3に対するIAMロールやネットワーク経路が必要となるので要注意
  • 料金はS3より少し割高(0.10USD/GB)
  • ECRにプッシュするには、ひと工夫必要。AWSではECR内のDockerイメージをAWSアカウントごとに識別している関係上、IMAGEIDとして決められた形式でプッシュする必要がある

    イメージスキャン

    • ECRにプッシュしたDockerイメージの脆弱性評価スキャンはClairと呼ばれるOSSをベースに実装されている
    • Red HatUbuntuといったOSレベルの脆弱性スキャンを行う
    • アプリケーションレベルのスキャンは行わないので要注意
    • また、すべてのベースイメージがサポートされているわけでもない
    • 例えばAlpine Linuxという軽量ベースイメージはサポート対象外(今も対象外なのかは要確認)
    • ベースイメージをlatestで取得している場合は、対象かどうか確認しておくとよい

Cloud9

  • デフォルトでログインしたAWSユーザーの権限で、自動的に認証権限が設定される
  • AWS Managed Temporary Credentialsと呼ばれる
  • AMTCを利用することでEC2認証設定が不要になるだけでなく、Cloud9側がクレデンシャル情報を定期更新してくれる

ECS

  • ECSはコントロールプレーン
    • 稼働するコンテナのスケールや死活監視などの管理を行う
  • Fargateはデータプレーン
    • コンテナが実際に稼働するリソース環境を提供する

コンテナデプロイの流れ

  • ECRにDockerイメージを登録
  • 登録したDockerイメージをデプロイするように、ECS上の定義をアップデート
  • 指示を受けたECSは、指定されたECS定義内のDockerイメージ情報を基に、Fargateに対してコンテナデプロイを指示
  • Fargateでは、コンテナごとにFirecracker20と呼ばれるマイクロVMを起動させ、その上でコンテナが稼働させる

用語

ECSクラスター > ECSサービス > タスク定義(タスク)

という包含関係になっている。ECSサービスがタスクの上位にいることに注意。

タスク定義

  • ひとつ以上のコンテナから構成されるアプリケーション実行の単位
  • タスクを作成するテンプレート定義で、JSONで記述される
  • JSONには、デプロイするDockerイメージ、コンテナに割り当てるリソースやIAMロール、CloudWatchLogsの出力先などを指定する

タスク

  • タスク定義から起動されるアプリケーションの実体です。

サービス

クラスタ

  • タスク、ECSサービスを実行する論理グループ

課金

  • Fargateを利用する場合、タスクに割り当てたCPUとメモリリソース分だけ課金される
  • コンテナに割り当てたリソースではないことに注意

ログ出力

  • タスク定義でログ出力の定義を行う
  • 代表的なログの送信先はCloud Watch Logs
  • コンテナアプリケーションのログ出力を標準出力にしておく必要があるので要注意

ECSクラスターの作成単位

どのようにコンテナを集約すべきかについて。

スケール観点

  • Capacity Providerというタスクのスケール調整機能はECSクラスター単位で動作する
  • スケーリング戦略が同一の場合は、同じECSクラスターとして集約すべき

IAM制御観点

  • ECSクラスター単位でIAMを制御できる
  • 特定のコンテナのみ許可したい場合はECSクラスターを分離する必要がある

ビジネスサービス観点

  • 決済、明細、振込、審査などのビジネス上の粒度でECSクラスsたーを分離するとわかりやすいし、IAM制御もやりやすい

Fargateのデメリット

  • マネージドなデータプレーンなので、コンテナが稼働するOSをいじることができない。カーネルパラメータなどのOSリソースをチューニングできない
  • EC2をデータプレーンとして利用する場合とくらべて、コンテナの起動がちょっと遅い
    • ENIがアタッチされ、個別のIPを付与するため(awsvpcモードのため)
  • ホストOS上にコンテナイメージをキャッシュしないので、スケールアウトなどのコンテナ起動時は、都度Dockerイメージをダウンロードする

テストポート

  • 有効化することで、新しいコンテナをパブリックに公開する前に、内部関係者のみがテストポート経由でコンテナの動作確認を行うことができる

タスク起動失敗時の調査

コンテナのデバッグ

  • Fargateはマネージドなデータプレーンであるため、docker exec -it <コンテナ名> /bin/shでコンテナ内にログインできない
  • いったんECS+EC2でデプロイしてチェックする
    • 厳密にはFargateとEC2は異なる環境だけど、一時切り分けとしてはいいかも

SSMパラメータストア

  • 環境変数を安全に保管できる
  • Fargate上で稼働すコンテナとシームレスに連携可能
  • コンテナ上の環境変数として読み込ませるには、ECSのタスク定義でアクセス権限を付与する
    • ssm:GetParameters
      • パラメータストアのパラメータ参照に必要
    • secretsmanager:GetSecretValue
      • パラメータストアのSecrets Managerシークレットを参照する場合に必要
    • カスタムKMSキーを利用する場合は、kms:Decryptの設定も必要

Secrets Manager

  • SSMパラメータストアの似ているが、Secrets Managerにはローテーション機能が備わっている
  • ローテーションさせたい場合にはSecrets Managerを使う