当前位置:首页 > 科技  > 软件

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

来源: 责编: 时间:2023-11-28 09:35:43 161观看
导读如果你是一名 Kubernetes Operator 的开发者,你曾经是否面临过这样一个棘手的问题:如何在本地环境中高效地调试 Webhook,尤其是在涉及有效证书回调的情况下。这篇文章旨在提供一种清晰的指南,帮助你克服这一挑战,优化本地

如果你是一名 Kubernetes Operator 的开发者,你曾经是否面临过这样一个棘手的问题:如何在本地环境中高效地调试 Webhook,尤其是在涉及有效证书回调的情况下。这篇文章旨在提供一种清晰的指南,帮助你克服这一挑战,优化本地开发和测试流程。jAt28资讯网——每日最新资讯28at.com

为什么本地调试 Webhook 如此重要?

当我们初步涉足 Kubernetes Webhook 时,面对的首个挑战通常是 Validation Webhook。对于这种验证型 Webhook 来说,我们可以通过编写自动化测试来验证其功能。jAt28资讯网——每日最新资讯28at.com

这不仅确保了我的 Webhook 按预期工作,还允许我在日常开发中临时禁用它,从而加快了整个开发过程。这种方法让我能够巧妙地避免复杂的调试问题,而不对整体功能造成任何影响。jAt28资讯网——每日最新资讯28at.com

if os.Getenv("ENABLE_WEBHOOKS") != "false" {    if err = (&webappv1.Guestbook{}).SetupWebhookWithManager(mgr); err != nil {        setupLog.Error(err, "unable to create webhook", "webhook", "Guestbook")        os.Exit(1)    }}

然而,对于 Mutating Webhook 来说,情况就变得有点复杂了。这类 Webhook 通常负责埋点的行为甚至更深层次的集群操作,比如注入 sidecar,这时候单靠自动化测试显然是不够的。我们需要一个更加高效的本地测试和调试方法。jAt28资讯网——每日最新资讯28at.com

在我们团队中,有同事采用 Kind 来部署和测试服务,这种方法非常值得称赞。它完全符合 K8s 的操作模式,为我们提供了一个接近生产环境的本地测试平台。但是,大家可能也注意到了,这种方式存在一个效率瓶颈:每次进行代码更改后,都需要重新构建 Docker 镜像并部署到集群中,这一过程既耗时又影响开发流程的连贯性。jAt28资讯网——每日最新资讯28at.com

作为开发工程师,我们渴望的是一个极速的内部开发循环,一个不再需要频繁的 docker build、docker push 或繁琐的部署流程,即使这些已经完全自动化。jAt28资讯网——每日最新资讯28at.com

我们希望能够使用本地熟悉的开发工具,如 VS Code 或者 IntelliJ IDEA 进行本地调试,而不是先部署到集群环境,再通过日志来分析错误这种远程调试模式。jAt28资讯网——每日最新资讯28at.com

从 Service 到 URL 的魔法变换

在不禁用 Webhook 的情况下,我们在本地启动 controller 后会有如下错误。这个比较好处理,我们只要使用自签证书,注入到 WebhookServer 即可,在前面的文章中我介绍过很多次,这里不再赘述。jAt28资讯网——每日最新资讯28at.com

2023-11-26T12:55:17+08:00       INFO    Stopping and waiting for webhooks...2023-11-26T12:55:17+08:00       INFO    Wait completed, proceeding to shutdown the manager2023-11-26T12:55:17+08:00       ERROR   setup   problem running manager {"error": "open /var/folders/hn/v2s5bx...00000gn/T/k8s-webhook-server/serving-certs/tls.crt: no such file or directory"}...

我们来运行一个示例,想必下面这个错误大家都非常熟悉吧,这个是因为 Webhook 注册的地址'不对',它是集群内的地址。jAt28资讯网——每日最新资讯28at.com

➜ kubectl apply -f ./config/samplesError from server (InternalError): error when creating "config/samples/webapp_v1_guestbook.yaml": Internal error occurred: failed calling webhook "vguestbook.kb.io": failed to call webhook: Post "https://testing-webhooks-webhook-service.testing-webhooks-system.svc:443/validate-webapp-foobar-ai-v1-guestbook?timeout=10s": no endpoints available for service "testing-webhooks-webhook-service"

我们再来看下 ValidatingWebhookConfiguration 的配置。jAt28资讯网——每日最新资讯28at.com

apiVersion: admissionregistration.k8s.io/v1kind: ValidatingWebhookConfigurationmetadata:  name: testing-webhooks-validating-webhook-configurationwebhooks:- admissionReviewVersions:  - v1  clientConfig:    service:      name: testing-webhooks-webhook-service      namespace: testing-webhooks-system      path: /validate-webapp-foobar-ai-v1-guestbook      port: 443  failurePolicy: Fail  matchPolicy: Equivalent  name: vguestbook.kb.io  rules:  - ...  ...

在这个配置中,webhooks 字段定义了一个或多个要注册的 Webhook。每个 Webhook 通过 clientConfig 配置与 Kubernetes API 服务器的连接方式。jAt28资讯网——每日最新资讯28at.com

正如大家所看到的 https://testing-webhooks-webhook-service.testing-webhooks-system.svc:443/validate-webapp-foobar-ai-v1-guestbook,这个默认地址其实就是 K8s 集群内部的地址。这恰是 K8s 中处理 Webhook 的常规方法,其中 service 字段指向集群内运行的特定服务。jAt28资讯网——每日最新资讯28at.com

