一、前言

很多地方都有 webhook 的概念,就是在需要的地方预留些钩子作为事件的回调通知。不管是 k8s 自带的资源、还是我们声明的 CRD 资源都可以定义对应的 webhook。

kubebuilder 的概念架构

二、k8s webhook

k8s 的 webhook 主要有 2 种:mutating-webhook、validating-webhook,前者可以在资源的创建、更新时候修改 yaml 定义的内容(比如设置一些默认值),后者可以对资源进行一些校验。

2.1 创建

kubebuilder create webhook --group webapp --version v1 --kind Guestbook --defaulting --programmatic-validation

上面的命令同时创建 2 种 webhook

  1. 会将你声明的 webhook 注册到 manager 里面,在 main.go 里面
  2. api/v1/guestbook_webhook.go 里面生成回调的相对应入口,你要你在里面填充相关的代码逻辑。
  3. config 里面也会生成 webhook 需要部署声明的一些 yaml(默认生成的 yaml 需要自己调整部分内容)
    a. default/kustomization.yaml 里面将 ../webhook ../certmanager 注释去除
    b. certmanager 证书声明的内容要调整
    c. webhook manifests.yaml 回调地址如果是部署在集群外的需要调整

2.2 证书认证

根据 K8S文档描述, Kubernetes API Server 通过 HTTPS POST 访问 Webhook Server, 也就是说 Webhook Server 必须要监听在HTTPS协议上。
这边使用 cert-manager 来提供 https 所需要的证书。

证书声明

修改 config/certmanager/certificate.yaml,当前实验服务是部署在本地,所以证书里面添加了本机的 ip 地址。正常是要填写服务端(webhook-server)的域名

# The following manifests contain a self-signed issuer CR and a certificate CR.
# More document can be found at https://docs.cert-manager.io
# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes.
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: selfsigned-issuer
  namespace: system
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: serving-cert  # this name should match the one appeared in kustomizeconfig.yaml
  namespace: system
spec:
  # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
  commonName: 10.130.161.13
  dnsNames:
  #- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
  #- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
  - 10.130.161.13
  ipAddresses:
  - 10.130.161.13
  issuerRef:
    kind: Issuer
    name: selfsigned-issuer
  secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize

2.3 调试

通过webhook 修改资源的参数值

路径:api/v1/guestbook_webhook.go

func (r *Guestbook) Default() {
 guestbooklog.Info("default", "name", r.Name)

 // 如果参数 == hello a ,就改成 hello b
 if r.Spec.Foo == "hello a" {
  r.Spec.Foo = "hello b"
 }
}

测试

  1. 通过 kubectl 修改 guestbook 的 spec.foo 值
    image.png
  2. 本地服务断点调试,有触发
    image.png
  3. 查看值被我们改成 b
    image.png

点赞(3) 打赏

Comment list 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部