2017年12月4日月曜日

指定された国のタイムゾーン情報をどうやって設定すれば良いか調べる方法

海外向けサービスを構築したときのお話です。
たとえば突然「インドネシア向けサービスを作りたいんだけどさ」みたいなことを言われたとします。
専用サーバを構築するとして、そのサーバの時刻をその国のタイムゾーンで合わせないといけないわけです。
どうやって合わせる…?ていうか時差は何時間?

まずその国の「アルファベット2文字の国コード」を確認します。
例えばこのWikipediaのページで確認できます。
日本なら、「JP」ですね。インドネシアは「ID」です。
次に、このWikipediaのページを開いて、その2文字の国コードの行を検索します。
「CC」の列が「ID」の行です。
4つありますね。
これにより、インドネシアにはタイムゾーンが4種類あり、GMT+07:00、GMT+08:00、GMT+09:00の3種類があるわけです。
なので、エンジニアとしては「調べたところ、インドネシアは時差が4種類ほどあるようなのですが、どれにすれば良いでしょうか?」みたいなことを言って確認する必要が出てくるわけです。

以上、簡単ですが、何気に重要なタイムゾーンの選定方法でした。


2017年12月1日金曜日

社内でガチの初心者向けDocker勉強会をしました

その時のスライドがこちらです。




勉強会当日には、主に「Dockerを一ミリも使ったことがないエンジニア」に集まっていただき、Dockerってどんな感じのソフトウェア・システムなのか、自社ではどんな感じで開発に利用してるのかというような観点でお話しました。

デザイナーも来てくれたりしたので、具体的な操作方法は抜きにしてとにかく概要を理解してもらうことに重点を置いたスライドになりました。

本当はハンズオンのパートを作る時間を捻出できなかっただけですが…。

社内では割と好評だったので(そもそも勉強会をオラッっとやる人が少ない…)、次回はECSについて説明するようなスライドを作成できればと考えています。


2017年8月2日水曜日

オライリーのDocker本を読んだり色々な記事を読んだりしたので自分なりにまとめる(Dockerfileについて)

Docker経験値0だった私も何冊か本を読んで実際にDockerfileを見たりいじったりしてみてECSに試行錯誤でデプロイしてみたりして、ようやく少しずつ慣れてきた感が出てきました。
しかしまだまだ「バッチリできます!」というには力不足間は否めなく…いやそういう話じゃない。
折角本を読んだりネット上の先輩たちの記事を読んだりして色々覚えたのだから、それをまとめておきたいと思います。
実はもうすでに日本語での公式なDockerfileベストプラクティスが存在するので、意味がないといえばたぶん意味はないのですが、アウトプットをして学習にいったんの区切りをつけるという意味で自己満足も兼ねて書きたいと思います。

Dockerfileについての基本的なこと

  • 1コンテナ1プロセスを起動するつもりでDockerfileを書く
    • 1プロセスとはつまりnginxとmod-phpによるPHPアプリケーションなら2つのコンテナを用意するということ
  • コマンドは大文字で書く( RUN, COPY, EXPOSE 等)
  • #によるコメントアウトが使える
  • FROM 文は先頭に1行だけ書く
  • CMD 文は末尾に1行だけ書く

