k8s-apiServer 准入控制插件(webhook)

君不见长松卧壑困风霜,时来屹立扶明堂。这篇文章主要讲述k8s-apiServer 准入控制插件(webhook)相关的知识,希望能为你提供帮助。
1.apiServer中的webhook1.1查看默认启用了哪些webhook

root@ubuntu-focal:~# kubectl exec -it kube-apiserver-ubuntu-focal -n kube-system -- kube-apiserver --help

--enable-admission-plugins strings
admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount,
TaintNodesByCondition, PodSecurity, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection,
PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction,
DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota).



1.2在源码中有哪些webhook

1.3webhook案例
1.openkruise好处:
不需要自己生成证书,代码中已经自动生成了证书,使用起来很方便,我在工作中就参考的这个。
仓库地址:
git@github.com:openkruise/kruise.git
重要逻辑介绍:
//证书相关内容每分钟同步一次
func (c *Controller) sync() error
utils.Log.Info("Starting to sync webhook certs and configurations")
defer func()
utils.Log.Info("Finished to sync webhook certs and configurations")
()

var dnsName string
var certWriter writer.CertWriter
var err error
// 获取ip或域名
// 没有 WEBHOOK_HOST 环境变量,就设置dnsName=serviceName.serviceNamespace.svc
if dnsName = webhookutil.GetHost(); len(dnsName) == 0
dnsName = generator.ServiceToCommonName(commonutil.GetNamespace(), webhookutil.GetServiceName())


//默认什么都不做,会创建secret
certWriterType := webhookutil.GetCertWriter()
if certWriterType == writer.FsCertWriter || (len(certWriterType) == 0 & & len(webhookutil.GetHost()) != 0)
certWriter, err = writer.NewFSCertWriter(writer.FSCertWriterOptions
Path: webhookutil.GetCertDir(),
)
else
certWriter, err = writer.NewSecretCertWriter(writer.SecretCertWriterOptions
Client: c.runtimeClient,
Secret: & types.NamespacedNameNamespace: commonutil.GetNamespace(), Name: webhookutil.GetSecretName(),
)

if err != nil
return fmt.Errorf("failed to ensure certs: %v", err)

// 自签名证书,并且吧证书内容存储在secret或磁盘中--自动创建secret或文件
certs, _, err := certWriter.EnsureCert(dnsName)
if err != nil
return fmt.Errorf("failed to ensure certs: %v", err)

//证书内容写入/tmp/ops-webhook-certs
if err := writer.WriteCertsToDir(webhookutil.GetCertDir(), certs); err != nil
return fmt.Errorf("failed to write certs to dir: %v", err)

// 根据上面自签名证书内容,更新证书CACert填入到 ValidatingWebhookConfiguration和 MutatingWebhookConfiguration 的CaBundle中
// 校验path是否正确
// 如果配置了WEBHOOK_HOST也配置了service,那就不使用service了
if err := configuration.Ensure(c.runtimeClient, c.handlers, certs.CACert); err != nil
return fmt.Errorf("failed to ensure configuration: %v", err)

//conversion问题
// 多版本的时候可能用到,没有多版本就不需要
// 在apps.kruise.io crd--CustomResourceDefinition资源中设置.Spec.Conversion.WebhookClientConfig,关于convert相关信息
if err := crd.Ensure(c.crdClient, c.crdLister, certs.CACert); err != nil
return fmt.Errorf("failed to ensure crd: %v", err)


//关闭uninit通道,如果程序没有走到这里,会触发Initialize中的case < -timer.C,webhook初始化超时,程序退出
onceInit.Do(func()
close(uninit)
)
return nil

2.vpa中的admission-controller组件没有上面的方便,但也知晓下这种写法
【k8s-apiServer 准入控制插件(webhook)】git@github.com:kubernetes/autoscaler.git



    推荐阅读