ecs-cli バージョン指定してインストール

完全な備忘録です。

経緯

6月に入って数日、
ecs-cli の latest をインストールすると latest が 1.6.0 となり
ecs-cli compose ... を実行すると以下のようなエラーが出るようになりました。

1
level=error msg="Unable to open ECS Compose Project" error="Volume driver is not supported"

1.4.0 では問題なかったタスク定義でしたが
1.6.0 では Volume driver is not supported となったそうで処理がこけるようになりました。

その対応として 1.4.0 にバージョン固定した設定です。

続きを読む
AWS ECS prefix 指定してまとめてタスク登録解除
AWS Vault で複数アカウントにMFA認証通過

AWS Vault で複数アカウントにMFA認証通過

AWS Vault とは?

AWS Vault は IAM の認証情報 (Access Key Id, Secret Access Key) を安全に OS のキーストアに保存しアクセスできる仕組みを提供するツールです。

Vault = 金庫 というだけあって
PC 落としても秘匿情報が漏れにくい仕組みにしてくれます。

今回の目的

AWS Vault で複数アカウントのコンソールログインを簡単にしたいと思います。

続きを読む

続 ECR にログイン(aws ecr get-login)無しでプッシュする

概要

前回 ECR への Docker イメージをプッシュする際の認証コマンドを実行せずにプッシュできる様にしました。

ECR にログイン(aws ecr get-login)無しでプッシュする

ですが、
設定が手間というのがあり、CircleCI, AWS CodeBuild 等でワンライナーでささっと書きたいときには不便です。

解決

awscli profile で設定した profile を利用し ecs-cli を利用することで認証をよろしくやってくれます。

1
ecs-cli push <image> --aws-profile <profile> --region <region>

設定 Step

1
2
3
aws configure set --profile hogehoge aws_access_key_id $ACCESS_KEY_ID
aws configure set --profile hogehoge aws_secret_access_key $SECRET_ACCESS_KEY
aws configure set --profile hogehoge region ap-northeast-1
1
2
3
ecs-cli push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/stg-mogemoge-rails:latest \
--aws-profile hogehoge \
--region ap-northeast-1

以上で aws ecr get-login を使用せず、ECR へプッシュができる様になりました♪

docker build 時に Text file busy で shell が実行できない対策

docker build 時に Text file busy で shell が実行できない対策

概要

Dockerfile 内に以下のように shell の実行を記述していました。

1
2
RUN chmod +x hoge.sh \
&& hoge.sh

上記記述のある状態で docker build 実行した所、以下のようなエラーに遭遇しました。

1
/bin/sh: hoge.sh: Text file busy

What is Text file busy ?

書き込みのために現在開いている手続きのみの (共用テキスト) ファイルを実行しようとした場合や、実行中の手続きのみのファイルを書き込みのために開こうとしたり、削除しようとしたりする場合に発生します。

上記鑑みると
chmod +x hoge.sh 実行中に hoge.sh を実行しようとしたが為に発生しているということ??
と推測。

環境情報

  • Ubuntu 14.04.5 LTS \n \l
  • Docker version 17.05.0-ce, build 89658be
  • Base Image: ruby:2.5-alpine

対策

以下 sync 処理を追加し無事問題解決できました。

1
2
3
RUN chmod +x hoge.sh \
&& sync \
&& hoge.sh

What is sync command ?

参考

curl で FTPS (File Transfer Protocol over SSL/TLS) 接続確認

curl で FTPS (File Transfer Protocol over SSL/TLS) 接続確認

以下コマンドで FTPS 接続確認ができます。

1
curl -u <user> --ftp-ssl -k ftp://<ftp domain>/

概要

備忘録記事です。

社外向けに FTPS で接続許可をする必要があり設定しました。

単純に作成・更新した user, password で認証をパスできるか、
の確認だけができれば良いので、その確認方法を模索している時に
程よいコマンドがありました。