Dockerfile についてやるべきこと・意識すべきこと

  • DockerHub のイメージは「公式」とわかるもの以外むやみやたらに使わずできるだけ Dockerfile を読んでから利用を判断する
    DockerHub は Docker イメージの共有サイトだが、有象無象のコンテナイメージが登録されており、(その意図はなくても)セキュリティ的に危険なコンテナが存在する可能性は十分にある。 DockerHubが公式に提供しているNginx など、ソフトウェアベンダ(団体)の公式イメージ以外は基本的に利用しないことで基本的なセキュリティある程度確保することができる。
  • 構文にはshell形式とexec形式が利用できるものがあるが基本的にexec形式を利用する
    例えばCMDコマンドはshell形式とexec形式を利用することができる。
    shell形式は指定された文字列を /bin/sh -c に渡すことでコマンドを実行する。
    その場合に、exec形式だと/bin/shに対する攻撃のような文字列の実行を回避することができる。
  • FROM 文で引用するイメージのタグに latest は利用しない
    Docker はタグと呼ばれるバージョン情報で Docker イメージのバージョンを管理、選別することができる。
    latest は文字のごとく最新のバージョンのイメージに使われるタグのように見せかけて、実は Docker の予約語であり、特別にタグを指定していない時のデフォルト値として勝手に付与される。つまりそれは latest =! 最新という可能性を否定できず、意図しない動作を引き起こす原因になるかもしれない。
  • 作成したイメージには一意なタグを設定し latest は利用しない
    上述の「FROM 文で引用するイメージのタグに latest は利用しない」と同じ理由。
    もしも「これは最新のイメージです」という意味の任意のタグが必要であれば、「newest」といったタグを自分で設定するのがよい。
  • Docker はイメージのミルフィーユであることを意識する
    Docker は自身の軽量化のため、イメージ生成の各段階でスナップショットとしての中間イメージを作成する。
    そしてそれらの中間イメージは他の Docker イメージを作る際などでも流用できるものはキャッシュとして流用される。
    そして、その中間イメージは Dockerfile の1行ごとに作成される。
    なので Dockerfile の行数を減らすことによりイメージの軽量化に貢献し、開発プロセスをより高速に回すことができる。
  • MAINTAINER 文はオライリーの Docker 本でも必須などとは書かれていなかったけれどもできる限り書いた方がよい
    個人のプロジェクトで DockerHub にイメージを登録する場合は改善要望などをもらえるかもしれない。
    仕事で Dockerfile を書く場合にたとえプライベートリポジトリを用意されていたとしても、プロジェクトの共通メールアドレスなどを記載しておくと出生が分かって他のプロジェクトからの利用しやすくなる可能性など考えられる。
  • CMD 文は上書きされる 最後の1つのみが適用される
    また、ENTRYPOINT 文を書いたときは、そちらが最優先となって適用される。
    ただし、その場合CMD文を ENTRYPOINT 文の引数部分として利用することができる。
    CMD文と同等のコマンドは、docker run 実行時のオプションとしても与えることができる。
    つまりそのオプションで ENTRYPOINT 文の引数を与えることができる。
  • 明示的に圧縮ファイルの展開が必要な場合以外は基本的に COPY 文を使う
    ADD と COPY はどちらもホスト(開発端末)上のファイルをコンテナに転送するが、 ADD は圧縮ファイルの展開なども行う。
    ただのファイル転送であれば COPY 文を利用することで不要な誤解や不慮の不具合を防ぐことができる。
  • yum や apt-get で複数のパッケージをインストールする際は1行のRUN文内でできるかぎりすべてのパッケージをインストールする
    RUN 文を記述するたびに Docker は中間イメージを生成する。
    そのため、パッケージマネージャで各種プログラムをインストールする際は、必要なものをできる限り1回でインストールすることが Dockerfile としては望ましい。
  • yum や apt-get で複数のパッケージをインストールする際はパッケージ名ごとに改行し、かつ、パッケージ名をアルファベット順に記載する
    上述の中間イメージ節約を考慮しつつ、可読性を向上させるためのTipsとして推奨されている。
  • RUN 文で cd は使わずに WORKDIR 文 を利用する
    WORKDIR 文はコンテナ内での作業ディレクトリを定義する。
    用意されている WORKDIR 文を利用することで可読性が向上し、メンテナンスがしやすくなる。 また、同様の理由でパスには絶対パスを利用する。
  • RUN 文 と USER 文を利用してコンテナのプロセス実行ユーザを定義した方がよい Dockerは何もな考えずにイメージを起動するとrootユーザで実行されることが多い。
    VMと違って、ホストマシン(開発端末・本番環境のDockerサーバ)のrootと同じユーザとして振舞う。
  • root権限奪取の危険性を減らすためにコンテナ内に非rootなユーザを作成してそいつにプロセスを起動させる
    日本語のエントリでこれについて言及している人は何故か少ないが、オライリーの Docker 本には明確に書かれてあるし、 How secure are Docker containers? (Ben Hall) - Full Stack Fest 2016 などでも言及されている。
    利用しているイメージのDockerfileが非rootユーザを作成していない場合はできる限り非rootユーザを作成した方がよいのでは。
    そういう意味でも利用するイメージのDockerfileには一度目を通しておいた方がよいのではと考えられる。

