ようへいの日々精進XP

よかろうもん

2018 年 12 月 16 日 (日)

ジョギング

  • お休み

日課

  • 腹筋が出来るようになってきたので, 明日から筋トレは再開したい

ルミエール

自宅から車で 10 分くらい行ったところに, ルミエールというディスカウントストアがあるらしいので奥さんと出かけた.

ディスカウントストア ルミエール

香椎に住んでいた時に利用していたダイレックスと同じ感じで, 生鮮食品が充実していたけど, 車で行くと駐車場の確保が大変なので, 次回はチャリンコで行きたい

豚汁

寒いので温かいものを...というリクエストを奥さんに出したら豚汁を作ってくれた. 里芋も入っていてとても美味しかった.

Nagios のアラート通知をホスト単位で有効化, 無効化, ホストの情報を取得するコマンドラインツールを作った 〜 Kubernetes も触ってみたよ 〜

tl;dr

シェルスクリプトで作成してたものを, 諸般の事情から, 勉強がてら Go で書き直してみました. 記事のタイトル通り, Nagios のアラート通知を有効化, 無効化, ホストの情報 (Host State Information) を取得するだけの機能を持っています.

作ったもの

github.com

テレビでシン・ゴジラを見ながら作ったので...名前は godzilla っぽくしてみました.

自分の知る限りでは...

Nagios は他の監視ツールのように, REST API で監視や通知の状態を操作することはオフィシャルでは出来ないという認識でして, シェルスクリプト版を作成した際にも, 以下のブログ記事を参考にして curl で操作出来るように実装していました.

cloudpack.media

Nagios に用意されている「外部コマンド」を curl または HTTP クライアントで叩くことで, ブラウザ操作以外からの操作を実現しています. 今回は, Go 言語の net/http パッケージを利用しています.

何が大変だったか

Nagios の外部コマンドを Go 言語から叩く部分については, 特に難しいことはありませんでした. 今回は Nagios 自体に Basic 認証が設定されているホストを対象としているので, リクエストヘッダに認証情報を追加してあげることで, 通知の有効, 無効, ホストの情報を取得することは出来ました.

ところが, レスポンスはシンプルとは言え, JSON ではなく HTML で返却される為, HTML を解析する必要がありました...これが, 今回の鬼門で一番時間が掛かりました. HTML 解析には, 以下のように net/html を利用しています.

...
func ParseCheckHostStatus(targetHost string, body io.Reader) {
    z := html.NewTokenizer(body)
    keys := []string{}
    values := []string{}

    // 苦肉の HTML 解析...
    for z.Token().Data != "html" {
        tt := z.Next()
        if tt == html.StartTagToken {
            t := z.Token()
            var key string
            var value string
            if t.Data == "td" {
                inner1 := z.Next()
                if inner1 == html.TextToken {
                    text := ((string)(z.Text()))
                    if strings.TrimSpace(text) != "" {
                        key = strings.TrimSpace(text)
                        if strings.HasSuffix(key, ":") || strings.HasSuffix(key, "?") {
                            keys = append(keys, strings.Trim(key, ":?"))
                        } else {
                            values = append(values, strings.Trim(key, ":?"))
                        }
                    }
                }

                if inner1 == html.StartTagToken {
                    if z.Token().Data == "div" {
                        inner2 := z.Next()
                        if inner2 == html.TextToken {
                            text := (string)(z.Text())
                            if strings.TrimSpace(text) != "" {
                                value = strings.TrimSpace(text)
                                values = append(values, strings.Trim(value, ":?"))
                            }
                        }
                    }
                }
            }
        }
    }

    m := map[string]string{}
    for i := 0; i < len(keys); i++ {
        m[keys[i]] = values[i]
    }
    // fmt.Println(m)
    data := map[string]interface{}{"Host": targetHost, "Status": m}
    data_json, _ := json.Marshal(data)
    fmt.Println(string(data_json))
}
...

