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 さん(-人-)

Datadog で Rails Unicorn の Memory, Idle|Busy Worker 監視 〜呉越同舟〜

Datadog で Rails Unicorn の Memory, Idle|Busy Worker 監視 〜呉越同舟〜

概要

Rails の乗っているホストへ Datadog で Unicorn を監視しようとした所、
それらしい Integration がありません((あったら教えてください >_< ))。

ということで独自スクリプトを作成しようと思いました!

独自スクリプトを書こうとしてたら…

同僚「Mackerel なら plugin ありますよ?」

自分「えっ?…」

Mackerel 入ってる

Mackerel に unicorn 監視用の plugin がありました。

mackerel-plugin-unicorn

はてなさんも OSS で出して頂いている、
車輪の再開発は時間の無駄、
人生は一度しかないのでこの Mackerel プラグインを Datadog で使わせて頂こうと思いました。

Mackerel + Datadog 呉越同舟スクリプト

  • /etc/dd-agent/unicorn_check.py
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
from checks import AgentCheck
import subprocess
import re
class UnicornCheck(AgentCheck):
def check(self, instance):
pidfile = instance['pidfile']
cmd = "/usr/bin/mackerel-plugin-unicorn -pidfile=%s" % (pidfile)

res = self.exeCmdWithStripLF(cmd)

for r in res:
y = re.split(r'\t+', r.rstrip('\t'))
metrics = y[0]
out = y[1]
self.gauge(metrics, out)

# コマンド実行結果から改行コードから取り除く
def exeCmdWithStripLF(self, cmd):
res = self.exeCmd(cmd)
return [str(x).rstrip("\n") for x in res]

# コマンド実行
def exeCmd(self, cmd):
return subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
shell=True
).stdout.readlines()
  • /etc/dd-agent/conf.d/unicorn_check.yaml

Unicorn の PID ファイルを指定します。

1
2
3
4
init_config:

instances:
- pidfile: /path/to/rails_project/shared/tmp/pids/unicorn.pid

Datadog Agent 設定ファイルチェック

1
2
3
$ sudo dd-agent configcheck

unicorn_check.yaml is valid

Datadog Agent 再起動

1
$ sudo service datadog-agent restart

数分後グラフを見てみる

出てきた!

総評

これで呉越同舟型モニタリングができました!

自分自身が呉でも越でもない所に若干の背徳感がありますが
手っ取り早く舟をこしらえたことに本記事の意味があるかと
筆を取りました。

参考になれば幸いです。

terraform workspace で環境毎に tfsate 管理

terraform workspace で環境毎に tfsate 管理

terraform workspace で環境毎に tfsate 管理した話です。

追記 2019/04/17

追記時点で workspace は運用時点の問題が多くあった為、利用していません。以下記事ご参考いただければと思います。

概要

Terraform tfstate の管理をかつて
0.8 系では -backend-config でせっせと環境(stg,prod) 毎に bucket を変えて、
なんてコードを見てきました。

ですが、
workspace で 1 つの bucket に 環境毎に保管できる様になりました。

厳密には環境毎でなくとも
リソースの集合毎、module 毎等で管理するイメージですが

今回はイメージを捉えやすく環境毎で分けました。

歴史

  • 0.5 で S3 で管理、
  • < 0.9 では、 remote config で管理場所を設定
  • = 0.9 では、terraform workspace で同一ディレクトリで複数のリソース群を管理

とより利用しやすくなりました。

前提

以下条件とします。

  • tfstate は backend.tf で s3 管理

移行手順

既存 terraform で tfstate 確認

  • 想定の実行計画通りか確認します。
  • 異なる場合は、そもそも現環境と差分が生じている、及び、tfstate が正しく取得できていない等、問題ありなのでそちらを修正します。
1
$ terraform plan

tfstate ファイル取得

local に terraform.tfstate を取得します。
中身を確認してリソースの設定がある程度問題ないか確認しておきます。

  • 0.8 系
1
2
3
4
5
6
$ terraform remote config \
-backend=s3 \
-backend-config="bucket=tfstate.bucket" \
-backend-config="key=terraform.tfstate" \
-backend-config="region=ap-northeast-1" \
-backend-config="profile=aws-hogehoge"
  • 0.9 系以降
1
macOS%$ terraform state pull > terraform.tfstate

terraform 0.11.x (2017 年 12 月現在最新) へバージョンアップ

Homebrew ならば upgrade で!

1
macOS%$ brew upgrade terraform

state 管理を backent.tf で記述

既にこの様に設定されている方はスキップです。特に普遍的な書き方です。

1
2
3
4
5
6
7
8
9
terraform {
backend "s3" {
bucket = "tfstate.bucket"
key = "terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
profile = "aws-hogehoge"
}
}