2017年6月28日水曜日

日本語ドメインについてお勉強したのでそのまとめ

日本語.jp みたいなドメインってたまに見かけますが実際に自分が運用することになるとは思わなかったので学んだことをまとめたいと思います。
このような形式のドメイン名は「国際化ドメイン名」と呼ばれるものらしいです。

従来のアルファベット、数字、ハイフン以外にマルチバイト文字を利用できるようにする仕組みのことで、日本語の他にもアラビア文字なども利用できるようです。
ただ、毎回国際化ドメインと呼ぶのもアレだし非エンジニアのスタッフに説明する時に相手に難しそうなイメージを持たれたくないので、
日本語が含まれたドメイン名のことを日本語ドメインと会社では呼んでいます。
中国語だったら中国語ドメインですね。

この日本語ドメインをDNSサーバが理解できるようにするためには、Punycode(ピュニコード)と呼ばれる形式で、アルファベット数字ハイフンだけの、既存のドメイン名に使用できる文字だけの対応ドメインに変換してあげる必要があります。
言いたかったのはそれだけです。

たとえば、JPRSが運用している 日本語.jp はPunycodeだと xn--wgv71a119e.jp になります。

これはHTTPS接続についてほんのちょっとだけめんどくさいトラブルが発生します。
curlなどでHTTPアクセスのテストをすることはよくあると思いますが、開発している日本語ドメインのサービスがHTTPSを基本としていて、curlでもHTTPSで行う場合、通常はSSLに関するエラーが出力されます。
SSL証明書を取得するときはPunycode変換済みのドメイン名で取得することが前提となっており、変換済みのドメインは変換前のドメインとリテラル的に同等とみなされないからです。
SSL証明書エラーを回避するには curlの -k オプションを利用します。

今回私が運用することになった日本語のドメイン名は、AWSのACMで無料の証明書を取得しました。
そのドメインは お名前.com で購入したのですが、デフォルトの状態では取得不可能でした。
なぜか?それは、こちらの仕様によるもの

日本語ドメインは、A / AAAA / CNAMEレコードのみご利用いただくことが可能です。
設定方法はこちらをご参照ください。

これはMXレコードを設定できないことを意味します。
MXレコードが設定できないということは、該当ドメインでのメール受信ができないことを示します。
つまり、ACMで必須となる認証メールによるACM発行承認が得られないわけです。

なので、何らかの方法でお名前.com以外のDNSサーバ、できればRoute53でDNSレコードが管理できる状況にしなければなりません。
私は「お名前.comのドメインをAWSで使用する4つの方法 - Qiita」によるところの、2番目の方法で実質的な管理者をRoute53に変更して対応しました。

これを行うことにより、Route53上で好きなようにDNSレコードを設定することができるようになりました。
これでACMの証明書が取得できましたので、ELBやCloudFrontに登録して、快適HTTPSライフが遅れるという算段です。

以上がTIL(Today I Learned)になります。
これから同様の仕事を行う方の参考になれば幸いです。




2017年5月4日木曜日

基本的な使い方を学ぶために速習Docker的なことをしました

MacでDockerを使うために基本的な使い方を学習しました。
下記を読みながら、適宜読み替えたりググったりしてコマンドを実行してみました。


Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!] (Software Design plus)

Docker実行環境の構築

brew install docker
brew install docker-machine
brew install docker-compose

Dockerマシンを作成しようとして失敗

TearTheSky-MacBook:~ TearTheSky$ docker-machine create --driver virtualbox test-docker
Running pre-create checks...
(test-docker) You are using version 4.3.26r98988 of VirtualBox. If you encounter issues, you might want to upgrade to version 5 at https://www.virtualbox.org
Error with pre-create check: "VirtualBox is configured with multiple host-only adapters with the same IP \"192.168.33.1\". Please remove one."
TearTheSky-MacBook:~ TearTheSky$

