LoginSignup
3
1

More than 5 years have passed since last update.

あわてんぼうのサンタクロースPodをクリスマス前にデプロイさせないようにする

Last updated at Posted at 2018-12-16

はじめに

あわてんぼうのサンタクロース
クリスマスまえにやってきた

吉岡治作詞、小林亜星作曲「あわてんぼうのサンタクロース」より

曲中のサンタクロースは「しかたがないから踊ったよ」とあるように、その場をコミュ力で乗り切りインシデントを回避しましたが、普通は障害扱いで大目玉をくらうような事態です。

リリースの手続きを踏んだとしてもチェックミスなどによる障害は往々にして起きるものなので、システム側であわてんぼうのサンタクロースがデプロイされないように対策をとってみましょう。

How to implement

どうやって実現する?

KubernetesのAPI Serverへのリクエストを検証する仕組みの一つである「Admission Controllers」を利用して上記の要件を実現できそうです。しかし、Admission Controllerはkube-apiserverに組み込む必要があり、apiserverの起動時にのみ指定が可能です。

それでは少々不便なため、Kubernetesでは「Admission webhook」という動的に追加する機能が提供されています。
今回はAdmission webhookを利用して実装してみます。

実際に作ってみる

ValidatingWebhookConfiguration

Podが作成されるタイミングでチェックをしかけるValidatingWebhookConfigurationを書きます。
ValidatingWebhookConfigurationは、その名の通りリクエストを通していいかどうかのチェックのための設定です。
(MutatingWebhookConfigurationというのもありますが、今回は割愛)

clientConfigには、クリスマスかどうかを検証するサーバのURLを記載しておきます。

証明書関連の情報は適宜入れておいてください。

ValidatingWebhookConfiguration.yml
piVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  name: check-hasty-santa-clause
webhooks:
  - name: check.hasty.santa.clause
    rules:
      - apiGroups:
          - ""
        apiVersions:
          - "v1"
        operations:
          - "CREATE"
        resources:
          - "pods"
    failurePolicy: Fail
    clientConfig:
      url: <クリスマスかどうかを検証するサーバ>
      caBundle: <証明書関連の情報>

クリスマスかどうかを検証するサーバ

適当にGoで書きました。
今年の12月24日21時から12月25日3時までの間だけ受け付けるようにしています。

こちらも証明書関連の情報は適宜入れておいてください。

main.go
package main

import (
    "fmt"
    "log"
    "net/http"
    "encoding/json"
    "time"
)

type ValidateResponse struct {
    Response struct {
        Allowed bool `json:"allowed"`
        Status  struct {
            Status  string `json:"status"`
            Message string `json:"message"`
            Reason  string `json:"reason"`
            Code    int    `json:"code"`
        } `json:"status"`
    } `json:"response"`
}

func validate(w http.ResponseWriter, r *http.Request) {
    format := "2006-01-02 15:04:05"
    start, _ := time.Parse(format, "2018-12-24 21:00:00")
    end, _ := time.Parse(format, "2018-12-25 03:00:00")

    nowUTC := time.Now().UTC()
    jst := time.FixedZone("Asia/Tokyo", 9*60*60)
    nowJST := nowUTC.In(jst)

    w.Header().Set("Content-Type", "application/json")

    vr := ValidateResponse{}
    if nowJST.After(start) && nowJST.Before(end) {
        fmt.Println("Merry Xmas!")
        vr.Response.Allowed = true
    } else {
        fmt.Println("Not Xmas!")
        vr.Response.Allowed = false
        vr.Response.Status.Status = "Failure"
        vr.Response.Status.Message = "It is still before Christmas. Please wait a little more."
        vr.Response.Status.Reason = ""
        vr.Response.Status.Code = 402
    }

    res, _ := json.Marshal(vr)
    w.Write(res)
}

func main() {
    http.HandleFunc("/", validate)

    err := http.ListenAndServeTLS(
        ":8080",
        "<CERT>",
        "<KEY>", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

検証してみよう

環境

  • Minikube v0.28.0
  • Kubernetes v1.11.0

クリスマスチェック機能のデプロイ

ValidatingWebhookConfigurationの適用

kubectl apply -f ValidatingWebhookConfiguration.yml

クリスマスかどうかを検証するサーバ

go run main.go

サンタクロースPodのデプロイ

チェックがされるかデプロイしてみます。
(サンタさんの代わりにNginxさんで代用)

$ kubectl run --image=nginx --restart=Never santa
Error from server: admission webhook "check.hasty.santa.clause" denied the request: It is still before Christmas. Please wait a little more.
# 検証サーバ側の標準出力
Not Xmas!

12月16日に実行したため、チェックがはたらきデプロイはされませんでした。
検証サーバからのメッセージもきちんと表示されています。やったね。

まとめと所感

今回の題材はおふざけでしたが、例えばIstioのSidecar InjectionもAdmission Webhook(MutatingWebhookConfiguration)を利用して実装されています。これを読んでいるあなたも気づかないところでお世話になっているかもしれません。

Kubernetesには上記で述べたAdmission WebhookやCRD+CustomControllerなどの多数の拡張機能が用意されています。
K8sをより深く理解するためにも拡張機能の作り方は知ってると良いかもしれません。

TODO

  • Githubにソースを置く
  • 参考リンクをはっておく
  • 12月24日にデプロイされるか確認(念のため)
3
1
0

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
1