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

Posted DevOperaterVita

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s-apiServer 准入控制插件(webhook)相关的知识,希望对你有一定的参考价值。

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

k8s-apiServer

1.2在源码中有哪些webhook

k8s-apiServer

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组件

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

git@github.com:kubernetes/autoscaler.git


以上是关于k8s-apiServer 准入控制插件(webhook)的主要内容,如果未能解决你的问题,请参考以下文章

认证授权与准入控制

Kubernetes入门至精通 | Kubernetes集群安全 - 准入控制

kubernetes API 访问控制之:准入控制

k8s-apiServer认证

十六 RBAC

k8s-apiServer鉴权