VirtualBox上のDockerマシンの確認

TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
test-docker   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.04.0-ce
TearTheSky-MacBook:~ TearTheSky$

Dockerコンテナを確認しようとして失敗

TearTheSky-MacBook:~ TearTheSky$ docker ps
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
TearTheSky-MacBook:~ TearTheSky$

対処法

yoshida-no-MacBook-Pro:~ TearTheSky$ eval "$(docker-machine env test-docker)"
TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
TearTheSky-MacBook:~ TearTheSky$

Dockerコンテナの作成

TearTheSky-MacBook:~ TearTheSky$ docker run -d -p 80:80 --name webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
6d827a3ef358: Pull complete
f8f2e0556751: Pull complete
5c9972dca3fd: Pull complete
451b9524cb06: Pull complete
Digest: sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582
Status: Downloaded newer image for nginx:latest
61d1da7ae17cf573ceb51a99b213cb5e315150ce92ee8c23686898e28d603946
TearTheSky-MacBook:~ TearTheSky$

Dockerコンテナの確認

TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
61d1da7ae17c        nginx               "nginx -g 'daemon off"   15 seconds ago      Up 14 seconds       0.0.0.0:80->80/tcp, 443/tcp   webserver
TearTheSky-MacBook:~ TearTheSky$

Nginxの起動確認

ブラウザで「192.168.99.100」にアクセスするとNginxデフォルトページが表示される。
「192.168.99.100」はVirtualBox上のDockerコンテナホスト。

Dockerコンテナの削除

TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
61d1da7ae17c        nginx               "nginx -g 'daemon off"   25 minutes ago      Up 25 minutes       0.0.0.0:80->80/tcp, 443/tcp   webserver
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker rm webserver
Error response from daemon: You cannot remove a running container 61d1da7ae17cf573ceb51a99b213cb5e315150ce92ee8c23686898e28d603946. Stop the container before attempting removal or force remove
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker stop webserver
webserver
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker rm webserver
webserver
TearTheSky-MacBook:~ TearTheSky$

VirtualBox上のDockerマシンの停止と削除

TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
test-docker   *        virtualbox   Running   tcp://192.168.99.100:2376           v17.04.0-ce
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine kill test-docker
Killing "test-docker"...
Machine "test-docker" was killed.
TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
test-docker   -        virtualbox   Stopped                 Unknown
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine rm test-docker
About to remove test-docker
Are you sure? (y/n): y
Successfully removed test-docker
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS
TearTheSky-MacBook:~ TearTheSky$

Docker for Macのインストールと利用

インストール

Docker Machine でコンテナを立てたような感じでコンテナを立てる

TearTheSky-MacBook:~ TearTheSky$ docker run -d -p 80:80 --name webserver nginx
TearTheSky-MacBook:~ TearTheSky$ docker ps

Nginxの起動確認

ブラウザで「localhost」にアクセスするとNginxデフォルトページが表示される。
VirtualBoxには仮想マシンが存在しない。

Docker Machine と Docker for Mac の違い

Docker Machine は 書籍上の Boot2Docker と同じ立ち位置で、Mac上にVirtualBoxを使って仮想マシンのLinuxを起動し、それをコンテナサーバとして、その中にコンテナを立てる。
Docker for Mac は Macbook 自身がコンテナサーバになる。
なのでVirtualBox上に仮想マシンは不要だし、起動されない。
なるほどなるほど。 基本の使い方は理解できました。

2017年3月7日火曜日

AWSを使ってソーリーサーバを構築しました。割と便利だと思う…。

とてもお久しぶりです。
恵比寿のITベンチャーでサービス運営やっています。
仲間募集中です。ご興味ある方はTwitterなどでご連絡ください。

今回はAWSを使って、わりと便利なソーリーサーバを構築しましたというお話です。
構成は下の図のようになっています。



