0
点赞
收藏
分享

微信扫一扫

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

程序员知识圈 02-01 14:10 阅读 53

1.apiServer中的webhook

1.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).

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

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

1.2在源码中有哪些webhook

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

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.NamespacedName{Namespace: 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组件

没有上面的方便,但也知晓下这种写法

git@github.com:kubernetes/autoscaler.git


举报

相关推荐

0 条评论