その接続確認を FileZilla, Cyberduck でしましたが
どうもうまくいかず。。

改めて、 lftp とか色々 ftp だけでもコマンドは多々あるんだなと実感しました。

Linux に rbenv をセットアップして ruby バージョンを切り替える

Linux に rbenv をセットアップして ruby バージョンを切り替える

概要

サーバの ruby のバージョンが古かった為、
rbenv で ruby のバージョンを切り替える様にした際の設定メモです。

setup rbenv

1
2
3
4
5
6
7
8
9
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

$ source ~/.bash_profile
$ rbenv --version
rbenv 1.1.1-30-gc8ba27f

rbenv 経由で Ruby 2.5.0 インストール

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ rbenv install 2.5.0

// 現 version は system. まだ 2.5.0 に切り替わっていない
$ rbenv versions
* system (set by /home/vagrant/.rbenv/version)
2.5.0

// 2.5.0 へ切り替え
$ rbenv global 2.5.0

// 切り替え確認
$ rbenv versions
system
* 2.5.0 (set by /home/vagrant/.rbenv/version)

$ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

// リフレッシュしないと .rbenv/versions/2.5.0/bin 以下のパスを通らない
$ rbenv rehash
ECR にログイン(aws ecr get-login)無しでプッシュする

ECR にログイン(aws ecr get-login)無しでプッシュする

概要

Docker version 1.11 で実装された credential-helper を利用し
ECR へのプッシュを安全に簡易的に行う仕組みを実装します。

Docker ver 1.11 以上にアップグレード

1
2
3
4
5
6
7
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ sudo sh -c "echo deb https://apt.dockerproject.org/repo ubuntu-trusty main\
> /etc/apt/sources.list.d/docker.list"
$ sudo apt-get purge lxc-docker docker
$ sudo apt-get update
$ sudo apt-get install docker-engine
$ sudo service docker restart

pull Dockerized ECR credential helper

1
$ docker pull pottava/amazon-ecr-credential-helper

認証設定

以下 3 つの中から 1 つ利用ください。
EC2 であれば、1. インスタンスロールで認証 が一番すっきりしていてコードの見通しが良いです。

  1. インスタンスロールで認証
  2. credential で認証
  3. 環境変数で認証

1. インスタンスロールで認証

1
2
3
docker run --rm \
-e REGISTRY=123457689012.dkr.ecr.us-east-1.amazonaws.com \
pottava/amazon-ecr-credential-helper
1
2
3
4
5
6
7
8
9
10
sudo sh -c 'cat << EOF > /usr/bin/docker-credential-ecr-login
#!/bin/sh
SECRET=\$(docker run --rm \\
-e METHOD=\$1 \\
-e REGISTRY=\$(cat -) \\
pottava/amazon-ecr-credential-helper)
echo \$SECRET | grep Secret
EOF'

sudo chmod +x /usr/bin/docker-credential-ecr-login

2. credential で認証

1
2
3
4
docker run --rm \
-e REGISTRY=123457689012.dkr.ecr.us-east-1.amazonaws.com \
-v $HOME/.aws/credentials:/root/.aws/credentials \
pottava/amazon-ecr-credential-helper
1
2
3
4
5
6
7
8
9
10
11
sudo sh -c 'cat << EOF > /usr/bin/docker-credential-ecr-login
#!/bin/sh
SECRET=\$(docker run --rm \\
-e METHOD=\$1 \\
-e REGISTRY=\$(cat -) \\
-v $HOME/.aws/credentials:/root/.aws/credentials \\
pottava/amazon-ecr-credential-helper)
echo \$SECRET | grep Secret
EOF'

sudo chmod +x /usr/bin/docker-credential-ecr-login

3. 環境変数で認証

  • 環境変数セット
