Terraform でキーペア登録し起動した EC2 に SSH接続

Terraform でキーペア登録し起動した EC2 に SSH接続

今回やること

  • Mac ローカルで公開鍵、秘密鍵を生成
  • Terraform で EC2 起動、セキュリティグループで SSH (ポート 22)許可、key-pair 登録

Terraform の Hello World 的なチュートリアルと思っていただけたら幸いです。

環境

  • Mac OS 10.12.3 (Sierra)
  • Terraform 0.9.1

公開鍵、秘密鍵生成

RSA フォーマットで鍵を生成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ ssh-keygen -t rsa

Enter file in which to save the key (/Users/kenzo_tanaka/.ssh/id_rsa): /Users/kenzo_tanaka/.ssh/terraform-test
Enter passphrase (empty for no passphrase): (空のままEnter)
Enter same passphrase again: (空のままEnter)
...
...

// 生成されたか確認
$ ls ~/.ssh/terraform-test*

/Users/kenzo_tanaka/.ssh/terraform-test # 秘密鍵
/Users/kenzo_tanaka/.ssh/terraform-test.pub # 公開鍵

公開鍵を起動した EC2 インスタンスに登録し
秘密鍵でアクセスします。

以下のように利用する予定です。

1
$ ssh -i ~/.ssh/terraform-test <ec2 user>@<ec2 public ip>

Terraform 設定ファイル

  • Point !

    • resource "aws_key_pair" で使用する公開鍵設定をしています。
    • resource "aws_security_group" で SSH(ポート 22)を開いてます。
    • resource "aws_instance" で使用しているセキュリティグループの指定は vpc_security_group_ids を利用
      • セキュリティグループの条件追加・削除する場合にインスタンスを一度削除し作り直すことをしたくない場合に vpc_security_group_ids を利用すると良いです。
  • main.tf

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
provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}

resource "aws_instance" "example" {
ami = "${lookup(var.amis, var.region)}"
instance_type = "t2.nano"
key_name = "${aws_key_pair.auth.id}"
vpc_security_group_ids = ["${aws_security_group.default.id}"]
}

resource "aws_key_pair" "auth" {
key_name = "${var.key_name}"
public_key = "${file(var.public_key_path)}"
}

resource "aws_security_group" "default" {
name = "terraform_security_group"
description = "Used in the terraform"

# SSH access from anywhere
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
  • variables.tf
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
variable "access_key" {}
variable "secret_key" {}
variable "region" {
default = "ap-northeast-1"
}

variable "amis" {
type = "map"
default = {
us-east-1 = "ami-13be557e"
us-west-2 = "ami-21f78e11"
ap-northeast-1 = "ami-1bfdb67c"
}
}

variable "key_name" {
description = "Desired name of AWS key pair"
}

variable "public_key_path" {
description = <<DESCRIPTION
Path to the SSH public key to be used for authentication.
Ensure this keypair is added to your local SSH agent so provisioners can
connect.

Example: ~/.ssh/terraform.pub
DESCRIPTION
}
  • terraform.tfvars
1
2
3
4
5
access_key = "A******************Q"
secret_key = "q**************************************Z"

key_name = "terraform-test"
public_key_path = "~/.ssh/terraform-test.pub"

いざ実行

  • 実行計画確認
1
$ terraform plan
  • 実行
1
$ terraform apply

確認

  • AWS コンソール上で起動確認

    • キーペアに terraform-test が指定されています。
    • vpc, subnet も自動的にアタッチされてます。
  • キーペア
    一応キーペアを見てみると登録されているのがわかります。
  • セキュリティグループ確認
  • SSH ログイン確認
1
$ ssh -i ~/.ssh/terraform-test ubuntu@ec2-54-65-244-25.ap-northeast-1.compute.amazonaws.com

無事 SSH ログインできました!

所感

terraform を見ながら各パラメータの利用意図を確認しながら
設定してみましたが
パラメータの説明自体はざっくりで利用方法まではわからないです。

Teffaform のチュートリアルに始まり
その他 Stack Overflow
適宜パターンを蓄積していく学習が程よいと思います。

参考

Terraform で AWS インフラストラクチャ!

Terraform で AWS インフラストラクチャ!

Terraform とは

  • インフラ構成や設定をコードにより実行計画を確認しながら自動化できるツール
  • AWS, Google Cloud 等多数のクラウドサービスで利用可能
  • HashiCorp 社製

今回やること

  • インスタンス起動
  • Elastic IP 付きインスタンス起動
  • インスタンス破棄

非常にミニマムなインフラ構築をしてみます。
※個人のアカウントでも無料枠を使えば数十円しか掛からなかったです。

環境

  • Mac OS Sierra X 10.12.3 16D32
  • Terraform 0.9.1

terraform インストール

1
$ brew install terraform

バージョン確認

1
2
3
$ terraform version

Terraform v0.9.1

では、早速使ってみます。

EC2 instance (t2.micro) 起動

  • main.tf 作成
1
2
3
4
5
6
7
8
9
10
provider "aws" {
access_key = "A******************Q"
secret_key = "q**************************************Z"
region = "ap-northeast-1"
}

resource "aws_instance" "example" {
ami = "ami-71d79f16"
instance_type = "t2.micro"
}
  • 実行計画確認
1
$ terraform plan
  • 実行
1
$ terraform apply

Amazon Console からインスタンスが起動されたことが確認できます。

変数を別ファイルで管理

上記 main.tf を github 等で管理するとなると
access_key, secret_key が露見されてしまいます。

その為、以下の様に別ファイルで管理することが望ましいです。

  • main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
variable "access_key" {}
variable "secret_key" {}
variable "region" {
default = "ap-northeast-1"
}

provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}