Workspace 作成

  • Workspace stg 作成
1
$ terraform workspace new stg
  • workspace リスト一覧
1
2
3
$ terraform workspace list
default
* stg

tfstate を push

1
$ terraform state push -force .terraform/terraform.tfstate

これで S3 tfstate.bucketenv:/stg/ ディレクトリ以下に terraform.tfstate が push されました。
実際に S3 を見て確認してみてください。

env でなく env: なのが肝です。

実行計画確認

1
$ terraform plan

想定の実行計画通りか確認して問題なければ移行完了です。

おまけ

terraform を指定したバージョンで実行するには
one-off Container で実行できる様に Makefile でラップする、
が今の所自分の中のベストプラクティスです。

これによって local 環境に依存せず指定したバージョンの terraform 実行が可能となります。

one-off Container とは

one-off Container は Docker コンテナを run --rm で 1 度のコマンド実行の為だけに起動する手法です。

Makefile で Docker コマンドをラップしておくと
TERRAFORM_VERSION を変更するだけで
指定の terraform バージョンを利用できます。

以下は 0.11.1 の例です。

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
TERRAFORM_VERSION=0.11.1

DOCKER=docker run --rm -v ~/.ssh:/root/.ssh:ro -v ~/.aws:/root/.aws:ro -v ${PWD}:/work -w /work hashicorp/terraform:${TERRAFORM_VERSION}

$(eval ENV := $(shell ${DOCKER} workspace show))

ifeq (${ENV}, default)
$(error select workspace ! ex: make init ENV=<stg|prod>)
endif

default: init

init:
# tfstate ファイル初期化
${DOCKER} init
# workspace 作成. "; true" は既に作成済みエラーをスキップする為
${DOCKER} workspace new ${ENV}; true
# 作成した workspace を選択
${DOCKER} workspace select ${ENV}
# 作成した workspace の tfstate ファイルを同期
${DOCKER} init

plan:
${DOCKER} plan

apply
${DOCKER} apply -auto-approve
  • make init ENV=stg 実行で以下まとめてました
    • tfstate 初期化
    • workspace stg 作成
    • 選択した workspace の tfstate で初期化

きっとさらに素敵なベストプラクティスがあれば教えてください!

参考になれば幸いです。

Hubot で Git の Pull Request や Issue のコメントのメンション相手に Slack DM で通知

概要

Git での Pull Request や Issue コメントのメンションがメール通知で気づけず困った!
という声を多く聞き、メンション相手に Slack DM を通知する様な仕組みを作りました。

システム概要

今回は AWS 上に構築しました。

  • Git は GHE on EC2
    • github.com の場合だと、IP 定まらない問題があるかと思うので、動的に IP を取得して解放させる様な仕組みを入れる必要がありそう。
  • hubot は t2.nano と最小
    • 当初、IBM Bluemix で構築してみましたが、サポートから IP 制限はまだできていない、とのことなので on AWS にしました。
  • GHE からの hubot の受け口は ELB で EIP のみ許可させてます。
    • 今後、受け口を色々作る目的で ELB 立てました。
    • 元々は JIRA のメンションを Slack DM に送るだけの目的だったので 同一 Private Subnet に置いてました。

スクリプト

  • getSlackUsernameByGitUsername
    • 基本 git name と slack name は命名規則が統一されていたので正規表現で変換させる様に解決しています。
    • git name: kenzo-tanaka だったら slack name: kenzo.tanaka に変換
    • 命名規則に即していないユーザは以下の users リストに変換を任せます。
      • kimika.himura は DM 送られたくないと言う人を想定してます。
  • 依存ライブラリ
    • “hubot-slack”: “^4.4.0”
    • “hubot-slack-attachement”: “^1.0.1”
1
2
3
4
users = {
"kenzo-tanaka": "kenzo0107",
"kimika.himura": "no_send"
}

ソース全容は以下になります。

Git 設定

設定したい Organization or Owner > Settings > Hooks で hubot への URL を設定します。((Organization 跨いで一気に全部のリポジトリにHookかけるのは別途スクリプト組むなりしないと難しそう。GitHub社も Organization は 1つとすることを推奨とのことなので今回はこれで!))

その他設定

  • Content type: application/json
  • Let me select individual events:
    • Issues
    • Issue comment
    • Pull request
    • Pull request review
    • Pull request review comment

※ よりセキュアにする際には Secret 設定してください。

通知が来た!

早速 Pull Request でメンションしてみたら通知が来ました!
絵文字もしっかり!
URL も自動でリンクされている!

以上、参考になれば幸いです♪

Prometheus2.0 remote storage 検証

Prometheus2.0 remote storage 検証

いよいよ出ました Prometheus 2.0 !

