LoginSignup
25
16

More than 3 years have passed since last update.

初心者でも試せる!DockerをECRにpushしてECS上で動かしてみた

Last updated at Posted at 2019-11-14

概要

前提

Macですすめる
仮想化やDocker概要など基本的な内容は割愛

目的

DevOpsの勉強のため、DockerやECR, ECSをざっくり把握する

ゴール

以下ができるようになること

  • Dockerでのコンテナ起動
  • Docker imageをECRへpush
  • ECSにDockerコンテナのデプロイ

Docker で Nginx を動かしてみる

1. Docker for Macをインストール

  • DockerHubからダウンロードしてインストール
  • インストールされたかの確認
terminal
$ docker version
Client: Docker Engine - Community
 Version:           19.03.2
 API version:       1.40
 Go version:        go1.12.8
 Git commit:        6a30dfc
 Built:             Thu Aug 29 05:26:49 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.2
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.8
  Git commit:       6a30dfc
  Built:            Thu Aug 29 05:32:21 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc8
  GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

2. Dockerfile 作成

今回はnginxを稼働させるコンテナを作るので、下記を行います

  1. nginxの設定・WEBサーバで実行するコンテンツを作成
  2. Dockerfileの作成

最終的に以下のようなディレクトリになります

ディレクトリ構成
.
├── Dockerfile
├── app
│   └── index.html
└── nginx.conf

Webサーバ設定を作成

  • listen: IPアドレス:ポート番号の指定
  • default_server オプション:複数のバーチャルサーバがあるときにデフォルトサーバとなる
  • root: ドキュメントルートを指定する(nginxのデフォルトは/usr/share/nginx/html)
nginx.conf
server {
        listen *:80 default_server;

        location / {
            root /app;
        }
}

WEBサーバで実行するコンテンツを作成

表示する index.html を作成

app/index.html
<html>
    <head>
        <title>hello</title>
    </head>
    <body>
        <p>HELLO WORLD!</p>
    </body>
</html>

Dockerfile作成

  • FROM: ベース・イメージを指定。ここでは軽量化のため、alpine linux をベースにする
  • RUN: イメージ上でコマンド実行。ここではnginx 導入/起動
  • COPY: コンテナ内にホストのファイル/ディレクトリをコピー。ここではWEBページ表示に必要なソースを配置
  • EXPOSE: コンテナ起動時に公開するポートを記載。
    • イメージ作成者とコンテナ実行者の間の一種のドキュメンテーションとして機能し、これだけではホストからコンテナにアクセスできない。
    • コンテナの実行時(docker run)に-pオプション等でポートを公開する必要がある
  • CMD: Docker起動時に実行するコマンド。nginxはデフォルトはデーモンで動くので、フォアグラウンドで動くようにする
Dockerfile
FROM alpine:3.10.3

# nginxのインストール
RUN apk update && \
    apk add --no-cache nginx

# 必要なファイルを配置
COPY app /app
COPY nginx.conf /etc/nginx/conf.d/default.conf

# ポート設定:
EXPOSE 80

RUN mkdir -p /run/nginx

# フォアグラウンドでnginx実行
CMD nginx -g "daemon off;"

3. docker image 作成/確認

作成した Dockerfile からdocker image を作成

  • docker build -t <IMAGE:TAG> <コンテキスト指定>
  • -t: 名前とオプションのタグを指定
  • コンテキスト指定: Dockerデーモンへ送信するディレクトリ指定(Dockerfileは必ず含まれるようにする)
terminal
$ docker build -t test_nginx . 

作成されたimageを確認

terminal
$ docker images
REPOSITORY     TAG        IMAGE ID        CREATED           SIZE
test_nginx     latest     d4a1d35ad05f    10 seconds ago    6.5MB

ここまででDockerコンテナの作成ができました🎉

4. コンテナ起動/動作確認

コンテナの起動

  • docker run -d -p <ホストのポート番号:コンテナのポート番号> --name <コンテナ名> <イメージ名>
  • --name: 任意のイメージ名を指定
  • -d: デタッチド・モードで起動(バックグラウンドでコンテナを実行)
  • -p: ポートの割当(ホスト側ポート:コンテナ側ポート)
terminal
$ docker run -d -p 80:80 --name sample_container test_nginx