resource "aws_instance" "example" {
ami = "ami-71d79f16"
instance_type = "t2.micro"
}
  • terraform.tfvars
    • terraform 実行時に自動で読み込まれるファイル
1
2
access_key = "A******************Q"
secret_key = "q**************************************Z"
  • 実行計画確認
1
2
3
4
5
$ terraform plan

...

Plan: 1 to add, 0 to change, 0 to destroy.

正しく実行できることが確認できました。

terraform.tfvars ファイルは .gitignore に登録しておくなど
絶対に公開されない様な設定が望ましいと思います。

EC2 instance (t2.micro) AMI 変更

  • main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
variable "access_key" {}
variable "secret_key" {}
variable "region" {
default = "ap-northeast-1"
}

provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}

resource "aws_instance" "example" {
ami = "ami-047aed04"
instance_type = "t2.micro"
}
  • 実行計画

変更される内容が表示されます。

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
$ terraform plan

...

-/+ aws_instance.example
ami: "ami-71d79f16" => "ami-047aed04" (forces new resource)
associate_public_ip_address: "true" => "<computed>"
availability_zone: "ap-northeast-1a" => "<computed>"
ebs_block_device.#: "0" => "<computed>"
ephemeral_block_device.#: "0" => "<computed>"
instance_state: "running" => "<computed>"
instance_type: "t2.micro" => "t2.micro"
ipv6_addresses.#: "0" => "<computed>"
key_name: "" => "<computed>"
network_interface_id: "eni-f4a214bb" => "<computed>"
placement_group: "" => "<computed>"
private_dns: "ip-172-31-31-239.ap-northeast-1.compute.internal" => "<c
omputed>"
private_ip: "172.31.31.239" => "<computed>"
public_dns: "ec2-52-199-88-146.ap-northeast-1.compute.amazonaws.com"
=> "<computed>"
public_ip: "52.199.88.146" => "<computed>"
root_block_device.#: "1" => "<computed>"
security_groups.#: "0" => "<computed>"
source_dest_check: "true" => "true"
subnet_id: "subnet-7a79cc0d" => "<computed>"
tenancy: "default" => "<computed>"
vpc_security_group_ids.#: "1" => "<computed>"


Plan: 1 to add, 0 to change, 1 to destroy.

最初に作成したインスタンスは破棄され、新たにインスタンスを作成していることがわかります。

terraform で新規作成・変更ができました。

次は破棄してみましょう。

EC2 instance (t2.micro) 破棄

  • 実行計画確認

破棄対象のリソースが表示されます。

1
2
3
4
5
$ terraform plan -destroy

...

- aws_instance.example
  • 実行
1
2
3
4
5
6
7
8
9
10
$ terraform destroy

Do you really want to destroy?
Terraform will delete all your managed infrastructure.
There is no undo. Only 'yes' will be accepted to confirm.

Enter a value: yes (← yes 入力)
...

Destroy complete! Resources: 1 destroyed.

Amazon コンソールで破棄されたことを確認できます。

インスタンス起動し Elastic IP (固定 IP) 設定

  • main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