然而,在本地开发环境中,我们只在本地运行了我们的 Operator,直接使用内部服务是不大可能的,因为它要求 Webhook 服务必须部署在 K8s 集群中。jAt28资讯网——每日最新资讯28at.com

使用 kubectl explain 探索 Webhook 配置

当我们在 K8s 中配置 Webhook 时,了解其配置细节是非常重要的。kubectl explain 是一个非常实用的小工具,它可以帮助我们深入理解 K8s 资源的各个属性。jAt28资讯网——每日最新资讯28at.com

以 ValidatingWebhookConfiguration.webhooks.clientConfig 为例:jAt28资讯网——每日最新资讯28at.com

➜ 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 the     webhook's server certificate. If unspecified, system trust roots on the     apiserver 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 be     specified.

通过以上提供的详细信息,不难发现 clientConfig 它除了通过定义 Service 让 API 服务器连接到 WebhookServer 外,还有另外一种方式,那就是直接通过 URL 连接。jAt28资讯网——每日最新资讯28at.com

为了解决这个问题,我们可以将 Webhook 的配置从服务转变为直接使用 URL。jAt28资讯网——每日最新资讯28at.com

使用 URL 连接 Webhook

通过将 clientConfig 中的 service 字段替换为 url 字段,我们可以指定 Webhook 服务的外部 URL。这样一来,开发者可以在本地运行 Webhook 服务,并通过公开的 URL 使其可被 Kubernetes API 服务器访问。jAt28资讯网——每日最新资讯28at.com

例如:jAt28资讯网——每日最新资讯28at.com

webhooks:- admissionReviewVersions:  - v1  clientConfig:    url: https://testing-webhooks.loca.lt/validate-webapp-foobar-ai-v1-guestbook

这种方法使得在本地开发环境中调试 Webhook 变得更加灵活和便捷。开发者可以使用本地服务器或通过隧道(如 ngrok[1] 或 localtunnel[2])暴露的服务,从而实现在本地环境中的有效调试。jAt28资讯网——每日最新资讯28at.com

事实上,我最初的首选是 ngrok,因为这玩意确实好用,它还有个 localhost:4040 非常的实用,但遗憾的是,它的 tls 能力是付费的。幸好,有很多平替工具可以选择,比如 localtunnel,用起来也非常的方便。jAt28资讯网——每日最新资讯28at.com

步骤 1: 在我们的 main.go 需要接收一个证书路径jAt28资讯网——每日最新资讯28at.com

...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,并启动我们的程序jAt28资讯网——每日最新资讯28at.com

修改 Makefile 文件,让其可以接收证书目录:jAt28资讯网——每日最新资讯28at.com

.PHONY: runrun: manifests generate fmt vet ## Run a controller from your host.  go run ./cmd/main.go --webhook-cert-dir ./config/certs

启动程序:jAt28资讯网——每日最新资讯28at.com

➜ make run...go run ./cmd/main.go --webhook-cert-dir ./config/certs2023-11-26T11:18:42+08:00       INFO    controller-runtime.builder      Registering a mutating webhook  {"GVK": "webapp.foobar.ai/v1, Kind=Guestbook", "path": "/mutate-webapp-foobar-ai-v1-guestbook"}2023-11-26T11:18:42+08:00       INFO    controller-runtime.webhook      Registering webhook     {"path": "/mutate-webapp-foobar-ai-v1-guestbook"}2023-11-26T11:18:42+08:00       INFO    controller-runtime.builder      Registering a validating webhook        {"GVK": "webapp.foobar.ai/v1, Kind=Guestbook", "path": "/validate-webapp-foobar-ai-v1-guestbook"}2023-11-26T11:18:42+08:00       INFO    controller-runtime.webhook      Registering webhook     {"path": "/validate-webapp-foobar-ai-v1-guestbook"}...2023-11-26T11:18:42+08:00       INFO    controller-runtime.webhook      Starting webhook server...2023-11-26T11:18:42+08:00       INFO    controller-runtime.webhook      Serving webhook server  {"host": "", "port": 9443}...

步骤 3:将本地主机服务器通过隧道公开jAt28资讯网——每日最新资讯28at.com

# 安装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 配置jAt28资讯网——每日最新资讯28at.com

我们将默认的 service 服务。jAt28资讯网——每日最新资讯28at.com

webhooks:- admissionReviewVersions:  - v1  clientConfig:    service:      name: testing-webhooks-webhook-service      namespace: testing-webhooks-system      path: /validate-webapp-foobar-ai-v1-guestbook      port: 443...

替换换成 url 直连模式jAt28资讯网——每日最新资讯28at.com

webhooks:- admissionReviewVersions:  - v1  clientConfig:    url: https://testing-webhooks.loca.lt/validate-webapp-foobar-ai-v1-guestbook...

以上仅以 ValidatingWebhookConfiguration 为例,如果你的 controller 同时使用了 MutatingWebhookConfiguration,别忘了,处理方式是一样的。jAt28资讯网——每日最新资讯28at.com

步骤 5:看看实际效果如何jAt28资讯网——每日最新资讯28at.com

最后,我们再执行同样一个用例,就可以被当前的 ValidatingWebhook 拦截到了。jAt28资讯网——每日最新资讯28at.com

➜ kubectl apply -f ./config/samples/webapp_v1_guestbook.yamlThe Guestbook "guestbook-sample" is invalid: metadata.name: Invalid value: "guestbook-sample": Guestbook name must be no more than 5 characters for test purposes

本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-34633-0.html云原生小技巧 : 如何在本地调试 Kubernetes Webhook?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 四种消息队列,如何选型?

下一篇: 深入探索Python中的Contextlib模块

标签:
  • 热门焦点
Top
Baidu
map