コンテナの起動を確認

termina
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
4da8512fc776        test_nginx          "/bin/sh -c 'nginx -…"   11 minutes ago      Up 11 minutes       0.0.0.0:80->80/tcp   sample_container

ブラウザでWEBページ表示確認

ローカルホスト(127.0.0.1:80)で下記ページが表示されていることを確認できればOK!

スクリーンショット 2019-11-12 午後5.32.00.png

※(必要に応じて)コンテナ削除/イメージ削除

コンテナやイメージが不要になった場合は削除しておく

コンテナ削除

terminal
$ docker rm -f <コンテナ名>

イメージ削除

terminal
$ docker rmi -f <イメージ名>

コンテナへの接続

terminal
$ docker exec -it <コンテナ名> <実行コマンド>

例) shellに接続する場合(shell接続後は、exitで抜ける)

terminal
$ docker exec -it <コンテナ名> sh

AWS設定(AWS CLI)

1. IAM でユーザー作成

2. CLIインストール

インストール

pipをインストールしてからaws-cliをインストールする方法もあるが、homebrewでinstall

terminal
$ brew install awscli

インストールされたか確認

terminal
$ aws --version
aws-cli/1.16.9 Python/2.7.16 Darwin/17.7.0 botocore/1.11.9

環境変数の設定(pathを通す)

terminal
$ vi ~/.bash_profile

以下を追記
export PATH=~/.local/bin:$PATH

3. AWS CLIアカウント設定

  • IAMでアクセスキーを作成
  • 認証情報登録 -> 設定ファイル(~/.aws/config, ~/.aws/credentials )が作成される
terminal
$ aws configure
AWS Access Key ID [None]: 作成したアクセスキー ID
AWS Secret Access Key [None]: 作成したアクセスキーのシークレットアクセスキー
Default region name [None]: ap-northeast-1
Default output format [None]: 

profile確認/設定

設定を確認すると、default とうプロファイルで定義されている

terminal
$ less ~/.aws/config
[default]
output = json
region = ap-northeast-1

AWS CLIコマンドを利用する際、プロファイルを指定しなければ、[default]設定が利用される。
defaultのプロファイルではない場合、何度もプロファイルを指定するのが面倒なので、
以下のようにシェルセッションの終了時まで変数に持たせておくと便利

terminal
$ export AWS_PROFILE=利用したいプロファイル名

Amazon ECR へ Docker image を Push

1. リポジトリ作成

  • リージョンやリポジトリは何度も利用するので変数に持たせておく
terminal
$ REPOSITORY_NAME=sample-docker
$ AWS_REGION=ap-northeast-1
  • リポジトリ作成
terminal
$ aws ecr create-repository --repository-name ${REPOSITORY_NAME} --region ${AWS_REGION}
  • リポジトリ確認
terminal
$ aws ecr describe-repositories --region ${AWS_REGION}
{
    "repositories": [
        {
            "repositoryArn": "arn:aws:ecr:ap-northeast-1:***********:repository/sample-docker",
            "registryId": "***********",
            "repositoryName": "sample-docker",
            "repositoryUri": "***********.dkr.ecr.ap-northeast-1.amazonaws.com/sample-docker",
            "createdAt": 1573385404.0,
            "imageTagMutability": "MUTABLE"
        }
    ]
}
  • レジストリIDは頻繁に利用するので、環境変数に保持
terminal
$ REGISTRY_ID=作成したリポジトリID

2. デフォルトレジストリに対して Docker を認証する

aws cli コマンドと、Dockerコマンドは別のコマンドなので、それぞれの認証が必要。
aws cli コマンドでDocker認証情報を取得し、DockerコマンドでECRへログインする

ECR レジストリに対し Docker クライアントで認証

  • 下記コマンドのレスポンスに、ログイン用コマンドが表示されるので、それをそのまま実行するとログイン完了
  • 対象レジストリで12時間有効な認証トークンが提供される
terminal
$ aws ecr get-login --region ${AWS_REGION} --no-include-email

※以下のように実行結果を出力し展開するようにすると一回で完了

terminal
$ $(aws ecr get-login --region ${AWS_REGION} --no-include-email)