通信フローとしては、まずエンドユーザがELBにアクセスします。 このELBは既存のWebサービスやWebサイトをバランシングしていたものです。 諸事情によりメンテナンスしたり、ドメインを畳むことになったという話を想定しています。
そのELBに接続されていたWebサーバやアプリケーションサーバの代わりにソーリーサーバを接続します。 するとエンドユーザはソーリーサーバにアクセスしてきますよね。
ソーリーサーバはリクエストを受けたら、各ドメインに対応させたいCloudFrontへリクエストをパスします。 CloudFrontはS3のコンテンツを返すのですが、このS3に静的なソーリーページを格納しておきます。 それにより、ドメインにアクセスしてきたエンドユーザにソーリーページを見せることができます。
ポイントはソーリーサーバとCloudFrontですがやってることは簡単です。 まず、ソーリーサーバはただのNginxです。 proxy_pass を使って、特定ドメインに来たリクエストを対応するCloudFrontのドメインへパスします。 その設定は、/etc/nginx/conf.d/virtual.conf に書きました。
server {
        listen 80;
        server_name example.com;
        if ($http_x_forwarded_proto != https) {
                return 301 https://$host$request_uri;
        }
        location / {
                proxy_pass http://domain-a.sorry.example.com/;
        }
}
上記の server ディレクティブのかたまりを、ソーリーページの数だけ用意します。 1ドメイン1種類のページでよければ、3ドメインなら3つのディレクティブになります。
if文のおかげで、自動でHTTPSになります。
しかしここで一つ問題があります。 ELBごとにヘルスチェックエンドポイントが違うのです。 なのでそのままではそもそもNginxがヘルスチェックに合格せず、ELBがNginxにリクエストを渡してくれません。
それはNginxの素敵機能 empty_gif を使って解決します。 今回は /etc/nginx/nginx.conf に以下のように書きました。
http {
    (略)
    server { 
        (略)
        location / {
                 empty_gif;
                break;
        }
    (略)
    } 
    (略)
}
これにより、どんなパスへのアクセスに対しても 1ピクセルのgifイメージを生成して返します。 そのおかげで、ELBのどんなヘルスチェックパスも合格し、めでたく InService になることができます。
残りは CloudFront ですね。
CloudFrontはソーリーページごとにインスタンスを用意する必要があります。
理由はカスタムエラーページを利用したいからです。
CloudFrontのカスタムエラーページでは、特定のHTTPステータースコードの場合、任意のステータスコードに変更することができ、さらに任意のコンテンツを表示させることができます。
これを使って、全ての403アクセスを404へ変更して、ついでにソーリーページのhtmlを表示させちゃうことができます。
なんで403にするかというと、CloudFront + S3 でのコンテンツ配信方式で、ページが存在しない場合、CloudFront側が 403 Access Denied を返すからです。
これを404+ソーリーページにすることで、どんな存在しないURLにアクセスが来ても、自分が用意した404用のhtmlが表示されることになります。
ただし、「正しいソーリーページのパス」にアクセスされると、ステータスコードは200になってしまいます。
よほどの物好きなエンドユーザ意外はそんなことしないので、気にしないことにしました。
Nginxのコンフィグの書き方でもうちょっとCloudFrontのインスタンスを減らせる気もしますが、料金体系的にデータ転送量とリクエスト数のみで、インスタンス数による固定料金はないので、管理は面倒くさいですがこれでいいかなという感じです。

あ、あと、ACMを使って無料証明書を取得してCloudFrontに登録しています。
そのために、 sorry.example.com のような、ソーリーページ専用サブドメインを用意して、 それのワイルドカード証明書をACMから発行させてもらっています。

ところで何が便利なの?
まず、ステータスコードを任意に指定できます。404とか、500とか。それから、ソーリーページにhttpsが使えます。労力の割には些細なリターンのような気もしますが…。
NginxのコンフィグはGitで管理してAnsibleなどで配布できます。
1台に全部のソーリーページについて書かなきゃいけないですが、書いてしまえば、1台をマスターサーバにして楽にスケールアウトできます。
マスターサーバのコンフィグに全てのソーリーページの設定が書かれてあるので、ドメインに対して透過的なソーリーサーバが出来上がります。
どのELBにどのサーバを突っ込んでもOKということです。

2016年10月30日日曜日

小さな会社で一人で監視サーバ立てて運用して一年以上たったのでそのまとめ