variable "access_key" {}
variable "secret_key" {}
variable "region" {
default = "ap-northeast-1"
}

provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}

resource "aws_instance" "example" {
ami = "ami-047aed04"
instance_type = "t2.micro"
}

resource "aws_eip" "ip" {
instance = "${aws_instance.example.id}"
}
  • 実行計画確認
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
$ terraform plan

...

+ aws_eip.ip
allocation_id: "<computed>"
association_id: "<computed>"
domain: "<computed>"
instance: "${aws_instance.example.id}"
network_interface: "<computed>"
private_ip: "<computed>"
public_ip: "<computed>"
vpc: "<computed>"

+ aws_instance.example
ami: "ami-047aed04"
associate_public_ip_address: "<computed>"
availability_zone: "<computed>"
ebs_block_device.#: "<computed>"
ephemeral_block_device.#: "<computed>"
instance_state: "<computed>"
instance_type: "t2.micro"
ipv6_addresses.#: "<computed>"
key_name: "<computed>"
network_interface_id: "<computed>"
placement_group: "<computed>"
private_dns: "<computed>"
private_ip: "<computed>"
public_dns: "<computed>"
public_ip: "<computed>"
root_block_device.#: "<computed>"
security_groups.#: "<computed>"
source_dest_check: "true"
subnet_id: "<computed>"
tenancy: "<computed>"
vpc_security_group_ids.#: "<computed>"


Plan: 2 to add, 0 to change, 0 to destroy.
  • 実行
1
$ terraform apply

Elastic IP が設定されたインスタンスが起動していることが確認できます。
※ただ、起動しただけで接続できないことがわかります(>_<) 次回実施します

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

  • 実行計画確認

破棄される Elastic IP, インスタンスが確認できます。

1
2
3
4
5
6
7
$ terraform plan -destroy

...

- aws_eip.ip

- aws_instance.example
  • 実行
1
2
3
4
5
$ terraform destroy

...

Destroy complete! Resources: 2 destroyed.

全インスタンスが破棄されていることが確認できました。

その他便利な設定

Map 設定

  • region 毎に AMI を選択し terraform apply 時に変数指定し選択可能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...

variable "amis" {
type = "map"
default = {
us-east-1 = "ami-13be557e"
us-east-2 = "ami-71d79f16"
us-west-1 = "ami-00175967"
us-west-2 = "ami-06b94666"
ap-northeast-1 = "ami-047aed04"
}
}

...

resource "aws_instance" "example" {
ami = "${lookup(var.amis, var.region)}"
instance_type = "t2.micro"
}

ex) region us-west-2 を選択

1
$ terraform apply -var region=us-west-2

出力設定

生成された Elastic IP の値が知りたいときなど便利です。

  • main.tf
1
2
3
4
5
6
7
resource "aws_eip" "ip" {
instance = "${aws_instance.example.id}"
}

output "ip" {
value = "${aws_eip.ip.public_ip}"
}

出力値が確認できます。

1
2
3
4
5
6
7
$ terraform apply

...

Outputs:

ip = 52.197.157.206
  • terraform output

より明示的にパラメータを絞って表示できます。

1
2
3
$ terraform output ip

52.197.157.206
  • show
1
2
3
4
5
6
7
$ terraform show

...

Outputs:

ip = 52.197.157.206

構成のグラフ化

1
$ terraform graph | dot -Tpng > graph.png
  • graph.png
  • dot コマンドがない場合は graphviz インストール
1
$ brew install graphviz

総評

簡単でしょ?と言われているようなツールでした ♪

引き続きプロビジョニングや AWS の各種設定をしていきたいと思います。

次回 EC2 インスタンスを起動し、ローカル環境で作った鍵をキーペア登録し SSH ログインを実施します。

node_exporter シェルでクエリ自作

node_exporter シェルでクエリ自作

概要

node_expoter のオプション --collector.textfile.directory で指定したディレクトリに *.prom という拡張子を配置することで
そこに記述したメトリクス情報を prometheus server が読み取ってくれます。

この *.prom ファイルを一定時間毎に更新すればメトリクスが自作できる、というものです。

手順

  • node_exporter 自体のインストール・セットアップは以下ご参照ください。

上記手順では以下に node_exporter を配置しています。
環境によって適宜書き換えてください。

1
/usr/local/node_exporter/node_exporter

text_collector ディレクトリ作成