1
2
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
1
2
3
4
5
docker run --rm \
-e REGISTRY=123457689012.dkr.ecr.us-east-1.amazonaws.com \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
pottava/amazon-ecr-credential-helper
1
2
3
4
5
6
7
8
9
10
11
sudo sh -c 'cat << EOF > /usr/bin/docker-credential-ecr-login
#!/bin/sh
SECRET=\$(docker run --rm \\
-e METHOD=\$1 \\
-e REGISTRY=\$(cat -) \\
-e AWS_ACCESS_KEY_ID \\
-e AWS_SECRET_ACCESS_KEY \\
pottava/amazon-ecr-credential-helper)
echo \$SECRET | grep Secret
EOF'
sudo chmod +x /usr/bin/docker-credential-ecr-login

credential 保存設定

1
2
3
4
5
6
7
mv $HOME/.docker/config.json $HOME/.docker/config.json.org

cat << EOF > $HOME/.docker/config.json
{
"credsStore": "ecr-login"
}
EOF

これで aws ecr get-login から解放されます ♪

AWS ECS トラブルシューティング

ECS を利用していて幾つかはまったポイントがあったのでまとめました。

started 1 task が複数回実行されるが、コンテナが起動しない

1
2
3
4
5
$ ecs-cli compose service up ...

level=info msg="(service hogehoge) has started 1 tasks ..."
level=info msg="(service hogehoge) has started 1 tasks ..."
level=info msg="(service hogehoge) has started 1 tasks ..."

ecs-cli compose service up でデプロイ時にタスク起動を実行するものの、起動が正しくできていない状態です。
こちらはコンテナ起動時の処理に問題がある場合があります。

  • コンテナログを確認して、コンテナ起動失敗時刻付近のログを確認してください。
  • 例えば、Nginx の設定ファイル, Rails のコードに typo, syntax error がある等です。

already using a port required by your task

1
2
service hogehoge was unable to place a task because no container instance met all of its requirements.
The closest matching container-instance a1b2c3d4-e5f6-g7h8-j9k0-l1m2n3o4p5q6 is already using a port required by your task

port mapping を以下の様に設定していた。

1
2
3
4
5
6
7
"portMappings": [
{
"hostPort": 0,
"protocol": "tcp",
"containerPort": 80
}
],

新しいタスクでも 0:80 のポートを利用しようとする為、エラーとなります。
以下の様に設定することで回避できました。

1
2
3
4
5
"portMappings": [
{
"containerPort": 80
}
],

insufficient memory available

1
INFO[0031] (service hogehoge) was unable to place a task because no container instance met all of its requirements. The closest matching (container-instance a1b2c3d4-e5f6-g7h8-j9k0-l1m2n3o4p5q6) has insufficient memory available. For more information, see the Troubleshooting section of the Amazon ECS Developer Guide.  timestamp=2018-03-09 15:45:24 +0000 UTC

タスク更新(ecs-cli compose service up)実行時、
上記の様なメモリ不足が出る場合はインスタンスタイプを上げる、また、他タスクを削除する等、メモリーリソースを増やす対応が必要です。

no space on device

no space on device で イメージを pull できない。

df -hT コマンドで 容量の使用状況確認

未使用のコンテナ・ボリュームを強制削除しお掃除

1
docker system prune -af --volumes

msg=”Couldn’t run containers” reason=”RESOURCE:CPU”

1
msg="Couldn't run containers" reason="RESOURCE:CPU"

タスクで指定している cpu (vCPU) が不足しています。
インスタンスタイプを上げる、もしくは、他タスクを削除する等、 CPU リソースを増やす対応が必要です。

Fargate - Port Mapping Error

1
level=error msg="Create task definition failed" error="ClientException: When networkMode=awsvpc, the host ports and container ports in port mappings must match.\n\tstatus code: 400, request id: a1b2c3d4-e5f6-g7h8-j9k0-l1m2n3o4p5q6"

起動タイプ Fargate で以下の様な設定だと、NG

1
2
ports:
- "80"

こちらだと OK。

