ECS(Fargate)でコンテナを起動する方法

2021/9/19

(最終更新: 2022/10/09

アイキャッチ画像

はじめに

ECS(Fargate)を使ってdockerコンテナを立ち上げ、コンテナ上でWebアプリを起動します。

dockerイメージの管理にはAmazon ECRを利用します。

前提

  • AWSマネジメントコンソールにアクセスできること。
  • IAMユーザに対し、必要なAWSサービスの利用を許可するIAMロールが紐づいていること。
  • 開発環境にdockerがインストールされていること。
  • 開発環境にdockerイメージが作成されていること。イメージ名は、hello-world-docker-testとする。

dockerインストール方法とイメージの作成方法については、以下の記事を参照してください。

EC2(Linux)上でdockerコンテナを起動してみる | エンジニアを目指す日常ブログ

aws CLIを使えるようにする

aws CLIをインストール

公式ガイドに従いaws CLIをインストールします。

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
$ aws --version

すでにインストールされている場合、

$ sudo ./aws/install

でエラーが出ることがあります。その場合は

$ sudo ./aws/install --update

を実行します。

awsCLIの基本設定(aws configure設定)

公式ガイドに従ってaws CLIの認証情報を設定します。

IAM認証情報の設定

アクセスキー ID とシークレットアクセスキーを取得します。

AWSマネジメントコンソールのIAMコンソール→ユーザ→自分のIAMユーザ「認証情報」タブ→「アクセスキーの作成」

アクセスキーの作成

アクセスキー ID とシークレットアクセスキーは、メモまたはCSVダウンロードしておきます。

awsコマンドを実行しているサーバが、自分のサーバであることを証明するためのキーとなります。

IAM認証情報をサーバ側で設定

以下コマンドを実行し、取得した「アクセスキーID」「シークレットアクセスキー」「リージョン」「出力形式」を対話型で設定します。

$ aws configure

設定項目

  • AWS Access Key ID
  • AWS Secret Access Key
  • Default region name
  • Default output format

リージョンはap-northeast-1、出力形式はjsonとします。

$ aws configure
AWS Access Key ID [None]: ★
AWS Secret Access Key [None]: ★
Default region name [None]: ap-northeast-1
Default output format [None]: json

ECRにdockerイメージをプッシュする

AWSのdockerイメージ管理サービスであるAmazon ECR(Amazon Elastic Container Registry)を利用します。

Gitのようにdockerイメージを管理できる機能と思えば良いらしいです。

リポジトリを作成

マネジメントコンソールから「ECS」を検索して「Elastic Container Service」を選択する。

左側のメニューから「リポジトリ」を選択します。

ECR

「リポジトリを作成」を選択します。

今回は名前をhello-world-ecs-test-2で作成しました。

hello-world-ecs-test-2

CLIでクライアント認証

クライアント認証

コンソール画面で、リポジトリを選択し、プッシュコマンドを表示を押すとプッシュするためのコマンドが表示されるため、指示に従います。

プッシュコマンドを表示

まずCLIからECRにログインします。

認証トークンを取得し、レジストリに対して Docker クライアントを認証します。

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin [アカウント].dkr.ecr.ap-northeast-1.amazonaws.com

以下、発生したラーの記録が続きます。エラーが起きなかった場合は dockerイメージの構築へ。

参考:ECR認証で発生したエラー(IAM権限問題)

こちらのエラーに5時間ほど悩まされましたが、IAMロールの設定を変更することで解消しました。

An error occurred (AccessDenied) ・・・(省略)

参考:ECR認証で発生したエラー(ファイルアクセス権限)

IAMロール問題解決の後、こちらのエラーが発生しました。

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/auth": dial unix /var/run/docker.sock: connect: permission denied

/var/run/docker.sockファイルに実行権限が無いことが問題のようなので、実行権限をつけました。

この操作により、これまでsudoをつけていたdockerコマンド操作がsudo無しで実行可能になりました。

$ sudo chmod 666 /var/run/docker.sock

参考:ECR認証で発生したエラー(config参照不備)

以下のエラーが発生しました。

Unable to locate credentials. You can configure credentials by running "aws configure". Error: Cannot perform an interactive login from a non TTY device

これは本来、前の手順のアクセスキー設定ができていないときに発生するエラーです。

設定しているのになぜ出てしまったかというと、aws ecr get-login-passwordコマンドにsudoをつけてしまっていたことが原因でした。

ECRのコンソールで指定されている通りに、sudo無しのコマンドを実行し解決しました。

参考:同じことをEC2ではなくVirtualBox上で実施したときのエラー

エラー内容

Error saving credentials: error storing credentials - err: exit status 1, out: `Cannot autolaunch D-Bus without X11 $DISPLAY`

何かの認証情報が保存できていない状況とのことでした。

passgnupg2をインストールして解決。詳細は不明です。

$ sudo apt-get install pass gnupg2
$ gpg2 - gen-key
$ pass init $gpg_id

gnupg2は、公開鍵と秘密鍵を生成してくれるツールらしいです。

参考にしたサイト:

dockerイメージの構築

dockerイメージを作成します。

$ docker build -t hello-world-ecs-test-2 .
Sending build context to Docker daemon  212.3MB
Step 1/2 : FROM nginx:latest
 ---> 51086ed63d8c
Step 2/2 : COPY ./src /usr/share/nginx/html
 ---> Using cache
 ---> e79af938e3b8
Successfully built e79af938e3b8
Successfully tagged hello-world-ecs-test-2:latest

dockerイメージの一覧を確認すると、以下のようになっていました。

$ docker images
REPOSITORY                TAG       IMAGE ID       CREATED       SIZE
hello-world-docker-test   latest    e79af938e3b8   2 hours ago   142MB
hello-world-ecs-test-2    latest    e79af938e3b8   2 hours ago   142MB
nginx                     latest    51086ed63d8c   3 days ago    142MB

上2つはIMAGE IDが同じになっています。中身は同じイメージですが、別のリポジトリとしてイメージを作成できました。

hello-world-ecs-test-2というリポジトリでdockerイメージを作成できている場合は、本手順は実行しなくてもOKです。

イメージにタグをつける

dockerイメージに「タグ」をつけます。

構築が完了したら、このリポジトリにイメージをプッシュできるように、イメージにタグを付けます。

docker tagコマンドを利用します。ECRが提示してくれたコマンドをコピペでOKです。

$ docker tag hello-world-ecs-test-2:latest [アカウント名].dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-ecs-test-2:latest

ここでCLI上で、

$ docker images

でイメージを見ると、同じイメージIDで、「REPOSITORY」の名前が異なるものが1行増えていました。

$ docker images
REPOSITORY                                                                 TAG       IMAGE ID       CREATED       SIZE
hello-world-docker-test                                                    latest    e79af938e3b8   2 hours ago   142MB
hello-world-ecs-test-2                                                     latest    e79af938e3b8   2 hours ago   142MB
[アカウント名].dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-ecs-test-2   latest    e79af938e3b8   2 hours ago   142MBnginx

ECRにdockerイメージをプッシュ

リポジトリにイメージをプッシュします。

$ docker push [アカウント名].dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-ecs-test-2:latest

ECRにイメージをプッシュできました。 プッシュできた

ECSを利用したコンテナ立ち上げ

いよいよAmazon ECS(Amazon Elastic Container Service)でコンテナを立ち上げます。

クラスター作成

ECSのマネジメントコンソールからクラスターの作成→ネットワーキングのみを選択します。

クラスタ名とNameタグは入れておきます。

タスク定義の作成

タスク定義とは、コンテナを立ち上げるときに実行する処理を書いておくことができるものです。 docker-compose.ymlのイメージ。

まずは「新しいタスク定義の作成」からタスク定義を作成します。

  • FARGATEを選択
  • タスクロール:立ち上がるコンテナからほかのAWSサービスにAPIアクセスする際などは、タスクロールを設定して権限を付与する必要があります。今回は「なし」とします。
  • ネットワークモードはawsvpc、オペレーティングシステムファミリーはLinuxとしました。
  • タスクの実行IAMロール:ECRにイメージをおいているので、ECRに対するアクセス権限が必要です。 また、コンテナのログをCloud Watchに吐き出す権限をつける必要があります。「新しいロールの作成」にしておきます。
  • メモリ、CPUは最小(0.5GB・0.25vCPU)としました。
  • コンテナの定義追加
    • コンテナ名をつけます。
    • イメージ:ここに、直接Dockerfileの中身を書いても良いです。ECRを使う場合はイメージの URIを記載します。今回はURIを記載します。
    • ポートマッピングは、80tcpを選択します。「ホストコンテナインスタンス」のポート80に、フォワーディングする設定とのことです。

ECRのURIは、マネジメントコンソールから確認可能です。

ECRのURI

サービスの作成

実際にコンテナを立ち上げます。

「クラスター」からクラスターを選択し、「サービス」タブから「作成」をクリックします。

  • 起動タイプはFARGATE
  • タスク定義は先ほど作ったタスク定義
  • サービス名は適当に
  • タスクの数:実際に立ち上がるコンテナの数を設定できます。今回は3とします。
  • デプロイメント:主流はBlue/Greenですが、今回は簡単のためローリングアップデートとします。
  • VPCとサブネットは、過去作ったものを利用します。サブネットは、パブリックサブネットのAZ-aとAZ-cでそれぞれ設定しておきます。
  • セキュリティグループは、自動で作ってくれます。
  • パブリックIPの自動割り当てはENABLEDにします。
  • ロードバランサは、簡単のため無しにします。

サブネット設定

タスクが立ち上がった

タスクが3つ立ち上がったのが確認できます。

タスクが立ち上がった

Webサイトにアクセスする

立ち上がったタスクのパブリックIPアドレスを確認して、ブラウザでアクセスします。

パブリックIP

IPアドレスだけ入れればポート80にアクセスすることができます。

ブラウザ

コンテナの中には入れないらしい

FARGATEを使った場合、コンテナの中に入ることはできないらしいです。

おわりに

ECSを使ってコンテナを立ち上げ、コンテナ上にWebサイトを構築することができました。



個別連絡はこちらへ→Twitterお問い合わせ

プロフィール

プロフィールイメージ

はち子

事業会社のシステム部門で働きはじめて5年目の会社員。システム企画/要件定義/システムアーキテクチャ等。

Twitter→@bun_sugi

過去の記事について

はてなブログに掲載の記事(主にプログラミングメモ)についてはこちらに掲載しております。(本ブログに移行中)

タグ一覧

関連記事

Copyright© 2023, エンジニアを目指す日常ブログ

お問い合わせ|プライバシーポリシー