Kubernetes Webhook
介绍
使用k8s生成资源的时候,会选择是否要添加webhook到你的 API。你可以选择 "Yes" 并按照提示进行操作。
在生成的 config/webhook
目录下,你可以找到用于 Webhook 的配置文件。编辑 MutatingWebhookConfiguration
或 ValidatingWebhookConfiguration
文件来指定你的 Webhook 应该拦截哪些资源。
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: mutating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /mutate-networking-k8s-io-v1-ingress
failurePolicy: Ignore
name: mingress.sealos.io
namespaceSelector:
matchExpressions:
- key: user.sealos.io/owner
operator: Exists
rules:
- apiGroups:
- networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- ingresses
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /mutate--v1-namespace
failurePolicy: Ignore
name: mnamespace.sealos.io
namespaceSelector:
matchExpressions:
- key: user.sealos.io/owner
operator: Exists
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- namespaces
sideEffects: None
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /validate-networking-k8s-io-v1-ingress
failurePolicy: Ignore
name: vingress.sealos.io
namespaceSelector:
matchExpressions:
- key: user.sealos.io/owner
operator: Exists
rules:
- apiGroups:
- networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
- DELETE
resources:
- ingresses
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /validate--v1-namespace
failurePolicy: Ignore
name: vnamespace.sealos.io
namespaceSelector:
matchExpressions:
- key: user.sealos.io/owner
operator: Exists
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
在你的 Go 代码中,需要注册 Webhook。这通常是在 setupwebhookwithmanager.go
文件中完成的,例如:
复制
func (r *MyResource) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
}
在生成的webhook文件中,主要需要以下方法并提供实现:
在 Kubernetes 中定义一个 Admission Webhook 通常涉及实现特定的接口方法,这些方法属于 admission.Handler
接口,由 kubebuilder
提供的框架抽象。对于 Mutating Webhook 和 Validating Webhook,核心方法如下:
Mutating Webhook
Default 方法:这个方法用于设置请求资源的默认值。例如,可以在这个方法中为资源添加或修改注解、标签或其他字段。
func (m *YourMutatingHandler) Default(ctx context.Context, obj runtime.Object) error { // 实现默认值设置逻辑 }
Validating Webhook
ValidateCreate 方法:这个方法在创建资源之前被调用,用于验证新资源是否符合要求。
func (v *YourValidatingHandler) ValidateCreate(ctx context.Context, obj runtime.Object) error { // 实现创建时的验证逻辑 }
ValidateUpdate 方法:这个方法在更新资源之前被调用,用于验证新旧资源之间的差异是否符合要求。
func (v *YourValidatingHandler) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) error { // 实现更新时的验证逻辑 }
ValidateDelete 方法(可选):这个方法在删除资源之前被调用,用于执行删除前的验证逻辑。
func (v *YourValidatingHandler) ValidateDelete(ctx context.Context, obj runtime.Object) error { // 实现删除时的验证逻辑 }
其他通用方法
InjectDecoder 方法:这个方法用于注入一个解码器,它能够将 AdmissionReview 请求解码成具体的资源对象。
func (h *YourHandler) InjectDecoder(d *admission.Decoder) error { h.decoder = d return nil }
Handle 方法:这是 Webhook 的核心处理方法,它接收 AdmissionReview 请求并返回 AdmissionResponse。
func (h *YourHandler) Handle(ctx context.Context, req admission.Request, resp *admission.Response) { // 实现 Webhook 处理逻辑 }
应用场景举例
发版的权限验证:拦截各种操作
既然用户唯一能使用他人镜像的地方就是系统内的发版,那么可以使用admission webhook进行限制。
工作流程:
1.当用户在前端选择发版/创建应用程序的时候,识别下镜像地址,如果发现
是我们的私有地址,那么修改yml文件,为其打上一个标签
2.配置部署admission webhook,拦截特定标签的pod create请求,拦截逻辑可以自定义:
判断试图创建pod的ns和仓库中的ns是否相同,如果相同即允许,不相同则拒绝。
获取rbac信息,对比后做判断。
还有一种情况是,假设后面可以在镜像仓库层面上做限制,仍然会有问题,比如用户a尝试创建一个用户b的镜像,被调度到节点1上进行,结果节点1上已经有了b的镜像,此时不会走镜像仓库,仍然会有问题,需要webhook进行限制。
理论上分析应该是可以的,因为镜像仓库的认证是拉取过程的认证,这种情况相当于已经把镜像从仓库中拉取到节点本地了,这时候就没有任何认证相关的问题了。不过还没有做实验。
绕开crd,访问controller
当需要crd不变更而访问controller时,可以考虑使用controller的webhook.