1
2
$ cd /usr/local/node_exporter
$ mkdir text_collector

shell 作成

今回は httpd の process count のメトリクス追加することとします。

  • /usr/local/node_exporter/text_collector/httpd.sh 作成

cron 設定

1
2
# node_exporter httpd 5分毎更新
*/5 * * * * /usr/local/node_exporter/text_collector/httpd.sh

httpd.prom 作成確認

  • /usr/local/node_exporter/text_collector/httpd.prom
1
node_httpd_count 24

上記の node_httpd_count がメトリクス名になります。

node_expoter 再起動

以下のようにディレクトリ指定します。

1
node_expoter --collector.textfile.directory /usr/local/node_exporter/text_collector

作成したメトリクスを指定し確認する。

無事できました!

これを利用してるとシェル芸で色々事足りることもあります ♪

一助になれば何よりです。

標準的な Golang インストール方法

標準的な Golang インストール方法

概要

Golang オフィシャルサイトに書かれているそのままです。

他 Golang 関連記事説明の為に、また、備忘録として記述します。

環境

  • CentOS Linux release 7.3.1611 (Core)

手順

Golang Official - Downloads から環境に合わせ
最新バージョンをインストールすることをお勧めします。

  • ソースからビルド
1
2
3
$ cd /usr/local/src
$ sudo wget https://storage.googleapis.com/golang/go1.7.5.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.7.5.linux-amd64.tar.gz
  • PATH 設定
1
2
3
4
5
6
7
8
$ sudo cat << 'EOF' | sudo tee /etc/profile.d/golang.sh
export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin
EOF

$ sudo cp /etc/profile.d/golang.sh /etc/profile.d/golang.csh

$ source /etc/profile
  • 確認
1
2
3
$ go version

go version go1.7.5 linux/amd64

以上で Golang のインストール完了です。

node_expoter error occured ! hwmon collector failed

node_expoter error occured ! hwmon collector failed

概要

Amazon Linux に node_exporter をインストールし起動した所以下のエラーが発生し、起動停止してしまいました。

1
ERRO[0007] ERROR: hwmon collector failed after 0.000011s: open /proc/class/hwmon: no such file or directory  source="node_exporter.go:92"

hwmon とは?

Hard Ware MONitoring. Linux カーネルのセンサーチップから Hard Ware の温度やファン回転数や電圧を取得できる。

環境情報は以下の通りです。

  • Amazon Linux AMI release 2016.09
  • node_exporter version 0.14.0-rc.1 (branch: master, revision:5a07f4173d97fa0dd307db5bd3c2e6da26a4b16e)

上記エラーですが issue として上がっていました。
そして解決されてました!

タイミングが悪かったのかマージされる前の release を取得していた為
このエラーに遭遇していました。

最新のソースは master ブランチしてビルドするのが良さそうです。

以下に Amazon Linux で実施したインストール手順をまとめました。

手順

Golang インストール

以下 Golang オフィシャルサイトにある標準的なインストール方法です。参考にしてください。

node_exporter をソースからインストールしビルド

1
2
3
4
5
6
7
8
9
$ mkdir -p $GOPATH/src/github.com/prometheus
$ cd $GOPATH/src/github.com/prometheus
$ git clone https://github.com/prometheus/node_exporter
$ cd node_exporter
$ make build

// version 確認
$ ./node_exporter --version
node_exporter, version 0.14.0-rc.1 (branch: master, revision: 428bc92b1c9b38f6de96bceb67bc5d9b3bdcf6e7)

ついでに起動スクリプト

  • 事前準備
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// pid ファイル置き場 作成
$ sudo mkdir -p /var/run/prometheus

// log ファイル置き場 作成
$ sudo mkdir -p /var/log/prometheus

// daemonize インストール
$ cd /usr/local/src
$ sudo git clone https://github.com/bmc/daemonize
$ cd daemonize
$ sudo ./configure
$ sudo make
$ sudo make install

// PATHが通ってなかったらPATHに乗せる
$ sudo cp daemonize /bin/

$ which daemonize
/bin/daemonize
  • 起動スクリプト作成
1
2
3
4
$ cd /etc/init.d
$ sudo git clone https://gist.github.com/kenzo0107/eebb6c1c06ba04b7073c171580cec445
$ sudo cp eebb6c1c06ba04b7073c171580cec445/node_exporter.init ./node_exporter
$ sudo chmod 0755 node_exporter
  • 起動