3. コンテナ名変更/image に tag つけ

  • イメージ名は、使用する Amazon ECR レジストリ、リポジトリ、オプションのイメージタグ名の組み合わせによって変わり、名称を一致させる必要がある
  • コンテナ/tag命名規則: {レジストリID}.dkr.ecr.{リージョン}.amazonaws.com/{リポジトリ名}:{タグ名}
terminal
$ docker tag test_nginx ${REGISTRY_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPOSITORY_NAME}}:v1.0

4. image を push

terminal
$ docker push ${REGISTRY_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPOSITORY_NAME}:{タグ名}

5. ECR にアップした image を確認

terminal
$ aws ecr list-images --repository-name ${REPOSITORY_NAME} --region ${AWS_REGION}
{
    "imageIds": [
        {
            "imageDigest": "sha256:*********************************************",
            "imageTag": "v1.0"
        }
    ]
}

6. image を pull

terminal
$ docker pull ${REGISTRY_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPOSITORY_NAME}:{タグ名}

7. イメージを削除

terminal
$ aws ecr batch-delete-image --repository-name ${REPOSITORY_NAME} --image-ids imageTag={タグ名}

8. リポジトリを削除

  • リポジトリに保存するデータとインターネットに転送するデータの量で料金発生なので、不要な場合は削除しておく
terminal
$ aws ecr delete-repository --repository-name ${REPOSITORY_NAME} --region ${AWS_REGION}

補足

aws cli で docker image を push するために必要な条件

  • docker の最小バージョン 1.7 がインストールされている
  • Amazon ECR 認証トークンが docker login で設定されている
  • Amazon ECR リポジトリが存在し、リポジトリにプッシュするアクセス権がユーザーにある

ここまでで、ECRに対して docker pull/push/delete ができました🎉

Amazon ECS で Docker を起動

1. キーペア作成

ECS では、EC2 起動タイプを使用する場合にのみキーペアが必要
※UI以外から接続することでエラーでインスタンスが落ちたときなどにログを追うこともできます

2. ECSクラスターの作成

EC2インスタンスの作成

項目 内容
AMI Amazon ECS-Optimized Amazon Linux 2 AMI
インスタンスタイプ t2.micro
IAMロール 新しい IAM ロールを作し、Amazon EC2 Container Service Role中のAmazonEC2ContainerServiceRoleのロールを割り当てる
セキュリティグループの設定 HTTP TCP 80 0.0.0.0

クラスターの作成

項目 内容
クラスターテンプレート EC2 Linux + ネットワーキング
クラスター名 sample-cluster
プロビジョニングモデル オンデマンドインスタンス
EC2 インスタンスタイプ t2.micro
インスタンス数 1
EC2 Ami Id Amazon Linux 2 AMI
キーペア 手順1で作成したキーペアを利用
コンテナインスタンス IAM ロール EC2インスタンス作成時に割り当てたロールを選択

3. タスク定義作成

項目 内容
起動タイプの互換性 EC2
タスク定義名 sample-task

コンテナ追加箇所の設定

項目 内容
コンテナ名 sample-container
イメージ ECRにpushしている対象イメージのURIを入力
メモリ制限(MB) ハード制限 128
ポートマッピング ホストポート 80, コンテナポート 80, プロトコル tcp

4. タスクの実行

  • 作成したクラスター(sample-cluster)をクリック
  • [タスク]の項目から[新しいタスクの実行]をクリック
  • タスク定義
項目 内容
起動タイプ EC2
タスク定義 作成したタスク(sample-task)
クラスター 作成したクラスター(sample-cluster)
タスクの数 1
  • [タスクの実行]をクリック
  • ステータスが[RUNNING]になっていることを確認 スクリーンショット 2019-11-13 23.17.26.png

5. 表示確認

  • コンテナインスタンスのパブリック DNSに接続してうまく表示されればOK!

まとめ

  • Dockerでのコンテナ起動 -> 環境構築をお手軽に!
  • Docker imageをECRへpush -> チーム内で開発環境を共有可能に! 
  • ECSにDockerコンテナのデプロイ -> クラウド上でDockerコンテナを利用しサービスを稼働させられる!

参考

AWS CLIを使ってECRにDockerイメージを登録する
Amazon ECS入門 〜公式のDockerイメージを使って10分で構築してみる〜
Amazon ECR で AWS CLI を使用する

25
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
16