1
2
ports:
- "80:80"

ホストポートとコンテナポートのマッピングが必要です。

Fargate volume_from は利用できない

volume_from は Fargate では使用できません。

1
level=error msg="Create task definition failed" error="ClientException: host.sourcePath should not be set for volumes in Fargate.\n\tstatus code: 400, request id: a1b2c3d4-e5f6-g7h8-j9k0-l1m2n3o4p5q6"

指定された IAM Role が適切なパーミッションを与えられていない

IAM Role に権限を適宜付与します。

1
2
level=info msg="(service hogehoge) failed to launch a task with (error ECS was unable to assume the role 'arn:aws:iam::123456789012:role/ecsTask
ExecutionRole' that was provided for this task. Please verify that the role being passed has the proper trust relationship and permissions and that your IAM user has permissions to pass this role.)." timestamp=2018-06-21 08:15:43 +0000 UTC

イメージ pull できないというエラーも権限を付与していないことに起因することが主です。

1
CannotPullContainerError: API error (500): Get https://123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/v2/: net/http: request canceled while waiting for connection"

現在稼働している ECS の IAM Role の権限を参考してください。変更される可能性があるのであくまで参考にし、適宜最新の情報を以ってご対応ください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogStream",
"logs:CreateLogGroup",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:Describe*",
"elasticloadbalancing:DeregisterTargets",
"ecs:UpdateService",
"ecs:Submit*",
"ecs:StartTelemetrySession",
"ecs:StartTask",
"ecs:RunTask",
"ecs:RegisterTaskDefinition",
"ecs:RegisterContainerInstance",
"ecs:Poll",
"ecs:ListTasks",
"ecs:DiscoverPollEndpoint",
"ecs:DescribeTasks",
"ecs:DescribeServices",
"ecs:DescribeContainerInstances",
"ecs:DeregisterContainerInstance",
"ecs:CreateService",
"ecr:UploadLayerPart",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:GetAuthorizationToken",
"ecr:CompleteLayerUpload",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ec2:Describe*"
],
"Resource": "*"
}
]
}

以上です。

また何か発生したら追記していきたいと思います。

Reference

Datadog Agent 6系にアップデートして Logging 機能を試す!

Datadog Agent 6系にアップデートして Logging 機能を試す!

Datadog Agent 6 系にアップデートして Logging 機能を試す!

2017 年末に β 版ですが、Datadog の Log 可視化ツールの利用が発表されました。

  • Unifying the views でグラフの高負荷時刻付近のログを参照する機能があったり
  • Elasticsearch+Fluentd の代替として期待できそう

と思い早速導入してみました。

datadog-agent インストール方法

2018 年 1 月 10 日時点では 5 系がインストールされます。

5 系、6 系とで主に変わった点

  • Datadog 設定ファイルパス変更
5 系 6 系
ベースディレクトリ /etc/dd-agent /etc/datadog-agent
各種設定ファイル /etc/dd-agent/conf.d/nginx.yaml /etc/dd-agent/conf.d/nginx.d/conf.yaml
メトリクス情報 dd-agent info datadog-agent status

6 系では dd-agent コマンドがありませんでした。

  • dd-agent configcheck に該当するコマンドが見当たらない?
    どこにあるのか教えてください(;>_<)

5 系からのアップグレード方法

https://github.com/DataDog/datadog-agent/blob/master/docs/beta.md

自身の環境は Ubuntu 16.04.2 LTS だったので以下方法でアップグレードしました。

1
2
3
4
5
$ DD_UPGRADE=true bash -c "$(curl -L https://raw.githubusercontent.com/DataDog/datadog-agent/master/cmd/agent/install_script.sh)"

...
Error: /etc/datadog-agent/datadog.yaml seems to contain a valid configuration, run the command again with --force or -f to overwrite it
Automatic import failed, you can still try to manually run: datadog-agent import /etc/dd-agent /etc/datadog-agent