MECE目指して書き始めたけど全然無理でした。多分、初心者向けです。
仕事で書いたドキュメントの流用です。
会社にはインフラでズバッと意見を出す人がいないので、こういう割と広いこと見れてそうな入門ドキュメントを会社のドキュメントとしてためておくことで、将来誰か監視システムを刷新するときとかの方向性になれればという考えです。

持つべきか、もたざるべきか

まず大枠の設計として、監視システムを持つべきか、持たざるべきかという点について考える必要があると思います。
これは監視をするかしないかという意味ではなく、監視システムのサーバを持つかどうかという意味を指します。
つまりZabbixやmuninといった監視サーバを構築して運用していくのか、それともMackerelやNew Relicといった SaaS監視システムにお金を払って利用するのか、という監視システム運用の方向性の問題です。
私の場合は、会社でインフラエンジニアが私一人だったので、私の興味からZabbixを立てることにしました。
Zabbixに惹かれたのは主に「ネット上に先人の記事がそれなりに上がってる」「カスタムスクリプト書けばなんでもできる」「成長したイケてるベンチャーも使ってて実はダサくない」という3点で、とくにスクリプトを書けばなんでもできそうというのは、私自身のコーディング経験の足しにもできるし、アプリケーションエンジニアにも説明すれば監視業務にコミットしてもらえそうという期待からでした。
 CTOは新しくてイケてるSaaSを使うのが大好きだったので、実はすでにNew Relicが入っていました。しかし有料プランは結構高く、財布事情が許してくれなかったので、私の提案をしぶしぶ飲んで、Zabbixとの並行運用になりました。
そしていま運用して一年ちょいになりますが、Zabbixでできることが増えてきたので、New Relicはほとんど見ていません。
エージェント自体は残っているけど…。

監視システムに欲しい機能

監視システムには下にあげる機能が基本的に存在しているでしょう。
一部の特化型システムにはないものもあるかもしれないですが…。
そして、それらができるだけ自動化されていることが望ましいです。
ここでいう自動化とは、少ない手作業で必要な多くの作業をこなしてくれるという意味を含みます。 
  • 監視対象サーバ登録削除編集
  • 監視対象サーバの監視有効無効化
  • 監視項目追加削除編集
  • 閾値に応じたアラートの登録削除編集
    • 監視システムの画面上で表示
    • メール通知
    • 電話通知
    • スマートフォンアプリケーション通知(チャットとか)
  • 監視結果のグラフ表示
  • 複数のサーバのグラフを一元表示
  • カスタム(自作)スクリプト実行
  • カスタム(自作)監視項目追加削除編集
  • ユーザ複数作成と各ユーザの利用権限編集
  • 監視結果グラフをパッと見れるダッシュボード

やっておきたい連携

メール連携

原始的だけど社会人だったら誰でも理解できる説明がもっとも容易な連携。 
私の場合はZabbixのサーバにPostfixを入れて運用する様にしてしまったけれど、今から作り直すならSESのスタック立ててZabbixはそこを使う様にするかな…。
ついでにACMも認証させてSSL証明書もゲットしておくと尚よし。

チャットシステムとの連携

具体的には、Slack、HipChat、ChatWorkなど。
私の勤務先ではSlackを使っており、かつ有料プランになっているので、メール連携が使えたのでそれを使っています。
コードを書かずに連携できて超ラクです。ありがたや。
設定を行うとSlackからメールアドレスが発行されるので、それをZabbixでアラート通知用メールアドレスとして使用するだけです。
かんたん。
 障害、復旧、閾値オーバー、レスポンス速度悪化、バッチジョブ開始、バッチジョブ完了、サーバ新規追加、などをメール連携でSlackに飛ばす様にしていますが、開発チームみんなに全部投げるのもアレなので、何個かチャンネル分けて、たとえばたくさんの人がみる監視チャンネルには障害やジョブ失敗のアラートのみを投げる様にしています。
そんで、ジョブ成功とかは私だけが入ってるチャンネルを作ってそこに流したり。
半日単位とかでガーっとスクロールして流し見したりします。

電話連携

