kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

dockerfileのARGの使い方おぼえがき

ARGとは

build実行時にオプション --build-arg として渡せる可変の値

使いみち

環境毎になにかを変える時に使用する

  • ビルド時に使用する環境変数
  • entrypoint.sh
  • COPY元

など

Dockerfileでの定義方法

ARG hoge="fuga"

解説

上記は、変数 hoge を時環境変数 HOGE に定義している

  • ARG 変数名 で変数を定義する。ここで定義しない変数は使用できない
  • ARG 変数名=デフォルト値 でデフォルト値も定義可能

変数展開方法

ENV HOGE=$hoge

$変数名 で変数展開される

build実行時に ARG に値を渡す方法

$ docker build . --build-arg hoge=fuga

docker-compose.yml に build-arg を定義する方法

buildargs に定義する

  app:
    build:
      args:
        hoge: fuga

そんなかんじ

Amazon Aurora serverless を知らなかった人が 2019/07 現在の Aurora serverless の最新状況を分かる範囲でまとめた

これの続編

blog.kasei-san.com

Amazon Aurora serverless って何?

インスタンスの管理が不要な Amazon Aurora

決して、serverless 専用の Aurora ではない

サポートしているエンジンは?

  • MySQL 5.6 互換の Amazon Aurora
  • PostgreSQL 10.7+ 互換の Amazon Aurora

Aurora と何が違うの?

  • シンプル
  • スケーラブル
  • 高コスト効率

シンプル

インスタンスの管理が不要なため、Auroraよりも更に運用コストが低下している

スケーラブル

  • 負荷に応じて、自動スケール & (設定によっては)自動停止する
  • Aurora Capacity Unit (ACU) という単位で課金される
    • 最低2、最大384
    • 0.1$/1ACU時間

高コスト効率

上記のスケーラブルのために、負荷が不安定だったり、決められた時間にしか使用しないサーバなどはAmazon Aurora serverlessでコストダウンできる

Amazon Aurora serverless が向いているサービス

  • 社内用のシステムなど、8-17以外の時間は停止しているサービス
  • バッチシステムのように、決められた時間以外は停止しているサービス
  • 開発/ステージング環境