Error と出るので一瞬ハッとしましたが、Error Message をよく見ると
6 系の /etc/datadog-agent/datadog.yaml は問題ない設定となっている様に見えますが、上書きしたい場合は –force を使ってね、
とあります。

datadog-agent のアップグレードは無事完了していました。

1
2
3
4
5
6
7
8
9
$ sudo datadog-agent status

Getting the status from the agent.

===================
Agent (v6.0.0-rc.2)
===================
...
...

また各種設定(/etc/datadog-agent/conf.d, checks.d)ファイルも問題なく移行できていました。

5 系の設定ファイルを 6 系へオーバーライド

特に上記の手法で問題ないですが強制的にオーバーライドする方法を明記しておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// /etc/dd-agent/conf.d 以下のファイルを 6系へ移行
$ /opt/datadog-agent/bin/agent/agent import /etc/dd-agent /etc/datadog-agent --force

Success: imported the contents of /etc/dd-agent/datadog.conf into /etc/datadog-agent/datadog.yaml
Copied conf.d/http_check.yaml over the new http_check.d directory
Copied conf.d/network.yaml over the new network.d directory
Copied conf.d/nginx.yaml over the new nginx.d directory
Copied conf.d/process.yaml over the new process.d directory
Copied conf.d/process_check.yaml over the new process_check.d directory
Copied conf.d/ssl_check_expire_days.yaml over the new ssl_check_expire_days.d directory
Copied conf.d/unicorn_check.yaml over the new unicorn_check.d directory
Error: unable to list auto_conf files from /etc/dd-agent: open /etc/dd-agent/conf.d/auto_conf: no such file or directory

// /etc/dd-agent/checks.d/ 以下のファイルを 6系へ移行
$ sudo -u dd-agent -- cp /etc/dd-agent/checks.d/*.py /etc/datadog-agent/checks.d/

nginx log を Logging へ送付

  • /etc/datadog-agent/conf.d/nginx.d/conf.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
init_config:

instances:
- nginx_status_url: http://localhost/nginx_status/

logs:
- type: file
service: hogehoge
path: /var/log/nginx/access.log
source: nginx
sourcecategory: nginx_access

- type: file
service: hogehoge
path: /var/log/nginx/error.log
source: nginx
sourcecategory: nginx_error

基本的に logs ディレクティブを記述することで OK

  • /etc/datadog-agent/conf.d/fluentd.d/conf.yaml
1
2
3
4
5
6
7
8
9
10
11
12
init_config:

instances:
- monitor_agent_url: http://localhost:24220/api/plugins.json
tag_by: type

logs:
- type: file
service: hogehoge
path: /var/log/td-agent/td-agent.log
source: td-agent
sourcecategory: td-agent

datadog.conf 修正

/etc/datadog-agent/datadog.yaml に以下設定を加えます。

1
log_enabled: true

設定反映

1
$ sudo systemctl restart datadog-agent

うまく Datadog に反映されないときは

ログを見てみます。

1
2
3
4
5
$ sudo tail -f /var/log/datadog/agent.log

...
2018-01-07 11:01:58 JST | INFO | (logs-agent.go:75 in func1) | open /var/log/nginx/access.log: permission denied
...

パーミッションエラーが発生しており
datadog-agent を起動している dd-agent ユーザからアクセスできない状態となっていました。

対処

単純に /var/log/nginx/access.log に 0644 (-rw-r–r–) を付与するだけでなく、
logrotate で生成される新たな log のパーミッションにも注意します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0644 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}

元々 0640 でしたが 0644 で生成するようにしました。
これにて解決 ♪

Datadog Logging で確認

ログが流れてくるのを確認できました。
Kibana の Discover ページのような作りです。

今後フィルタリングしてグラフを作ったりできたりしてくるのか、
Pro 版なら無料で使わせてもらえないかな、
なんて期待が高まっております

お願い、Datadog さん(-人-)