1
$ sudo /etc/init.d/node_exporter start

無事エラーなく起動するようになりました ♪

Alertmanager 構築手順

Alertmanager 構築手順

概要

前回 Node Exporter 構築しました。

今回は監視実施サーバで Alertmanager 構築を実施します。

今回やること 3 行まとめ

  • Alertmanager インストール & 起動スクリプト作成
  • Prometheus 通知条件設定
  • Alertmanager で Slack 通知

Alertmanager の役割

アラートのレベルによって通知先をどの程度の頻度で送信するかを管理します。
あくまで、通知先の管理をします。

実際のアラート条件の設定は Prometheus Server でします。

環境

  • CentOS Linux release 7.3.1611 (Core)

Alertmanager インストール

  • パッケージインストール
1
2
3
4
5
$ cd /usr/local/src
$ sudo wget https://github.com/prometheus/alertmanager/releases/download/v0.5.1/alertmanager-0.5.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xvf alertmanager-0.5.1.linux-amd64.tar.gz
$ cd /usr/local
$ sudo mv alertmanager-0.5.1.linux-amd64 alertmanager
  • シンボリックリンク作成
1
2
3
4
5
6
7
8
$ sudo ln -s /usr/local/alertmanager/alertmanager /bin/alertmanager

$ alertmanager --version

alertmanager, version 0.5.1 (branch: master, revision: 0ea1cac51e6a620ec09d053f0484b97932b5c902)
build user: root@fb407787b8bf
build date: 20161125-08:14:40
go version: go1.7.3

Alert 通知先設定

以下 Slack へ通知設定です。

1
2
3
$ cd /usr/local/alertmanager
$ git clone https://gist.github.com/kenzo0107/71574c2d4d70ba7a9efaa88b4ff1be1b
$ mv 71574c2d4d70ba7a9efaa88b4ff1be1b/alertmanager.yml .
  • alertmanager.yml

slack 通知箇所を適宜変更して下さい。

Alertmanager 起動

とりあえず起動するならこれだけ

1
$ sudo alertmanager -config.file alertmanager.yml

http://alertmanager_server:9093/#/alerts にアクセスすると以下のような画面が表示されます。

Prometheus 同様、Alertmanager も起動スクリプトを作成しそこで起動管理をします。

起動スクリプト作成

  • オプションファイル作成
1
2
3
$ cat << 'EOF' > /usr/local/alertmanager/option
OPTIONS="-config.file /usr/local/alertmanager/alertmanager.yml"
EOF
  • Alertmanager 起動スクリプト
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo cat << 'EOF' | sudo tee /usr/lib/systemd/system/alertmanager.service
[Unit]
Description=Prometheus alertmanager Service
After=syslog.target prometheus.alertmanager.service

[Service]
Type=simple
EnvironmentFile=-/usr/local/alertmanager/option
ExecStart=/bin/alertmanager $OPTIONS
PrivateTmp=false

[Install]
WantedBy=multi-user.target
EOF
  • 起動設定
1
2
3
4
$ sudo systemctl daemon-reload
$ sudo systemctl enable alertmanager.service
$ sudo systemctl start alertmanager.service
$ sudo systemctl status alertmanager.service -l

アラート通知条件設定

アラート通知条件は Prometheus Server 側で設定します。

Prometheus Official - ALERTING RULES

サンプルとして以下設定します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cd /usr/local/prometheus-server
$ cat << 'EOF' > alerts.rules

# インスタンスに 5分以上(FOR) アクセスできない場合(IF up == 0)
# severity = "critical" とラベル付けし通知
ALERT InstanceDown
IF up == 0
FOR 5m
LABELS { severity = "critical" }
ANNOTATIONS {
summary = "Instance {{ $labels.instance }} down",
description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.",
}

// Prometheus 設定ファイルチェック
$ promtool check-config prometheus.yml

Checking prometheus.yml
SUCCESS: 1 rule files found

Checking alerts.rules
SUCCESS: 1 rules found

Prometheus Server で Alertmanager URL 設定

Prometheus の起動オプションで Alertmanager URL 設定します。

1
-alertmanager.url=http://localhost:9093
1
2
3
4
5
6
7
$ cd /usr/local/prometheus-server
$ cat << 'EOF' > option
OPTIONS="-config.file=/usr/local/prometheus-server/prometheus.yml -web.console.libraries=/usr/local/prometheus-server/console_libraries -web.console.templates=/usr/local/prometheus-server/consoles -alertmanager.url=http://localhost:9093"
EOF

