あきろぐ

いろいろめもするよ🐈🐈🐈

ECSタスクのCPUとメモリをチューニングする

ECSのtask定義のメモリとCPUをチューニングするときのメモ

メモリ制限

メモリは「ハード制限」と「ソフト制限」があり、2つの値を設定するとき必ず「ハード制限>ソフト制限」である必要がある。

  • 「ソフト制限」は、コンテナに予約するメモリ量(MiB)
  • 「ハード制限」は、メモリ使用量がこの値を超えると強制的にコンテナが終了するメモリ量(MiB)
    • ハード制限を設定することで一時的にメモリ使用量がバーストしても使うことができる

適正値がわからない場合、以下の範囲から始めると良いと言われている。

ECS ではウェブアプリケーション用に 300〜500 MB から始めることをお勧めします。

CPUユニット

  • ECSコンテナエージェントがコンテナ用に予約したCPUユニット数
  • コンテナインスタンス(EC2)にはCPUコアごとに1024ユニットある
  • 下記リンクにあるインスタンスタイプのvCPU数に1024かけることで使用可能なCPUユニット数を算出することができる

aws.amazon.com

チューニング方法

ECSのメモリとCPUのメトリクスは、サービスごとに監視しているので、Amazon開発ガイドに記載されている「サービス使用率」を使ってメモリとCPUをチューニングしていく。
それぞれ、現在のサービス使用率、タスクに割り当てているメモリ、CPU、サービスのタスク数が分かっているので、現在の使用率を算出することが可能である。

f:id:akngo22:20200303225306p:plain
サービスCPU使用率

f:id:akngo22:20200303225431p:plain
サービスメモリ使用率

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cloudwatch-metrics.html#cluster_utilization

# CPU使用率が90%で割り当てCPUユニットが500、タスク数が2出会った場合
90=(100x/500*2)
x=900
つまり、1つのタスクあたり450CPUユニット使用していることがわかる

# メモリ使用率
メモリ使用率も算出の仕方はCPUと同様
ソフト制限を指定した場合、メモリ使用率を求めるためにその制限値が計算に使われ、ハード制限を指定した場合はハード制限に設定したメモリ量が使われる

使用率をどの程度に抑えたいかで割り当てるCPUユニットやメモリ量を変更することができる。

awsコマンドの'ecr get-login'が非推奨になったので'ecr get-login-password'を試す

概要

クラメソさんの記事を読んでaws ecr get-loginがv1では非推奨、v2では使えなくなっていることを知ったので、自分の環境どうだったか確認をかねて新しいコマンドecr get-login-passwordを使ってみました。

dev.classmethod.jp

自分の環境

自分のawsコマンドのバージョンどうだったけ?と思ったので確認しましたが、まだv1でした。

~ $ aws --version
aws-cli/1.16.274 Python/3.6.6 Darwin/18.7.0 botocore/1.13.10

v1.17以下だとecr get-login-passwordが使えないのでアップグレードします。

# アップグレード
~ $ pip install --upgrade awscli

# バージョン確認
~ $ aws --version
aws-cli/1.18.0 Python/3.6.6 Darwin/18.7.0 botocore/1.15.0

確認

v1.18にアップデートされたので、試してみます。 まずは、get-loginのときの出力は以下の通りですね。ログインするための情報がコマンドラインで返ってきます。

~ $ aws-vault exec my-profile -- aws ecr get-login
docker login -u AWS -p [password]

新しいコマンドを使うと以下のように、パスワードだけ返ってきます。

~ $ aws-vault exec my-profile -- aws ecr get-login-password
[password]

Dokcerコマンドとパイプを使えば、セキュアな情報をターミナル上に表示させることなくログインすることが可能です。

~ $ aws-vault exec my-profile -- aws ecr get-login-password | docker login -u AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com
Login Succeeded

あとは普段通りdocker pullなど実行すればOK

~ $ docker pull [aws-account-id].dkr.ecr.ap-northeast-1.amazonaws.com/my-image:xxxxx
xxxxx Pulling from my-image

