Webhookの生成
Kubernetesには、Admission Webhookと呼ばれる拡張機能があります。 これは特定のリソースを作成・更新する際にWebhook APIを呼び出し、バリデーションやリソースの書き換えをおこなうための機能です。
kubebuilder
コマンドでは、以下の3種類のオプションで生成するWebhookを指定できます。
--programmatic-validation
: リソースのバリデーションをおこなうためのWebhook--defaulting
: リソースのフィールドにデフォルト値を設定するためのWebhook--conversion
: カスタムリソースのバージョンアップ時にリソースの変換をおこなうためのWebhook
ここでは--programmatic-validation
と--defaulting
を指定して、MarkdownViewリソース用のWebhookを生成してみましょう。
注意: kindにはPodやDeploymentなどの既存のリソースを指定できません。
$ kubebuilder create webhook --group view --version v1 --kind MarkdownView --programmatic-validation --defaulting
APIを作成したときと同様に、以下のコマンドを実行してマニフェストファイルを生成しておきます。
$ make manifests
以下のファイルが新たに追加されました。
├── api
│ └── v1
│ ├── markdownview_webhook.go
│ ├── markdownview_webhook_test.go
│ └── webhook_suite_test.go
└── config
├── certmanager
│ ├── certificate.yaml
│ ├── kustomization.yaml
│ └── kustomizeconfig.yaml
├── crd
│ └── patches
│ ├── cainjection_in_markdownviews.yaml
│ └── webhook_in_markdownviews.yaml
├── default
│ ├── manager_webhook_patch.yaml
│ └── webhookcainjection_patch.yaml
└── webhook
├── kustomization.yaml
├── kustomizeconfig.yaml
├── manifests.yaml
└── service.yaml
api/v1
markdownview_webhook.go
がWebhook実装の雛形になります。
このファイルにWebhookの実装を追加していくことになります。
config
certmanager
Admission Webhook機能を利用するためには証明書が必要となります。 cert-managerを利用して証明書を発行するためのカスタムリソースが生成されています。
crd/patches
このディレクトリにはConversion Webhook用のパッチファイルが格納されています。CRDのバージョンアップをおこなう際に利用します。
cainjection_in_markdownviews.yaml
は、cert-managerのCA Injection機能を有効にするためのパッチファイルです。
また、webhook_in_markdownviews.yaml
は、Conversion Webhookを有効にするためのパッチファイルです。
webhook
config/webhook
下は、Admission Webhook機能を利用するために必要なマニフェストファイルです。
webhookcainjectoin_patch.yaml
は、cert-managerのCA Injection機能を有効にするためのパッチファイルです。
また、manager_webhook_patch.yaml
は、Admission Webhook用の証明書をカスタムコントローラーから参照できるようにするためのパッチファイルです。
manifests.yaml
ファイルはmake manifests
コマンドで自動生成されるため、手動で編集する必要はありません。
cmd/main.go
cmd/main.go
には、以下のようなWebhookの初期化をおこなうためのコードが追加されています。
if os.Getenv("ENABLE_WEBHOOKS") != "false" {
if err = (&viewv1.MarkdownView{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "MarkdownView")
os.Exit(1)
}
}
kustomization.yamlの編集
Kubebuilderコマンドで生成した直後の状態では、Webhook機能が利用できるようにはなっていません。
config/default/kustomization.yaml
ファイルを編集する必要があります。
config/default/kustomization.yaml
ファイルを開き、以下のようにresources
の../webhook
と../certmanager
, patchesStrategicMerge
のmanager_webhook_patch.yaml
とwebhookcainjection_patch.yaml
, replacements
のコメントを外して有効化します。
# Adds namespace to all resources.
namespace: markdown-view-system
# Value of this field is prepended to the
# names of all resources, e.g. a deployment named
# "wordpress" becomes "alices-wordpress".
# Note that it should also match with the prefix (text before '-') of the namespace
# field above.
namePrefix: markdown-view-
# Labels to add to all resources and selectors.
#labels:
#- includeSelectors: true
# pairs:
# someName: someValue
resources:
- ../crd
- ../rbac
- ../manager
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
- ../webhook
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
- ../certmanager
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
#- ../prometheus
# [METRICS] Expose the controller manager metrics service.
- metrics_service.yaml
# Uncomment the patches line if you enable Metrics, and/or are using webhooks and cert-manager
patches:
# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443.
# More info: https://book.kubebuilder.io/reference/metrics
- path: manager_metrics_patch.yaml
target:
kind: Deployment
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
- path: manager_webhook_patch.yaml
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
# 'CERTMANAGER' needs to be enabled to use ca injection
- path: webhookcainjection_patch.yaml
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
# Uncomment the following replacements to add the cert-manager CA injection annotations
replacements:
- source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert # this name should match the one in certificate.yaml
fieldPath: .metadata.namespace # namespace of the certificate CR
targets:
- select:
kind: ValidatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 0
create: true
- select:
kind: MutatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 0
create: true
- select:
kind: CustomResourceDefinition
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 0
create: true
- source:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert # this name should match the one in certificate.yaml
fieldPath: .metadata.name
targets:
- select:
kind: ValidatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 1
create: true
- select:
kind: MutatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 1
create: true
- select:
kind: CustomResourceDefinition
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 1
create: true
- source: # Add cert-manager annotation to the webhook Service
kind: Service
version: v1
name: webhook-service
fieldPath: .metadata.name # namespace of the service
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
fieldPaths:
- .spec.dnsNames.0
- .spec.dnsNames.1
options:
delimiter: '.'
index: 0
create: true
- source:
kind: Service
version: v1
name: webhook-service
fieldPath: .metadata.namespace # namespace of the service
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
fieldPaths:
- .spec.dnsNames.0
- .spec.dnsNames.1
options:
delimiter: '.'
index: 1
create: true