下図のような Host State Information の情報を解析して JSON で出力しているクソコードです. 苦肉の対応が随所に見られていて, 本当にこれで良いのか悩みどころではあります.

f:id:inokara:20181217000113p:plain

ハンズオン的な

KubernetesNagios を立ち上げる

Docker for MacKubernetes を有効にして, 以下のようなマニフェストを書きました.

$ cat nagios.yml
---
apiVersion: v1
kind: Service
metadata:
  name: nagios-externalip
spec:
  type: LoadBalancer
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 8080
      targetPort: 80
  selector:
    app: nagios-pod
---
apiVersion: v1
kind: Pod
metadata:
  name: nagios-pod
  labels:
    app: nagios-pod
spec:
  containers:
    - name: nagios-container
      image: jasonrivers/nagios:latest
      ports:
      - containerPort: 80

Docker Compose っぽいなあというのがファーストインプレッションです.

以下のように実行して, 環境を起動します.

kubectl apply -f nagios.yml

LoadBalancer サービスや Nagios 環境の Pod が正常に起動すると http://localhost:8080Nagios の Web コンソールにアクセスすることが出来ます. 今回, Nagios コンテナは以下のコンテナを利用しています.

github.com

Nagios のバージョンは 4.4.2 となります. また, nagilla は以下の環境で実行しています.

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.13.6
BuildVersion:   17G65

$ nagilla -version
0.0.1

ホストの情報を取得

nagilla を始める為には, direnv が必要になります. また, 以下のように設定ファイルを JSON で書いておく必要があります. 詳細は README をご確認下さい.

以下を実行して, ホストの状態を確認してみます.

$ nagilla -hosts=localhost -check | jq .
{
  "Host": "localhost",
  "Status": {
    "Active Checks": "ENABLED",
    "Check Latency / Duration": "0.001 / 4.150 seconds",
    "Check Type": "ACTIVE",
    "Current Attempt": "1/10  (HARD state)",
    "Event Handler": "ENABLED",
    "Flap Detection": "ENABLED",
    "Host Status": "UP",
    "In Scheduled Downtime": "NO",
    "Is This Host Flapping": "NO",
    "Last Check Time": "12-16-2018 15:06:01",
    "Last Notification": "N/A (notification 0)",
    "Last State Change": "12-16-2018 10:37:29",
    "Last Update": "12-16-2018 15:08:07  ( 0d  0h  0m  3s ago)",
    "Next Scheduled Active Check": "12-16-2018 15:11:01",
    "Notifications": "DISABLED",
    "Obsessing": "ENABLED",
    "Passive Checks": "ENABLED",
    "Performance Data": "rta=0.077000ms;3000.000000;5000.000000;0.000000 pl=0%;80;100;0",
    "Status Information": "PING OK - Packet loss = 0%, RTA = 0.08 ms"
  }
}

-hosts に対象のホスト名 (Nagios に登録しているホスト名) を指定します. hosts の複数形にしているのは, 将来的にはカンマ区切りで複数指定出来るようにしたいと考えている為です. 現在, 上記のホストは通知 (Notifications) は無効 (DISABLED) になっているようです.

通知の有効化

通知を有効化します.

$ nagilla -hosts=localhost -enable
localhost
上記のホストの通知を有効しますか?(y/n): y
通知を有効にします.
通知を有効にしました.

有効化を改めて -check オプションで確認してみます.

$ nagilla -hosts=localhost -check | jq '.Status.Notifications'
"ENABLED"

上記の通り, ENABLED (有効) になっているようです.

通知の無効化

通知を無効化します.

$ nagilla -hosts=localhost -disable
localhost
上記のホストの通知を無効しますか?(y/n): y
通知を無効にします.
通知を無効にしました.

無効化を改めて -check オプションで確認してみます.

$ nagilla -hosts=localhost -check | jq '.Status.Notifications'
"DISABLED"

