云原生小技巧 : 如何在本地调试 Kubernetes Webhook?( 二 )


以 ValidatingWebhookConfiguration.webhooks.clientConfig 为例:
kubectl explain ValidatingWebhookConfiguration.webhooks.clientConfigGROUP:admissionregistration.k8s.ioKIND:ValidatingWebhookConfigurationVERSION:v1FIELD: clientConfig <WebhookClientConfig>:DESCRIPTION:FIELDS:caBundle<string>`caBundle` is a PEM encoded CA bundle which will be used to validate thewebhook's server certificate. If unspecified, system tRust roots on theapiserver are used.service<ServiceReference>`service` is a reference to the service for this webhook. Either `service`or `url` must be specified.If the webhook is running within the cluster, then you should use `service`.url<string>`url` gives the location of the webhook, in standard URL form(`scheme://host:port/path`). Exactly one of `url` or `service` must bespecified.通过以上提供的详细信息,不难发现 clientConfig 它除了通过定义 Service 让 API 服务器连接到 WebhookServer 外,还有另外一种方式,那就是直接通过 URL 连接 。
为了解决这个问题,我们可以将 Webhook 的配置从服务转变为直接使用 URL 。
使用 URL 连接 Webhook通过将 clientConfig 中的 service 字段替换为 url 字段 , 我们可以指定 Webhook 服务的外部 URL 。这样一来,开发者可以在本地运行 Webhook 服务 , 并通过公开的 URL 使其可被 Kubernetes API 服务器访问 。
例如:
webhooks:- admissionReviewVersions:- v1clientConfig:url: https://testing-webhooks.loca.lt/validate-webapp-foobar-ai-v1-guestbook这种方法使得在本地开发环境中调试 Webhook 变得更加灵活和便捷 。开发者可以使用本地服务器或通过隧道(如 ngrok[1] 或 localtunnel[2])暴露的服务,从而实现在本地环境中的有效调试 。
事实上,我最初的首选是 ngrok,因为这玩意确实好用,它还有个 localhost:4040 非常的实用 , 但遗憾的是,它的 tls 能力是付费的 。幸好,有很多平替工具可以选择,比如 localtunnel,用起来也非常的方便 。
步骤 1: 在我们的 main.go 需要接收一个证书路径
...var certDir stringflag.StringVar(&certDir, "webhook-cert-dir", "/tmp/k8s-webhook-server/serving-certs", "Admission webhook cert/key dir.")...mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{Scheme:scheme,Metrics:metricsserver.Options{BindAddress: metricsAddr},HealthProbeBindAddress: probeAddr,WebhookServer: webhook.NewServer(webhook.Options{CertDir: certDir,Port:9443,}),LeaderElection:enableLeaderElection,LeaderElectionID: "dcc993a0.foobar.ai",})...步骤 2:调整 Makefile,并启动我们的程序
修改 Makefile 文件 , 让其可以接收证书目录:
.PHONY: runrun: manifests generate fmt vet ## Run a controller from your host.go run ./cmd/main.go --webhook-cert-dir ./config/certs启动程序:
make run...go run ./cmd/main.go --webhook-cert-dir ./config/certs2023-11-26T11:18:42+08:00INFOcontroller-runtime.builderRegistering a mutating webhook{"GVK": "webapp.foobar.ai/v1, Kind=Guestbook", "path": "/mutate-webapp-foobar-ai-v1-guestbook"}2023-11-26T11:18:42+08:00INFOcontroller-runtime.webhookRegistering webhook{"path": "/mutate-webapp-foobar-ai-v1-guestbook"}2023-11-26T11:18:42+08:00INFOcontroller-runtime.builderRegistering a validating webhook{"GVK": "webapp.foobar.ai/v1, Kind=Guestbook", "path": "/validate-webapp-foobar-ai-v1-guestbook"}2023-11-26T11:18:42+08:00INFOcontroller-runtime.webhookRegistering webhook{"path": "/validate-webapp-foobar-ai-v1-guestbook"}...2023-11-26T11:18:42+08:00INFOcontroller-runtime.webhookStarting webhook server...2023-11-26T11:18:42+08:00INFOcontroller-runtime.webhookServing webhook server{"host": "", "port": 9443}...步骤 3:将本地主机服务器通过隧道公开
# 安装npm install -g localtunnel# 使用 lt 命令启动隧道lt --port 9443--local-https--local-ca $(pwd)/certs/ca.crt--local-cert $(pwd)/certs/tls.crt--local-key $(pwd)/certs/tls.key--subdomain testing-webhooksyour url is: https://testing-webhooks.loca.lt步骤 4:修改 ValidatingWebhookConfiguration 配置
我们将默认的 service 服务 。
webhooks:- admissionReviewVersions:- v1clientConfig:service:name: testing-webhooks-webhook-servicenamespace: testing-webhooks-systempath: /validate-webapp-foobar-ai-v1-guestbookport: 443...替换换成 url 直连模式
webhooks:- admissionReviewVersions:- v1clientConfig:url: https://testing-webhooks.loca.lt/validate-webapp-foobar-ai-v1-guestbook...

以上仅以 ValidatingWebhookConfiguration 为例,如果你的 controller 同时使用了 MutatingWebhookConfiguration , 别忘了,处理方式是一样的 。


推荐阅读