実はできていません…。
データセンターがメルアドを持っているので、そこにメール送って電話させようぜという人力電話連携構想が社内で湧いており、とりあえずそれでいっかな…。
そのうちTwillio連携とかさせたい。
優先度低い。

分けられる要素はできるだけ別インスタンスにしたい

たとえば私の場合はAWS上にZabbixを立てたわけですが、DBはRDSを利用しています。
その方がDBで心配する確率が減っていいです。
同様にメールサーバもZabbix内に立てるのではなく、SESなどを使った方がいいです。
その辺はケチったところで運用のための監視サーバのための運用がつらくなるだけなので、ある程度お金を使わせていただきたい…。

インフラエンジニア以外に使ってもらうにはお膳立て必須

  • ログインしてぱぱっと問題ないかを確認するまでの手順
  • 全体の状況を一覧で見れるダッシュボードへのアクセス手順
  • そういうダッシュボードの作成
  • チャットアプリに飛んでくるメッセージの意味と対処方法
  • よくある障害の内容と復旧方法
私の場合は多分まだ全然足りてなくて、10割オペレーションが7.5割に減ったくらいかな…。
マネージャーの上司にZabbixのスクリーンを教えたら自分でグラフ組み立てて性能レポート画面作ってたのはいい結果だったかなと思います。
障害対応とかはアプリケーションエンジニアにも少しずつシェアできると万々歳なんだけどそもそもPCを持ち帰っていないとか色々あるので私が対応…といってもサーバ多めにしてたりするので正統派なシステムダウンはもう全然起こっていません。
平日に利用者からくるアプリケーション不具合やデータ不整合に関する問い合わせ調査なんかはむしろ他のエンジニアにやってもらっているので、多分それでバランスはとれています…。

監視項目や検知内容は育てる前提で

監視項目はググって引っ張ってきていいと思いますが、まずは基本的に
  • CPU使用率
  • メモリ使用率
  • ロードアベレージ
を見ておけばいいのかなと思います。そしてそれらの使用率高騰のアラートを設定しておく。
DBは上記に加えて、
  • コネクション数
  • ストレージ残容量
なども必要ですね。気づいたらディスクがいっぱいでDB停止からのサービス停止とか怖いですね。
Webサーバのプロセス処理方式が Prefork の場合には
  • 稼働プロセス数
も監視しておいた方がいいですね。利用者が増えてくるとそこがボトルネックになることもあると思います。
それから運用しているWebサービスの主要エンドポイント(URL)の
  • レスポンスタイム
  • レスポンスコード
を見ておきましょう。
POSTが送れる場合はテストユーザでのログインとかをZabbixにやらせることもできると思いますので、そこでエラーコードが帰ってきたらログイン機能がトラブル!?みたいな検知もできるかなと思います。

手に入れた値はCloudWatchに寄せるのか、監視スステムに寄せるのか

AWS特有の悩みです。どっちかに決めるしかないです。悩ましいことにどっちもお互いにインポートすることができます。
私の場合は、CloudWatchは課金しないと2週間分しかログが残ってくれないので、一年単位でのトレンド分析とかそういうのには向いてなさそう…という理由でZabbix側に寄せることにしました。
つまり、CloudWatchが持ってる値のうち欲しいものをスクリプト書いてそいつに持ってこさせます。
するとZabbix側で好きにアラートやアクションを設定していろいろ処理することができます。
というかそういうことやらないとわざわざZabbix立てる意味はない…。

プロセス自動復旧

Zabbixの場合は、ダウンを検知したらZabbixからコマンド実行命令を出して復旧させることで自動復旧が実現できます。
私の場合はまだまだ導入が少ないので増やしていきたいところ…。

Mackerel使わないの?

なんか料金とインベントリ数だったかグラフ数だったか外形監視数だったかのコスパを考えると見合わないかなぁと思って検討をやめました。
プログラマフレンドリーっぽいので私がいなくなったらアプリエンジニアたちが乗り換えるかもしれません??


以上。
ある程度監視項目とか増えてきて回り始めると他のことに時間を取られて監視システムの成長が鈍化するのがつらいところ。
仲間が欲しい。