はじめに
GCE上のプロセスをStackdriverで監視していて、プロセスが落ちたらSlackにアラートを飛ばす・・・・
ちゃうねん!アラートが飛ばすことが目的じゃなくて、サービスをいち早く復旧させるのが目的やねん!
どうせAlert飛んだあとにやることは、systemctl status XXXXX
でステータス確認して、sudo systemctl start XXXXX
をするだけじゃん。
ということで、Stackdriver+Gitlab-CI+Ansibleを連携させて、アラートを飛ばすだけじゃなく、サービスを復旧させる仕組みを構築してみようと思う。
チームのメンバーがSlack botでもいい感じに自動復旧の仕組みを作ってる記事があるので、Slack botでやりたいんだよ!俺は!
っていう人は↓を参考にすると幸せになれる。
Stackdriverとslackbotでサービス自動復旧させる
https://qiita.com/andromeda/items/fcb2ea02e9bb32e329e4
全体構成
補足
後述もしているが、proxy経由でStackdriverのwebhookをしている理由は、SourceIPが固定化出来ないのでGitLabのFirewallルールにSourceIPを追加出来ないため。
一定のセキュリティを担保するためにBasic認証付きにしている。
前提
- gitlab自体はすでにインストール(稼働)済みとする
- GCPプロジェクトが利用可能な状態である
Gitlab-runner+Ansibleサーバを構築
適当にGCEインスタンスを作成する。
今回はCentOS7のイメージを使用。
Ansibleのインストール
適当にインストール
sudo yum install ansible
ansibleの設定ファイル
すごく単純でこんな構成
$ tree
.
├── inventories
│ └── hosts
├── roles
│ └── nginx
│ └── tasks
│ └── main.yml
└── site_test.yml
[nginx]
XXX.XXX.XXX.XXX
- name: start nginx
systemd:
name: nginx
state: started
- name: start nginx
hosts: nginx
become: yes
roles:
- nginx
.gilab-ci.ymlの設定
ansibleというユーザーを作って、ansibleユーザーで実行する。
また、ansibleユーザーの公開鍵は、監視対象となるNginxサーバがあるGCPプロジェクトに登録しておく。
stages:
- start-service
start-service:
stage: start-service
tags:
- autohealing
script:
- sudo ansible-playbook -i ./ansible/inventories/hosts -u ansible --private-key=/home/ansible/.ssh/id_rsa ./ansible/site_test.yml
GitLab-Runnerのインストール
公式ドキュメントを参考にインストール
$ sudo curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
$ sudo yum install gitlab-runner
# 起動確認
$ systemctl status gitlab-runner
● gitlab-runner.service - GitLab Runner
Loaded: loaded (/etc/systemd/system/gitlab-runner.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2018-10-20 01:04:37 JST; 11h ago
Main PID: 25635 (gitlab-runner)
CGroup: /system.slice/gitlab-runner.service
└─25635 /usr/lib/gitlab-runner/gitlab-runner run --working-directory /home/gitlab-runner --config /etc/gitlab-runner/config.toml --service gitla...
gitlab-runnerにsudo権限を与える
$ sudo visudo
# 以下を末尾に追加
gitlab-runner ALL=(ALL) NOPASSWD: ALL
GitLab-Runnerを登録する
公式ドキュメント通り対話形式で以下のようにRegisterする
$ sudo gitlab-runner register
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://example.gitlab.com/
Please enter the gitlab-ci token for this runner:
XXXXXXXXXXXXXXX
Please enter the gitlab-ci description for this runner:
[ansible-server] : autohealing
Please enter the gitlab-ci tags for this runner (comma separated):
autohealing
Registering runner... succeeded runner=yJC3cma3
Please enter the executor: docker+machine, docker-ssh+machine, kubernetes, docker, virtualbox, shell, ssh, docker-ssh, parallels:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
.netrcを作成する
git pullとかするときにアカウント情報聞かれてめんどいので、 .netrcを作っておく
$ su - gitlab-runner
$ vi .netrc
machine gitlab.com
login ci-user(適当)
password ci-password(適当)
Pipeline triggerを設定
GitLabにてtriggerを設定して、webhookで使用するtokenを取得する。
gitlab-proxyサーバの作成
Stackdriver AlertのWebhookはGIPが一定ではない(Googleサポートにも問合せたけど、左記の回答)。
GitlabにIPでFireWallがあった場合は、Webhookが通知できない。
なので、Nginxでproxyとなるサーバを用意して、GIPを固定化する。
そして、NginxにBasic認証を用いることで、一定のセキュリティを担保するようにする。
IPを固定できるようにしてーというissuesが上がっているので、ここをウォッチしていくと、このgitlab-proxyが不要になったら分かるようになる。
是非、スターつけてください!
nginxのインストール
$ sudo yum install -y nginx
basic認証を設定する
$ sudo yum install -y httpd-tools
$ htpasswd -c /etc/nginx/.htpasswd なんか適当にID
New password: なんか適当にPW
Re-type new password: なんか適当にPW
$ vi /etc/nginx/nginx.conf
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass https://gitlabのアドレス/;
}
監視対象のサーバ作成
今回、監視される側となるサーバを作成する。
このNginxがダウンしたら、stackdriverが検知して、gitlabに通知後にgitlab-runnerを発火する。
Nginxのインストール
適当にGCEにNginxをインストールしておく
$ sudo install -y nginx
$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2018-10-20 04:29:30 UTC; 42min ago
Process: 1726 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 1723 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 1722 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 1728 (nginx)
CGroup: /system.slice/nginx.service
├─1728 nginx: master process /usr/sbin/nginx
└─1729 nginx: worker process
StackdriverAgentのインストール
プロセスのメトリクスを取得するにはStackdriverMonitoringAgentのインストールがいる。
$ curl -sSO https://dl.google.com/cloudagents/install-monitoring-agent.sh
$ sudo bash install-monitoring-agent.sh
# 起動確認
$ systemctl status stackdriver-agent
● stackdriver-agent.service - LSB: start and stop Stackdriver Agent
Loaded: loaded (/etc/rc.d/init.d/stackdriver-agent; bad; vendor preset: disabled)
Active: active (running) since Sat 2018-10-20 11:27:42 UTC; 37s ago
Docs: man:systemd-sysv-generator(8)
Process: 9464 ExecStart=/etc/rc.d/init.d/stackdriver-agent start (code=exited, status=0/SUCCESS)
Main PID: 9495 (stackdriver-col)
CGroup: /system.slice/stackdriver-agent.service
└─9495 /opt/stackdriver/collectd/sbin/stackdriver-collectd -C /etc/stackdriver/collectd.conf -P /var/run/stackdriver-agent.pid
Stackdriverのアラート設定
webhookの設定
alertの設定
notificationの設定
いざ実践
Nginxを落とす
$ sudo systemctl stop nginx
$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Oct 25 05:05:39 web-test systemd[1]: Started The nginx HTTP and reverse proxy server.
Oct 25 05:36:07 web-test systemd[1]: Stopping The nginx HTTP and reverse proxy server...
Oct 25 05:36:07 web-test systemd[1]: Stopped The nginx HTTP and reverse proxy server.
Oct 25 05:44:40 web-test systemd[1]: Starting The nginx HTTP and reverse proxy server...
Oct 25 05:44:40 web-test nginx[13630]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Oct 25 05:44:40 web-test nginx[13630]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Oct 25 05:44:40 web-test systemd[1]: Failed to read PID from file /run/nginx.pid: Invalid argument
Oct 25 05:44:40 web-test systemd[1]: Started The nginx HTTP and reverse proxy server.
Oct 26 08:33:01 web-test systemd[1]: Stopping The nginx HTTP and reverse proxy server...
Oct 26 08:33:01 web-test systemd[1]: Stopped The nginx HTTP and reverse proxy server.
すると・・・パイプラインが動き出す