// Prometheus 再起動
$ sudo systemctl restart prometheus.service

注意

今回 Alertmanager は Prometheus Server と同サーバ上に設定しているので

1
http://localhost:9093

となっていますが、ドメインが異なる場合は適宜設定してください。

Prometheus Alerts ページアクセス

設定した通知条件が表示されています。

通知試験

監視対象サーバの node_exporter を停止してみます。

1
$ sudo systemctl stop node_exporter

すると…

Slack に通知が届きました!

http://alertmanager_server:9093/#/alerts にアクセスすると通知内容一覧が表示されます。

以上で簡単ながら
Prometheus からリモートサーバを監視しアラート通知するところまでを
まとめました。

  1. Prometheus でサーバ監視
  2. Node Exporter 構築手順 + Prometheus から AWS オートスケール監視
  3. Alertmanager 構築手順

補足

フロントエンド

Grafana 3.x 以降でデフォルトプラグインで Prometheus をサポートしていたりと
Prometheus のフロントは Grafana が導入しやすく相性が良かったです。

メトリクスを自作したり、Prometheus 独自のクエリを駆使して
様々なメトリクス監視が実現できます。

My alerts.rules

Learning

改めて自身で構築してみて
Line Casual Talks #1, #2 を見直すと非常に理解が深まると思います。

一助になれば何よりです。

以上です。
ご静聴ありがとうございました。

Node Exporter 構築手順 + Prometheus からAWSオートスケール監視

Node Exporter 構築手順 + Prometheus からAWSオートスケール監視

概要

前回 Prometheus Server 構築しました。

今回は 監視対象サーバで Node Exporter 構築を実施します。

今回やること 3 行まとめ

  • Node Exporter インストール
  • Node Exporter 起動スクリプト作成
  • Node Exporter 起動し Prometheus Server からモニタリング

環境

  • CentOS Linux release 7.1.1503 (Core)

Node Exporter インストール

  • パッケージインストール
1
2
3
4
5
$ cd /usr/local/src
$ sudo wget https://github.com/prometheus/node_exporter/releases/download/v0.14.0-rc.1/node_exporter-0.14.0-rc.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xvf node_exporter-0.14.0-rc.1.linux-amd64.tar.gz
$ cd /usr/local
$ sudo mv node_exporter-0.14.0-rc.1.linux-amd64 node_exporter
  • シンボリックリンク作成
1
2
3
4
5
6
7
$ sudo ln -s /usr/local/node_exporter/node_exporter /bin/node_exporter

$ node_exporter --version
node_exporter, version 0.14.0-rc.1 (branch: master, revision: 5a07f4173d97fa0dd307db5bd3c2e6da26a4b16e)
build user: root@ed143c8f2fcd
build date: 20170116-16:00:03
go version: go1.7.4

Node Exporter 起動

とりあえず起動するならこれだけ

1
$ sudo node_exporter

http://node_exporter_server:9100/metrics にアクセスし
取得できる node_exporter で取得しているサーバのメトリクス情報が確認できます。

Prometheus 同様、Node Exporter も起動スクリプトを作成しそこで起動管理をします。

起動スクリプト作成

  • Node Exporter 起動スクリプト
1
2
3
4
5
6
7
8
9
10
11
12
$ sudo cat << 'EOF' | sudo tee /usr/lib/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter

[Service]
Type=simple
ExecStart=/bin/node_exporter
PrivateTmp=false

[Install]
WantedBy=multi-user.target
EOF
  • 起動設定
1
2
3
4
$ sudo systemctl daemon-reload
$ sudo systemctl enable node_exporter.service
$ sudo systemctl start node_exporter.service
$ sudo systemctl status node_exporter.service -l

アクセスしてみる

http://node_exporter_server:9100/metrics にアクセスします。

以下のように表示されていれば Node Exporter 起動成功です。

Prometheus から監視

今回は AWS EC2 インスタンスで起動中の node_exporter によるメトリクス取得設定です。

※ 監視実施サーバに AmazonEC2ReadOnlyAccess をアタッチしたロール設定をする必要があります。
※ 監視対象サーバに 監視対象サーバから 9100 ポート へアクセスできるようにセキュリティグループ設定します。

  • /usr/local/prometheus-server/prometheus.yml 編集