いい感じです. ひとまず, 単一ホストの通知の有効化, 無効化は行えるようです.

以上

とにかくコードは汚いですが, やりたいことがコマンド一発で実行出来るのは嬉しいですね. ただし, HTML のパースは個人的には苦行でした... まだまだ, 修行が必要なようです. ところで, Kubernetes を初めて触ってみました. Kubernetes は概念からちゃんと勉強していきたいけど, 取り急ぎ, 検証やギョームで Docker で動かしている諸々を Kubernetes で動かしていきたいと考えています.

2018 年 12 月 15 日 (土)

ジョギング

  • お休み

Kubernetes 勉強会

  • 青柳さんにお願いして Kubernetes のプライベート勉強会を内村さんの株式会社ペンシルで行った
  • 今回は 0 会ということで, 青柳さんによる Kubernetes の座学を 2 時間程, Kubernetesコンポーネントとしては Pod くらいしか知らなかったので, すごく勉強になった
  • ペンシルさんの後は延長戦ということで, 博多のカフェで青柳さんとマンツーマンで Kubernetes のハンズオン
  • 次回は, 予習をしてから臨みたい

かずきん夫婦と忘年会

毎年恒例のかずきん夫婦と忘年会. 三時間のカラオケまでのフルコースでとても楽しい夜だった.

メリークリスマス。

2018 年 12 月 14 日 (金)

ジョギング

  • お休み

二日酔い無し

  • 昨晩の二日酔いが無いか不安だったけど, 特に二日酔いで気分が悪いということは無し
  • 睡眠不足が少しあって気分はイマイチだった

武川さんとランチ

  • 虎ノ門ヒルズにて武川さんとランチ
  • きっと, 武川さんとは最後のランチになるかもしれないなーと思うと感慨深いものがあった
  • マンツーマンで色々と話しが出来て良かった
  • 本当に色々とお世話になって感謝の言葉しか出てこないけど, いつまでも何かしらの関係を持っておきたいなあ
  • まずは, 体を大切にして頂いて, いつまでも元気でいて欲しい

福岡に帰る

山手線がいきなり止まったりして, ちょっと焦ったりしたけど無事に羽田空港に到着.