Announcing Prometheus 2.0 | Prometheus

先日モニタリング勉強会でも Paul Taylor さんの LT を拝聴させて頂き
パフォーマンス向上とストレージフォーマット変更による圧縮・バックアップがしやすくなった等、
良い話がたくさん出ていました。

Operating Prometheus

中でも最も期待していた機能が Remote Long-Term Storage、
長期保存機能には歓喜しました ♪

1 系以下では、短期間用と長期間用の Prometheus を別途用意する等、対策が必要で
冗長な作りを余儀なくされたところがありましたが
2.0 リリースでついに!

早速試してみたく使用感をまとめました。

今回やりたかったことまとめ

  • Prometheus 2.0 リリースに際して期待の長期保存機能 (Remote long-term storage) を早速試す!
  • 実際にローカル環境で構築してみて 1 系からの変更箇所を確認
  • DB 側にどんなデータが入るのか確認

システム概要

あくまで使用感の検証をしたかったので docker-compose でお手軽に作れる環境にしました。

前提条件

以下を Vagrant にインストール

  • Ubuntu 16.04.3 LTS \n \l
  • Docker version 17.09.0-ce, build afdb6d4
  • docker-compose version 1.12.0, build b31ff33

起動する Docker Container

  • Prometheus 2.0.0
  • Node Exporter 0.15.1
  • AlertManager 0.9.1
  • cAdvisor 0.28.0
  • Prometheu Adapter
  • PostgreSQL 9.6.3
  • Grafana 4.6.1
  • Nginx 1.13.6
  • Adminer

使い方

以下手順通りです。

kenzo0107/vagrant-docker/tree/vagrant-docker-ubuntu16.04/docker/prometheus-grafana-on-ubuntu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
macOS%$ git clone https://github.com/kenzo0107/vagrant-docker
macOS%$ cd vagrant-docker
macOS%$ vagrant up

// Install docker, docker-compose
macOS%$ vagrant provision
macOS%$ vagrant ssh
vagrant%$ cd /vagrant/prometheus-grafana-on-ubuntu
vagrant%$ sudo docker-compose up -d

Name Command State Ports
-------------------------------------------------------------------------------------------------------------------------------------
adapter /prometheus-postgresql-ada ... Up
adminer entrypoint.sh docker-php-e ... Up 8080/tcp
alertmanager /bin/alertmanager -config. ... Up 9093/tcp
cadvisor /usr/bin/cadvisor -logtost ... Up 8080/tcp
grafana /run.sh Up 3000/tcp
nginx nginx -g daemon off; Up 0.0.0.0:18080->18080/tcp,
0.0.0.0:3000->3000/tcp, 80/tcp,
0.0.0.0:8080->8080/tcp,
0.0.0.0:9090->9090/tcp
node-exporter /bin/node_exporter Up 9100/tcp
pgsql docker-entrypoint.sh -csyn ... Up 5432/tcp
prometheus /bin/prometheus --config.f ... Up 9090/tcp

アクセスしてみる

Prometheus

Grafana

1
2
GF_SECURITY_ADMIN_USER=admin-user
GF_SECURITY_ADMIN_PASSWORD=admin-pass
  • Datasource 設定

Datasource 設定フォームに以下情報を入力し Add ボタンをクリックします。

Item Value
Name Prometheus
Type Prometheus
URL http://prometheus:9090
Access proxy
  • Dashboard.json インポート

グラフが表示されます。

cAdvisor

Adminer

ログインフォームに以下情報を入力します。

Item Value
Server pgsql
Username prometheus
Password password
Database postgres
  • PostgreSQL に保存されているメトリクス情報が確認できます。

PostgreSQL >> pgsql >> postgres >> prometheus >> Select: metrics

AlertManager でアラート通知してみる

例として node-exporter を停止

1
vagrant%$ sudo docker-compose stop node-exporter

./alertmanager/config.yml で設定した Slack Channel にちゃんと通知がきました。

所感

  • 2.0 になって設定の仕方が諸々変わり、公式サイトじっくり見る必要あります。

  • 今回は Prometheus ×1 台構成ですが、2 台以上で冗長化する構成も試してみたい。

余談

あとがき

Mackerel の様なマネージドな監視サービスで運用コストを削減する以上に
Prometheus をマネージドすれば、さらにトータルコストを抑えられる様になる、
と睨んでます。

ですが、Datadog は APM 付きプランも適度なコスト感で提供しておりマネージドサービスの魅力は尚大きいです。

モニタリングの棲み分けをできる様にするにも、
選択肢の一つにするにも Prometheus 挑戦しがいがあるのでは?
と思っています。

Prometheus、今後さらに広まることを期待しています。

参考

iftop でネットワーク接続状況をリアルタイム監視