get-loginのコマンドリファレンスにも、このコマンドを使うとセキュアな情報が他人に見えてしまうので、セキュアな環境ではない限り使わないようにと書かれていますね。他にも使っているところあったら置きかえよう。。。

以上です。

参考文献

ansible-playbookのwith_itemsが肥大化するのを防ぎたい

概要

Ansible-playbookの1つのタスクで複数のユーザーを作成したり、色んなパッケージをインストールしたいときに役立つのがループ処理です。その代表的なパラメータがwith_itemsではありますが、このパラメータもうまく使わないとwith_itemsに羅列するパラメータが膨大になってしまい、1つのタスクだけ長ったらしくなります。 簡潔なタスクを書くためにwith_itemsの使い方を工夫したのでそのときのメモです。

docs.ansible.com

環境

  • MacOS 10.14.6
  • Ansible 2.5.0

解決案

以前のタスクの書き方

最初は以下のようなタスクを書いていました。 環境変数の設定で変数名を被らせることはできないので、どんどんwith_items以下が増える一方でした。

# 変数yamlファイル
test1: xxx
test2: xxx
test3: xxx
test4: xxx

# main.yml
- name: setting env
  lineinfile:
    dest: /etc/environment
    line: "export {{ item }}={{ lookup('vars', item) }}"
  with_items:
    - test1
    - test2
    - test3
    - test4

新しい書き方

変数定義の書き方をちょっと工夫すれば、タスクを簡潔に書くことができるようになりました。 辞書型の変数env_listに環境変数名とその値を入れ込むことで、タスクをかなりスッキリした形で書くことができます。

# 変数yamlファイル
env_list:
    - name: test1
      value: xxx
    - name: test2
      value: xxx
    - name: test3
      value: xxx
    - name: test4
      value: xxx

# main.yml
- name: setting env
  lineinfile:
    dest: /etc/environment
    line: "export {{ item.name }}={{ item.value }}"
  with_items: {{ env_list }}

追記

もっと良い書き方がありました。 上記の書方だと、変数をnamevalueで設定しないといけないので、ちょっとめんどくさいんですよね。そこで、with_itemsではなくてwith_dictを使うことで変数名と値をkeyvalueで取り出すことが可能となり以下のようにすっきり書くことができます。

# 変数yamlファイル
env_list:
  - test1: xxx
  - test2: xxx
  - test3: xxx
  - test4: xxx

# main.yml
- name: setting env
  lineinfile:
    dest: /etc/environment
    line: "export {{ item.key }}={{ item.value }}"
  with_dict: {{ env_list }}

以上

ECRのDockerイメージをローカルにプルしてビルドする

概要

デバッグするために、ECRにあげているDokcerイメージをローカルにプルしてビルドするまでのメモ。

環境

  • mac10.14.6
  • aws-vaultコマンドをインストールしている

手順

AWS ECRにログインする

下記コマンドを実行するとDokcerにログインするためのアクセストークンが返ってくるので、そのトークンを使ってECRにログインする。

# アクセストークンを取得する
$ aws-vault exec my-profile -- aws ecr get-login --no-include-email --region ap-northeast-1

docker login -u AWS -p [password] https://[aws_account_id].dkr.ecr.ap-northeast-1.amazonaws.com

$ docker login -u AWS -p [password] https://[aws_account_id].dkr.ecr.ap-northeast-1.amazonaws.com
~
Login Succeeded

Login Succeededと返って来ればログイン成功している。

Dockerイメージをプルする

ECR>リポジトリ>対象イメージ>イメージのURIをコピーする
f:id:akngo22:20200208211711j:plain
下記コマンドを実行してイメージをプルする

# イメージをプル
$ docker pull [aws_account_id].dkr.ecr.ap-northeast-1.amazonaws.com/my-docker-image/app:xxxx

# イメージ確認
$ docker image ls

Dockerビルドを実行する

ローカルにプルしてきたイメージを使ってビルドし、コンテナの中に入る

$ docker build -it [aws_account_id].dkr.ecr.ap-northeast-1.amazonaws.com/my-docker-image/app:xxx /bin/bash


以上