以下設定は region 指定しアクセス権のある Instance のメトリクスを取得します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# my global config
global:
scrape_interval: 15s
evaluation_interval: 15s

external_labels:
monitor: 'codelab-monitor'

rule_files:
# - "first.rules"
# - "second.rules"

scrape_configs:
- job_name: 'prometheus'

static_configs:
- targets: ['localhost:9090']

- job_name: 'node'
ec2_sd_configs:
- region: ap-northeast-1
access_key: ********************
secret_key: ****************************************
port: 9100

タグで監視対象を絞る

全インスタンスを監視であれば上記で問題ありません。

ですが、監視対象をある程度条件で絞りたいケースがあります。
そんな時、Prometheus では relabel_configs でインスタンスの設定タグで絞る方法があります。

  • インスタンスのタグ設定
  • prometheus.yml 設定
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
# my global config
global:
scrape_interval: 15s
evaluation_interval: 15s

external_labels:
monitor: 'codelab-monitor'

rule_files:
# - "first.rules"
# - "second.rules"

scrape_configs:
- job_name: 'prometheus'

static_configs:
- targets: ['localhost:9090']

- job_name: 'node'
ec2_sd_configs:
- region: ap-northeast-1
access_key: ********************
secret_key: ****************************************
port: 9100
relabel_configs:
- source_labels: [__meta_ec2_tag_Stage]
regex: production
action: keep
- source_labels: [__meta_ec2_tag_Role]
regex: web
action: keep
  • prometheus.yml 編集後、再起動
1
$ sudo systemctl restart prometheus.service

Prometheus から node_exporter 起動したサーバを監視できているか確認

http://prometheus_server:9090/consoles/node.html

Up : Yes となっている Node のリンクをクリックすると CPU, Disck のグラフが確認できます。

次回は 監視対象で Alertmanager 構築します。

参照

Prometheus でサーバ監視

Prometheus でサーバ監視

概要

以前 Ansible + Vagrant で Prometheus モニタリング環境構築について書きました。

今回は具体的によくある設定ユースケースを順追って設定していきます。

  1. Prometheus Server 構築
  2. 監視対象で Node Exporter 構築
  3. Alertmanager 構築

今回やること 3 行まとめ

  • Prometheus Server モジュールインストール
  • Prometheus Server 起動スクリプト作成
  • Prometheus Server 起動し自身のサーバモニタリング

Prometheus の設定ファイルについては
全体像を理解した後が良いと思いますので
Node Exporter の設定の後に実施したいと思います。

環境

  • CentOS Linux release 7.3.1611 (Core)

Prometheus インストール

1
2
3
4
5
$ cd /usr/local/src
$ sudo wget https://github.com/prometheus/prometheus/releases/download/v1.4.1/prometheus-1.4.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xvf prometheus-1.4.1.linux-amd64.tar.gz
$ cd /usr/local
$ sudo mv prometheus-1.4.1.linux-amd64 prometheus-server
  • シンボリックリンク作成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo ln -s /usr/local/prometheus-server/prometheus /bin/prometheus
$ sudo ln -s /usr/local/prometheus-server/promtool /bin/promtool

$ prometheus --version
prometheus, version 1.4.1 (branch: master, revision: 2a89e8733f240d3cd57a6520b52c36ac4744ce12)
build user: root@e685d23d8809
build date: 20161128-09:59:22
go version: go1.7.3

$ promtool version
promtool, version 1.4.1 (branch: master, revision: 2a89e8733f240d3cd57a6520b52c36ac4744ce12)
build user: root@e685d23d8809
build date: 20161128-09:59:22
go version: go1.7.3

Prometheus 起動

とりあえず起動するならこれだけ

1
$ sudo prometheus -config.file=/usr/local/prometheus-server/prometheus.yml

ただ ↑ これを毎回実行するのは辛いので起動スクリプトを作成して
サーバ再起動時に自動起動したり
systemctl start ... と実行したい。

起動スクリプト作成

  • Prometheus オプションファイル作成
1
2
3
$ cat << 'EOF' > /usr/local/prometheus-server/option
OPTIONS="-config.file=/usr/local/prometheus-server/prometheus.yml -web.console.libraries=/usr/local/prometheus-server/console_libraries -web.console.templates=/usr/local/prometheus-server/consoles"
EOF
  • Prometheus 起動スクリプト
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo cat << 'EOF' | sudo tee /usr/lib/systemd/system/prometheus.service
[Unit]
Description=Prometheus Service
After=syslog.target prometheus.service