iftop 概要

CLI上で利用できるネットワークの接続状況をリアルモニタリングするツールです。
→ ネットワークのボトルネックを特定する為に利用します。

単にネットワークのモニタリングであれば、モニタリングツールで良いですが

具体的にどこ(ドメイン・IP・ポート)にどれくらい(データ転送量)がわかります。

インストール方法

  • Ubuntu
1
$ sudo apt-get install -y iftop
  • CentOS
1
2
$ sudo yum -y install epel-release
$ sudo yum -y install iftop

使い方

よく利用するのはこんな形です。
※eth0 がない場合は -i eth0 を除いてください。

1
$ sudo iftop -i eth0 -B -P -n -N
  • -i インターフェース指定
  • -B 表示単位を Byte にする
  • -P プロトコル or ポート表示
  • -n ドメインでなく ip で表示
  • -N プロトコルサービス名でなくポート番号で表示

表示項目

=> が送信、
<= が受信です

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
                           24.4kB                      48.8kB                      73.2kB                      97.7kB                 122kB
+--------------------------+---------------------------+---------------------------+---------------------------+---------------------------
ip-10-13-1-101.ap-northeast-1.compute.internal:http => ip-10-13-100-41.ap-northeast-1.compute.internal:62635 559kB 121kB 67.1kB
<= 3.60kB 1.90kB 1.05kB
ip-10-13-1-101.ap-northeast-1.compute.internal:35244 => ip-10-13-102-56.ap-northeast-1.compute.internal:mysql 0B 2.18kB 1.21kB
<= 0B 23.1kB 12.8kB
ip-10-13-1-101.ap-northeast-1.compute.internal:35247 => ip-10-13-102-56.ap-northeast-1.compute.internal:mysql 0B 2.13kB 1.18kB
<= 0B 23.0kB 12.8kB
ip-10-13-1-101.ap-northeast-1.compute.internal:http => ip-10-13-0-231.ap-northeast-1.compute.internal:8239 0B 7.73kB 4.29kB
<= 0B 1.16kB 658B
ip-10-13-1-101.ap-northeast-1.compute.internal:ssh => ip-10-13-0-11.ap-northeast-1.compute.internal:56320 612B 576B 522B
<= 26B 26B 32B
ip-10-13-1-101.ap-northeast-1.compute.internal:http => ip-10-13-100-41.ap-northeast-1.compute.internal:62657 0B 49B 27B
<= 0B 92B 51B
ip-10-13-1-101.ap-northeast-1.compute.internal:40069 => ip-10-13-103-247.ap-northeast-1.compute.internal:6379 0B 99B 55B
<= 0B 34B 19B
ip-10-13-1-101.ap-northeast-1.compute.internal:40072 => ip-10-13-103-247.ap-northeast-1.compute.internal:6379 0B 99B 55B
<= 0B 34B 19B
ip-10-13-1-101.ap-northeast-1.compute.internal:http => ip-10-13-100-73.ap-northeast-1.compute.internal:27698 0B 44B 25B
<= 0B 33B 18B
ip-10-13-1-101.ap-northeast-1.compute.internal:53696 => ip-10-13-0-2.ap-northeast-1.compute.internal:domain 0B 21B 12B
<= 0B 31B 17B
ip-10-13-1-101.ap-northeast-1.compute.internal:41975 => ip-10-13-0-2.ap-northeast-1.compute.internal:domain 0B 21B 12B
<= 0B 31B 17B
-------------------------------------------------------------------------------------------------------------------------------------------
TX: cum: 1.31MB peak: 560kB rates: 560kB 134kB 74.7kB
RX: 505kB 117kB 3.69kB 49.8kB 28.1kB
TOTAL: 1.81MB 564kB 564kB 184kB 103kB
Item Value
TX (Transmitter) 送信量
RX (Receiver) 受信量
TOTAL iftop 起動からの総量
cum 総量
peak 最大
右端3列 (各トラフィック, rates含む) 2秒、10秒、40秒の転送量平均値

※TX,RX の 「X」 は省略しますよという意味

閲覧し続けると気になる処理があった時には
Shift + P で一旦停止させます。

もう一度開始したい場合は Shift + P です。

実際のCLI

以下見ていただくと白い帯グラフが左から伸びているのが見えるかと思います。
この横棒が一番上のバーの目盛りに相応してぱっと見でどの程度かわかるのが便利です。

DB への接続を確かめる

DB (MySQL) のデフォルトポート 3306 への送受信を調べたいとき

1
$ sudo iftop -B -P -n -N -f "port 3306"

当然ながら受信の方が大きいです。

補足

実際に負荷が高い時等、特定のインシデントがあった際に追記していこうと思います♪

Reference