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

toda-tocochan-bus flask on IBM Bluemix へ引っ越し

toda-tocochan-bus flask on IBM Bluemix へ引っ越し

GCP から IBM Bluemix へ引っ越しました!

toco ちゃんバス あと何分?

概要

さくら VPS から GCP、
そして今度は GCP から IBM Bluemix に引越ししました。

以前 GCP 運用時の話はコチラ

GCP は GKE に LB かましたら価格がバコッと上がってしまい
無料枠を逸脱してしまいました (>_<)

なんとか低価格で運用したいという目論見です。

何故 Heroku でなく IBM Bluemix ?

IBM Bluemix の良い所は機能が充実している所です。
無料・デフォルトで kibana が見れます。

その他 Git との連携も可です。

以下 Mac で作業することを前提に手順まとめました。

事前準備

  • IBM Bluemix に Sign Up しときます

Signup IBM Bluemix

  • clone
1
2
macOS%$ git clone https://github.com/kenzo0107/toda-tocochan-bus-on-ibmbluemix
macOS%$ cd toda-tocochan-bus-on-ibmbluemix
  • cloudfoundry の CLI インストール
1
2
macOS%$ brew tap cloudfoundry/tap
macOS%$ brew install cf-cli

デプロイ

1
2
3
macOS%$ cf api https://api.ng.bluemix.net
macOS%$ cf login
macOS%$ cf push <application name>
  • API は Region によって変わります。
Region API URL
米国南部 https://api.ng.bluemix.net
英国 https://api.eu-gb.bluemix.net

総評

Cloudfoundry の CLI のお陰で引っ越しも簡単でした ♪

セキュリティとして特定 IP やドメインからアクセスさせないとか出来たら
商用のメソッドとして利用出来そうかなと思いました。

その点質問してみましたが 2 週間ほど連絡がないので再度連絡してみます。
↑ 質問は英語限定でした!

サポートが強化されると有難いなと思いました。

以上
ご参考になれば幸いです。

CasperJS+PhantomJS で Github Organization 移行

CasperJS+PhantomJS で Github Organization 移行

概要

Github Enterprise の Organization 移行を実施した際に CasperJS と PhantomJS でヘッドレスブラウザより操作し移行しました。
Github 上で API がない(はず?)為、この様な対応をしました。

どちらかというと CasperJS+PhantomJS でブラウザ上の試験作りを楽しんでいたこともあり
試してみてすんなりできたので採用した経緯になります。

ヘッドレスブラウザとは?

GUI なしのブラウザを CLI で利用するというもの。
ページ描画や画像ロード、ログインしたりとフロントの試験で期待される機能を持っています。

三行まとめ

  • CasperJS + PhantomJS でログイン認証はじめブラウザ操作で Transfer する工程を実行
  • 移行後、元の URL が移行先にリダイレクトされるか確認
  • 期待する要素が時間内に取得できないときはページをキャプチャ

やってみる

Get Started ご参照ください。

以下にも手順まとめてます。

Clone

1
2
macOS%$ git clone https://github.com/kenzo0107/ghe-org-transfer
macOS%$ cd ghe-org-transfer

scripts/ghe-org-transfer.js の <your ****> 編集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var config = {
// site root.
siteRoot: 'https://<your github domain>',
// Github Login path
loginPath: '/login',
// Github Login Account
loginParams: {
email: '<your email>',
password: '<your password>',
},
viewportSize: {
width: 3000,
height: 2500,
},
paths: ['<your owner>/<your repository>'],
destOrganization: '<your destination of organization>',
reason: 'transfer this repository to new oragnization',
};

移行イメージ

  • ex) hoge/mywonderfulrepo —> moge/mywonderfulrepo
1
2
3
4
paths: [
"hoge/mywonderfulrepo"
],
destOrganization: 'moge',

paths は複数指定しても問題ありません。

移行実施

1
macOS%$ make run
  • 実行結果

※ 移行後に元の URL でリダイレクトされるか試験しています。