[Service]
Type=simple
EnvironmentFile=-/usr/local/prometheus-server/option
ExecStart=/bin/prometheus $OPTIONS
PrivateTmp=false

[Install]
WantedBy=multi-user.target
EOF
  • 起動設定
1
2
3
4
$ sudo systemctl daemon-reload
$ sudo systemctl enable prometheus.service
$ sudo systemctl start prometheus.service
$ sudo systemctl status prometheus.service -l

アクセスしてみる

<IP Address>:9090 にアクセスします。
以下のように表示されていれば Prometheus 起動成功です。

Imgur

オプション設定でも設定した、 /usr/local/prometheus-server/consoles の各 html にもアクセスしてみてください。

<IP Address>:9090/consoles/prometheus-overview.html?instance=localhost%3a9090

次回は 監視対象で Node Exporter 構築 します。

リモートサーバとローカルサーバとの差分のあるファイル情報を取得するツール作ってみた

リモートサーバとローカルサーバとの差分のあるファイル情報を取得するツール作ってみた

概要

リモートサーバとローカルサーバとの差分のあるファイル情報を取得するツールを Golang で作成しました。

どんなツールか 3 行まとめ

  1. ローカルワークスペースを元にリモートサーバからディレクトリと拡張子指定し実行ディレクトリ上にファイルをダウンロード
  2. ローカルのワークスペースから実行ディレクトリ上にファイルをコピー
  3. 1,2 で取得したファイルから差分をチェック

利用想定ケース

  • リモートファイルサーバとローカルワークスペースの同期状況が不明瞭である場合

この 1 点のみです。
整備されたデプロイ環境では発生しにくいケースです。

ですが意外と多いです。

それはこんなケース

  • 担当者が退職して引き継がれていない (>_<)
  • ちょっとしたツールだし Git 管理してなかった (>_<)
  • 別の業者さんがサーバにアクセスでき、勝手に編集することがある (>_<)

上記のケースに当たる案件にたまたま担当してしまって
デグレった、バグったとならない為に個人的に作ってました。

補足

デフォルトの対象拡張子は php,tpl,js,css,html を対象としています。
会社で PHP プロジェクトを扱うことが多いので m(_ _)m

あとがき

元々 Python で書いてましたが Go にしたところ
4~5 倍程度パフォーマンスアップしました!

並行処理についても
Python も multiprocessing がありますが
書き易さは Go かなと思いました。

ちなみに

実装に当たってこちら拝読させていただきました。
基礎的な Go 言語の構文や環境構築、
Semaphore を意識した設計はとても参考になりました。

Jenkins が起動しない - Unable to read /var/lib/jenkins/config.xml -

Jenkins が起動しない - Unable to read /var/lib/jenkins/config.xml -

とある午後、Jenkins を再起動したときに出たエラー

1
2
3
4
5
6
7
8
9
10
hudson.util.HudsonFailedToLoad: org.jvnet.hudson.reactor.ReactorException: java.io.IOException: Unable to read /var/lib/jenkins/config.xml
at hudson.WebAppMain$3.run(WebAppMain.java:234)
Caused by: org.jvnet.hudson.reactor.ReactorException: java.io.IOException: Unable to read /var/lib/jenkins/config.xml
at org.jvnet.hudson.reactor.Reactor.execute(Reactor.java:269)
at jenkins.InitReactorRunner.run(InitReactorRunner.java:44)
at jenkins.model.Jenkins.executeReactor(Jenkins.java:912)
at jenkins.model.Jenkins.<init>(Jenkins.java:811)
at hudson.model.Hudson.<init>(Hudson.java:82)
at hudson.model.Hudson.<init>(Hudson.java:78)
at hudson.WebAppMain$3.run(WebAppMain.java:222)

/var/lib/jenkins/config.xml が読み込めない というエラー

/var/lib/jenkins/config.xml の所有者は jenkins:jenkins だけど、なぜ?

と権限周りを諸々試験して直していくと
plugins をディレクトリごと所有者変更すると直りました汗

1
$ sudo chown -R jenkins:jenkins /var/lib/jenkins/plugins

plugin の挙動で何か所有者変更され得るものがあったのか解明せず。

同様の事象の記事を見つけたので参照