Running with gitlab-runner 11.3.1 (0aa5179e)
on autohealing 2cd3b42d
Using Shell executor...
Running on ansible-server...
Fetching changes...
HEAD is now at 324102c 改装を変更
Checking out 324102c4 as master...
Skipping Git submodules setup
$ sudo ansible-playbook -i ./ansible/inventories/hosts -u ansible --private-key=/home/ansible/.ssh/id_rsa ./ansible/site_test.yml
PLAY [start nginx] *************************************************************
TASK [Gathering Facts] *********************************************************
ok: [XXX.XXX.XXX.XXX]
TASK [nginx : start nginx] *****************************************************
changed: [XXX.XXX.XXX.XXX]
PLAY RECAP *********************************************************************
XXX.XXX.XXX.XXX : ok=2 changed=1 unreachable=0 failed=0
Job succeeded
Nginxのステータスを見てみると・・・復活している!
$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2018-10-26 08:41:40 UTC; 1min 16s ago
Process: 15845 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 15842 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 15841 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 15847 (nginx)
CGroup: /system.slice/nginx.service
├─15847 nginx: master process /usr/sbin/nginx
└─15848 nginx: worker process
Oct 26 08:41:39 web-test systemd[1]: Starting The nginx HTTP and reverse proxy server...
Oct 26 08:41:40 web-test nginx[15842]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Oct 26 08:41:40 web-test nginx[15842]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Oct 26 08:41:40 web-test systemd[1]: Failed to read PID from file /run/nginx.pid: Invalid argument
Oct 26 08:41:40 web-test systemd[1]: Started The nginx HTTP and reverse proxy server.
今後やりたいこと
gitlabの通知をする際に、variablesを付加してansibleで使用するplaybookを動的に変更出来るようにしておきたい。