Amazon Aurora serverless で注意すべきこと

  • 停止状態から再開するまでは1分程度掛かる
  • スケール時にはバッファプールがリセットされるため、再応答まで30秒程度掛かる
    • そのため、本番運用中にスケールするのはあまりよろしくない
  • Auroraの一部機能がサポートされていない
    • Amazon S3 バケットからのデータの読み込み
    • Aurora MySQL ネイティブ関数での AWS Lambda 関数の呼び出し
    • 高度な監査
    • Aurora レプリカ
    • バックトラック
    • データベースのクローン化
    • IAM データベース認証
    • クロスリージョンリードレプリカ
    • MySQL DB インスタンスからのスナップショットの復元
    • Amazon S3 からのバックアップファイルの移行
    • Amazon RDS パフォーマンスインサイト
  • リードレプリカが無いので、readだけやたら多いサービスの場合、むしろコスト効率が悪くなる?(要調査

参考リンク

dev.classmethod.jp

👆初回接続に22秒かかることを確認している

dev.classmethod.jp

👆ACU毎の最大コネクション数の調査

www.publickey1.jp

👆「スケールアップまたはスケールダウンは数秒で行われる一方、最初のインスタンスへの接続は25秒前後のレイテンシがあると説明されています」

qiita.com

👆一時停止→復帰、スケールが生じるとバッファプール(バッファキャッシュ)が初期化されるとのこと

感想

24/365で高負荷なサービスで運用するのには難しそう

ユースケースにあるとおり、低頻度利用環境向けのサービスと見るのが良さそう

AWS Systems Manager パラメータストアを使って、ECSのtaskで環境変数を安全に運用する方法

概要

DBのパスワードとかの機密情報をECSのtask実行時の環境変数に入れたい場合、AWS Systems Manager パラメータストアを使うとかんたん&安全

AWS Systems Manager パラメータストア is 何?

AWS Systems Manager パラメータストア は、設定データ管理と機密管理のための安全な階層型ストレージを提供します。パスワード、データベース文字列、ライセンスコードなどのデータをパラメータ値として保存することができます。値はプレーンテキストまたは暗号化されたデータとして保存できます。

ポイント

  • 値を暗号化して保管できる(暗号化はEKSで行われる)
  • APIを使って復号化した値を取得することができる

環境変数とかにパスワードとか入れたい時に便利!

AWS Secrets Manager シークレット というサービスもある

AWSで機密情報を扱いたい時にはどちらかを使えと公式ドキュメントにかかれている

機密データの指定 - Amazon ECS

Amazon ECS を使用すると、AWS Secrets Manager シークレットまたは AWS Systems Manager パラメータストアのパラメータに機密データを保存してコンテナの定義でそれを参照することによって、コンテナに機密データを挿入できます。

結局どちらが良いの?

こちらを参照しながら決めると良いかも

qiita.com

  • Secrets Managerの方が機能が多いけど有料(AWS Systems Managerも使い方によっては有料)
  • 昔はAWS Systems Manager パラメータストアは遅かったらしいが、現在は解決している様子

AWS Systems Manager のパラメータストアで、1 秒間に最大 1,000 件のリクエストがサポートされるようになりました。これにより、多数のパラメータに対してより高い同時アクセスが必要なアプリケーションを実行できるようになります

AWS Systems Manager がより高い API スループットでのパラメーターストアの使用のサポートを開始

ひとまずはAWS Systems Manager パラメータストアを使って、困ったらSecrets Managerに移行することにした

AWS Systems Manager パラメータストアのつかいかた

概要

  1. ロールの設定
  2. 機密情報の設定
  3. containerDefinitions の secrets にて呼び出す

1. ロールの設定

ECSを実行するロールに以下の権限を追加する

        "ssm:GetParameters",
        "kms:Decrypt"

自分の場合、今まで使用していたECS実行用のロールにインラインポリシーとしてアタッチした

(厳密にやるなら、アクセスできる機密情報の範囲をResourceで指定すること)

f:id:kasei_san:20190729093800p:plain

2. 機密情報の設定

AWS System Manager -> パラメータストア -> パラメータの作成 で設定できる

f:id:kasei_san:20190729094102p:plain

「安全な文字列」にしないと、暗号化されないので注意

f:id:kasei_san:20190729094324p:plain

よそのアカウントのKMSキーを使いたい場合は、「別のアカウント」にする

f:id:kasei_san:20190729094352p:plain

3. task Definition の containerDefinitions の secrets にて呼び出す

  • name に機密情報を格納する環境変数名を設定
  • valueFrom に AWS System Manager パラメータストアのパラメータのarnを入力する
    "containerDefinitions": [
        {
            "secrets": [
              {
                "name": "DATABASE_USERNAME",
                "valueFrom": "arn:aws:ssm:us-east-1:*********:parameter/DATABASE_USERNAME"
              },
              {
                "name": "DATABASE_PASSWORD",
                "valueFrom": "arn:aws:ssm:us-east-1:*********:parameter/DATABASE_PASSWORD"
              }
            ],

以上で、task実行時に環境変数に機密情報が格納されます!! 便利 & かんたん!!

dockerfileのCMDやENTRYPOINTでの変数展開について

前提

dockerfileの CMDENTRYPOINT でコマンドを定義する方法は2通りある

  • exec form(推奨) : JSONの配列で定義する ["echo", "${HOGE}"]
    • 直接コマンドが実行される(変数展開が行われない )
  • shell form : 文字列で定義する "echo ${HOGE}"
    • /bin/sh -c を介してコマンドが実行される(変数展開が行われる )

なので、CMDENTRYPOINT で変数展開したい場合、shell form を使用すればよい

exec formで変数展開を行いたい場合

exeform の中で shell を呼び出せば良い

ENTRYPOINT ["/bin/sh", "-c", "echo ${HOGE}"]

参考

おまけ

以下のように定義すると、HOGE は出力されず、空文字が出力される

ENTRYPOINT ["/bin/sh", "-c", "echo", "${HOGE}"]

これは、${HOGE} が、echo ではなく、/bin/sh の第二引数に渡るため

(第二引数は特に何もしない)

CMDとENTRYPOINT違いおぼえがき

きちんと理解したら全然意味が異なるものだった

ENTRYPOINTとは

docker run 時に実行されるコマンドを定義

apacheを起動させるコンテナ(オフィシャルじゃないけど、説明に最適だった)ENTRYPOINT

ENTRYPOINT ["/usr/sbin/apache2"]

docker run した場合 /usr/sbin/apache2 が実行される

  • ただし、--entrypoint オプションで変更可能

これがあるコンテナは、apacheのコンテナの様に単一の用途を持つという印象

CMDとは

docker run 時のコンテナのデフォルトを定義

この、「デフォルト」は2つの意味がある

  • docker run 時の ENTRYPOINTデフォルトの引数
  • docker run 時に デフォルトで実行されるコマンド

例1. ENTRYPOINT のデフォルトの引数

apache のコンテナCMD

CMD ["-D", "FOREGROUND"]

docker run した場合 ENTRYPOINT と合わせて /usr/sbin/apache2 -D FOREGROUND が実行される

もし、docker run に引数を与えた場合、CMD で定義された部分だけが置き換えられる

例えば、docker run -v を実行した場合、コンテナ上では /usr/sbin/apache2 -v が実行される

例2. デフォルトの振る舞い

alpine linuxのコンテナCMD

CMD ["/bin/sh"]

なので、

  • docker run -it とすれば、シェルに入ることができるし、
  • docker run -it echo "hello" とかすれば、任意のコマンドを実行できる

まとめ

  • ENTRYPOINTdocker run 時に実行されるコマンドを定める
  • CMDdocker run 時のデフォルトを定める。デフォルトとは
    • ENTRYPOINT のデフォルトの引数
    • デフォルトで実行されるコマンド

おまけ

ENTRYPOINTCMD 両方が実行可能な場合、CMD は無視される様子

FROM ubuntu:latest
ENTRYPOINT ["/bin/sh", "-c", "echo 123"]
CMD ["/bin/sh", "-c", "echo aaaa"]

これを docker run すると、123 が出力される

感想

メジャーなコンテナのDockerfileを見たけど、CMD 単一定義のものも多いので、そこまで厳密に定めなくても良いような気もしてきた

herokuのビルドをキャンセルする方法

heroku.yml の設定を間違えたりすると、デプロイ後、以下のエラーが出てタイムアウトするまで待たされて困るので、キャンセル方法を調べた

remote: Compressing source files... done.
remote: Building source:
remote: === Fetching app code
remote:
remote: =!= Unknown error

方法

heroku builds プラグインをインストール後、以下のコマンドを実行

heroku builds:cancel --app ${app_name}

heroku builds プラグインのインストール方法

heroku plugins:install heroku-builds

AWS cli で アカウントに紐づいたロールの切り替えをする方法

課題

セキュリティ上の理由等で、普段管理画面上でロールの切り替えを行っているけれど、それをCLI上でやる場合どうするの?

解決方法

ロール切り替え用のprofileを設定して、それを指定してあげれば良い

~/.aws/config

[default]
output = json
region = ap-northeast-1

[profile adminrole]
source_profile = default
role_arn = arn:aws:iam::***:role/AdminRole
region = ap-northeast-1

profile adminrole が、ロール切り替え後のprofile。 role_arn に切り替え先のロールを設定する

確認

profile default の場合

$ aws sts get-caller-identity  --profile default
{   
    "UserId": "********",
    "Account": "*********",
    "Arn": "arn:aws:iam::********:user/lcl-kobayashi"
}

arn が、IAMユーザであることがわかる

profile adminrole の場合

$ aws sts get-caller-identity  --profile adminrole
{   
    "UserId": "********:botocore-session-********",
    "Account": "********",
    "Arn": "arn:aws:sts::********:assumed-role/AdminRole/botocore-session-********"
}

adminrole のprofile の場合、Arnが、IAMロールに変わっている

上記 profile adminrole--profile なしで使用したい場合

環境変数 AWS_PROFILE を使用する

export AWS_PROFILE=adminrole

参考