乗り遅れるのも良い人生経験かもしれないけど, そこまでの肝は座っていなかった (笑.

相変わらず, 福岡便は満席で, 隣なのか, 前なのか, 後ろの座席は判らないけど, 誰かの (自分である可能性もある) 足のニホヒが臭くて辛かった.

とんとん

博多で奥さんと待ち合わせて, 夕飯を食べようと数軒のお店を覗いてみるも, 金曜日の夜というのと, 忘年会シーズンも重なり, どこのお店も入店を断られてしまったので, 結局, いつもの美人居酒屋にて.

2018 年 12 月 13 日 (木)

ジョギング

  • お休み

東京出張

  • アイレットでの最後の東京出張
  • というか, 忘年会に参加する為に上京させて頂いた感じ
  • ただ, タスクちゃんとスタックしているので忘年会までは黙々と作業をする

最後の忘年会

  • アイレットでは最後の忘年会
  • 会場は赤坂, 自分の一応エンジニアとして始まりの地, 赤坂で忘年会があるというのは感慨深いものがあった
  • 最後に忘年会に出たのは 2014 年だったので, 4 年ぶり
  • 9 割くらい知らない顔で人見知りの自分はかなり面食らったが, 普段, 話したことが無い人たちと色々と話せて本当に楽しかった

景品をゲットするつもりで少し大きめのスーツケースで来たのに一つもゲット出来ず...

ブログ読んでくださっている方, furikake 使ってくださっている方, 色々と声を掛けて頂いて嬉しかったし, 一人か, 二人でも誰かの役に立てているのかもしれないなと身の引き締まる思いになった.

一次会の後は, 有志の皆さんに唆されてwカラオケにジョイン. 福山雅治の HELLO を歌った. もう去っていく人間が HELLO なんて笑えるが, 人生は一期一会, その時, その時を大切に, 出会った人にはいつでも Hello と明るく声を掛けられるような人生にしていきたい. 皆さん, 有難うございました.


Hello [福山雅治]

2018 年 12 月 12 日 (水)

ジョギング

  • お休み
  • 引き続き, 左足の踝周りが痛すぎるので....どうしたらいいものか....
  • 走りたいというストレスが溜まってきている

健康診断

  • 有給取得
  • 左の腎臓に 4mm 大の石が出来ているくらい以外は問題なさげ
  • 腎臓の石について, ちゃんと水分摂ってますかと, 思わぬ質問をされて戸惑ったくらい
  • 明日から東京に行くのでバリウムはスキップ
  • ランチは奥さんと博多の馴染みのお鮨屋さんにて

わくわく忘年会

jaws-ug-kyushu.doorkeeper.jp

ただ, おっさん達が缶ビール片手にワイワイ色々と語る会にしたかったので, 全くそのとおりになって本当に楽しかった. 「俺のツールズ」の LT した.

2018 年 12 月 11 日 (火)

ジョギング

  • お休み
  • 引き続き, 左足の踝周りが痛すぎる...

一日中

雨が降っていたし, とても寒かった.

daimyo

を Backlog の公式ツイッターで紹介して頂いた.

2018 年 12 月 10 日 (月)

ジョギング

  • お休み
  • やっぱり, 左足の踝周りが痛すぎる...どうしようかしら

体調

  • 東京疲れかな...
  • 今週も木曜日から出張だな...

JapanContainerDays v18.12 報告会

connpass.com

に参加した.

ビールに大量のピザで驚いたけど, ピザは美味しいし, すごく刺激になった勉強会だった.

2018 年 12 月 09 日 (日)

ジョギング

  • 綾瀬の街を 40 分くらい
  • 左足のくるぶし, 右足の甲と色々と痛い...

福岡に帰る

  • 今回は 4 泊 5 日と長かった ( 1 泊 2 日は完全に私用だったけど)
  • 荷物が大きくて重く, これを引っ張って東京の街を行ったり来たりするのは辛かった...

夕飯

  • 奥さんが色々とお惣菜を作っていてくれて, 賑やかな晩酌となった
  • 肉と野菜のバランスを考えられていて, ちょっと味が濃いものもあったけど...とても美味しかった
  • やっぱり, 自宅で食べるご飯が最高だと思う

2018 年 12 月 08 日 (土)

ジョギング

  • 皇居 2 周
  • 同僚の矢澤さんといろいろと会話しながら走ったのでとても楽しかったので, 機会があればまた一緒に走りたい

矢澤さんと皇居ラン。めっちゃ楽しかった!ありがとうございました~

走った後に鹿屋アスリート食堂という皇居近くのごはん屋さんでランチを食べた.

www.asushoku.com

薄味でとても健康的なランチだったけど, 走った後も手伝ってとても美味しくいただくことが出来た.

秋葉原に行ったり

  • 土曜日は綾瀬国際ホテルに宿泊
  • 途中で秋葉原に寄ってはみたものの, あまり面白くなくてホテルに移動, チェックアウトまでは早かったのでカフェでコード書いたり

よっちゃん → よしじん → やすらぎ

夜は金町のいつものコース.

金町のよっちゃんマスターと。

錦通りのお店が少しずつ世代交代が進んでいる中で, よっちゃんをはじめ, よしじん, やすらぎは相変わらずの賑わいだった.

「よっちゃん」マスターは相変わらず元気そうでなにより. きょうじさんはいよいよ大将となりお店を一人で切り盛りしていて大変そうだった. 「やすらぎ」は客層が若返っていて休みの前の日ということも手伝って大盛況だった.

とにかく, たまにふら~っと立ち寄っても受け入れてくれる金町の皆さんには本当に感謝している.