「新しいビジネス様式 byGMO」と謳って在宅勤務を継続しながら出社勤務を再開したのですがあまりにも出社から遠のいた結果、何時に家を出れば何時に会社に到着するのか分からなくなった結果、めちゃくちゃ早く会社についたのでブログを書こうかと思う
はじめに
Kubewebhook とは、Kubernetesのexternal admission webhooks を作成するための小さなGoフレームワークです。
Kubewebhookを使用すると、Webhookの検証と変更を非常に高速に行うことができ、主にWebhook自体のドメインロジックに焦点を当てることができます。
特徴としては下記があります
- Ready for mutating and validating webhook kinds (compatible with CRDs).
- Easy and testable API.
- Simple, extensible and flexible.
- Multiple webhooks on the same server.
- Webhook metrics (RED) for Prometheus with Grafana dashboard included.
- Webhook tracing with Opentracing.
- Type specific (static) webhooks and multitype (dynamic) webhooks.
github のissues にも記載ありますが数ヶ月間本番環境で使用されているらしく 弊社() でも本番利用しております。本番運用で以下に運用していくかはk8s-webhook-example などをみていくつかのシステムに適合していくつかのエラー処理さえ追加すればよいのではないかなーって思います。
環境構築
cluster の構築
kind create cluster --name kubewebhook 2250ms Creating cluster "kubewebhook" ... ✓ Ensuring node image (kindest/node:v1.18.2) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-kubewebhook" You can now use your cluster with: kubectl cluster-info --context kind-kubewebhook Have a nice day!
cluster の確認
$ kind get clusters kubewebhook # コンフィグの生成 $ kind get kubeconfig --name kubewebhook apiVersion: v1 clusters: - cluster: certificate-authority-data: LS*****************************LS0tLQo= server: https://127.0.0.1:35765 name: kind-kubewebhook contexts: - context: cluster: kind-kubewebhook user: kind-kubewebhook name: kind-kubewebhook current-context: kind-kubewebhook kind: Config preferences: {} users: - name: kind-kubewebhook user: client-certificate-data: LS0tLS1*************************************************************************S0tLQo= client-key-data: LS0tLS1CRUd******************************************0tCg== $ kind get kubeconfig --name kubewebhook > kubeconfig.yaml $ kubectl version --kubeconfig=kubeconfig.yaml Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.2", GitCommit:"52c56ce7a8272c798dbc29846288d7cd9fbae032", GitTreeState:"clean", BuildDate:"2020-04-30T20:19:45Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
証明書発行
自己証明書、つまりオレオレ証明書を作って利用します。subj を設定しないとちゃんと設定しないと上手く動作しませんのでご注意ください。
$ openssl genrsa -out webhookCA.key 2048 $ openssl req -new -key ./webhookCA.key -subj "/CN=pod-annotate-webhook.default.svc" -out ./webhookCA.csr $ openssl x509 -req -days 365 -in webhookCA.csr -signkey webhookCA.key -out webhook.crt $ kubectl create secret generic \ pod-annotate-webhook-certs \ --from-file=key.pem=./webhookCA.key \ --from-file=cert.pem=./webhook.crt \ --dry-run -o yaml > ./deploy/webhook-certs.yaml
証明書をデプロイ
先程、生成したシークレットをデプロイします。
$ kubectl apply -f ./deploy/webhook-certs.yaml
Webhookをデプロイします
Docker のビルドとKind での読み込みをやってからWebhook を受け取る処理と設定の変更を行ってくれるサーバーをデプロイします。 main.go の中で下記のような感じでPod に追加したいラベルや情報を付与していきます。
if pod.Labels == nil { pod.Labels = make(map[string]string) } pod.Labels["webhook"] = "true"
$ docker build . -t kubewebhook $ kind load docker-image kubewebhook:latest --name kubewebhook $ kubectl apply -f ./deploy/webhook.yaml
Webhookを登録します
詳しくはDynamic Admission Control などをご覧ください。
$ kubectl apply -f ./deploy/webhook-registration.yaml
テストについて
このような よくあるyaml をデプロイします
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-test spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx
デプロイしたら "mutated": "true"
および"mutator": "pod-annotate"
がデプロイされているのが分かります。
$ kubectl apply -f ./deploy/test-deployment.yaml $ kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-test-f89759699-2f4pv 1/1 Running 0 3m51s app=nginx,pod-template-hash=f89759699,webhook=true nginx-test-f89759699-hkxs9 1/1 Running 0 3m51s app=nginx,pod-template-hash=f89759699,webhook=true nginx-test-f89759699-mj9bg 1/1 Running 0 3m51s app=nginx,pod-template-hash=f89759699,webhook=true pod-annotate-webhook-64fcdc7758-lgbtd 1/1 Running 0 5m5s app=pod-annotate-webhook,pod-template-hash=64fcdc7758 $ kubectl get pods/nginx-test-f89759699-mj9bg -o json | jq '.metadata.annotations' { "mutated": "true", "mutator": "pod-annotate" }
検証自体はかなり前にやっていたのですがそのログをかき集めた形になるので多少雑になったのですが時間があれば普通に解説のブログ書きます。終わり。