LoginSignup
3

More than 5 years have passed since last update.

Stackdriver+Gitlab-CI+Ansibleで自動復旧の仕組みを構築する

Last updated at Posted at 2018-10-26

はじめに

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

全体構成

autohealing (2).png

補足

後述もしているが、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

hosts
[nginx]
XXX.XXX.XXX.XXX
main.yml
- name: start nginx
  systemd:
    name: nginx
    state: started
site_test.yml
- name: start nginx
  hosts: nginx
  become: yes
  roles: 
    - nginx

.gilab-ci.ymlの設定

ansibleというユーザーを作って、ansibleユーザーで実行する。
また、ansibleユーザーの公開鍵は、監視対象となるNginxサーバがあるGCPプロジェクトに登録しておく。

.gitlab-ci.yml
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! 

こんな感じでrunnerが登録される
CI : CD Settings · CI : CD · blcloud-infra : blcloud-autohealing · GitLab 2018-10-20 14-13-28.png

.netrcを作成する

git pullとかするときにアカウント情報聞かれてめんどいので、 .netrcを作っておく

$ su - gitlab-runner
$ vi .netrc
machine gitlab.com
login ci-user(適当)
password ci-password(適当)

Pipeline triggerを設定

GitLabにてtriggerを設定して、webhookで使用するtokenを取得する。

スクリーンショット 2018-10-20 22.28.13.png

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の設定

スクリーンショット 2018-10-25 9.46.41.png

alertの設定

スクリーンショット 2018-10-25 9.43.51.png

notificationの設定

スクリーンショット 2018-10-25 9.53.01.png

いざ実践

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.

Stackdriverで障害を検知!
スクリーンショット 2018-10-26 17.41.43.png

すると・・・パイプラインが動き出す

Pipelines · blcloud-infra : blcloud-autohealing · GitLab 2018-10-25 13-24-57.png

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.

スクリーンショット 2018-10-26 18.08.07.png

今後やりたいこと

gitlabの通知をする際に、variablesを付加してansibleで使用するplaybookを動的に変更出来るようにしておきたい。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3