1
2
3
4
5
[url] https://github.aiueo.com/hoge/mywonderfulrepo/settings
[step] fill '#transfer_confirm > form'
[step] input checkbox #team-59
[step] click the button labeled "Transfer"
(^-^) redirect ok:https://github.aiueo.co.jp/hoge/mywonderfulrepo to https://github.aiueo.co.jp/moge/mywonderfulrepo

総評

以前 Grafana のグラフのスナップショットを撮る Grafana API がうまく動作しなかったのも
CasperJS+PhantomJS で取得する様にできました。

いやはや便利 ♪

全然別件ですが、サイトの認証に利用される reCAPTCHA の突破など挑戦してましたがうまく行かず…
うまくいったぜ!という方、是非教えてください m(_ _)m

WAF+CloudFront でリファラチェック (直リンク禁止)

WAF+CloudFront でリファラチェック (直リンク禁止)

概要

AWS WAF (Web Application Firewall) を利用し Cloudfront でのリファラ制御を実装しましたのでそのまとめです。

直リンク禁止対策として導入しました。

以下手順になります。

Go to AWS WAF ボタンクリック

サービス > WAF & Shield と辿り Go to AWS WAF クリック

Configure Web ACL ボタンクリック

ACL (Access Control List) を設定していきます。

概要確認

特にチェックせず Next ボタンクリック

web ACL 設定

以下、設定項目を設定し、Next ボタンクリック

Item Value
Web ACL name (任意) 例では Cloudfront の CNAME を設定しています。
CloudWatch metric name Web ACL name を入力すると自動で入力される。変更したい場合のみ変更
Region Global(CloudFront) 選択
AWS resource to associate 対象となる Cloudfront を選択する箇所。運用中の Cloudfront を対象とすると場合は後々設定。

条件作成

今回は文字列一致を条件とする為、 String match conditions にて Create condition ボタンクリック

string match condition 作成

以下設定し Add filter ボタンクリック。
複数 filter がある場合、Add filter を繰り返します。

Item Value
Name (任意)
Part of the request to filter on Header
Header Referer
Match type Contains
Transformation Convert to lowercase
Value to match 対象となるドメイン設定

Add filter 後、 Create ボタンクリック。

Next ボタンクリック

追加したもののすぐに反映されていない。
そのまま Next ボタンクリック

ルール作成

Create rule ボタンクリック。

ルールに条件を紐付け

Name, Cloudwatch metric name を設定し
Add conditions で条件を追加します。

その後、Create ボタンクリック。

ルール以外のリクエストのアクセス禁止

やはり Rule は反映されていない。ですが、続けて
Block all requests that don't match any rules をチェックし Review and create ボタンクリック。

※対象の Cloudfront に反映させたくない場合は、Cloudfront を選択したリソースを解除する必要があります。
※最後に関連付けができるのでここではするべきではないと思います。

確認ページで入力内容確認後作成

Confirm and create ボタンクリック。

対象の web ACL を編集

WEB ACLs より選択し Edit web ACL ボタンクリック

web ACL 編集

  1. 作成したルールを選択
  2. Add rule to web ACL ボタンクリック
  3. Allow 選択
  4. Update ボタンクリック

[f:id:kenzo0107:20171005183720p:plain]

Cloudfront 関連付け

Add association ボタンクリック

Web ACL に Cloudfront を関連付け

Resource で 対象の Cloudfront を選択し Add ボタンクリック

以上で数分後 WAF+CloudFront によるリファラチェックが確認できる状態になります。

アクセス確認

自環境では
ローカルの /etc/hosts 修正し対象ドメインから Cloudfront CNAME へのリンクを貼って確認しました。

Cloudfront CNAME ドメインでのリソースを直接アクセスすると
以下の様な エラーページが表示されることが確認できました。

もう少しユーザフレンドリーに

上記のエラーページは Cloudfront > Error Pages で Create Custom Error Response で S3 上のパスを指定することでカスタマイズが可能です。

是非サイトコンセプトに合ったエラーページをご用意されるとよりユーザフレンドリーな配信になるかと思います。

以上
ご参考になれば幸いです。