用Java编写Kubernetes的Sidecar注入器

这是什么?

我用Java编写了一个简易的sidecar-injector,使用了Kubernetes的MutatingWebhook功能,在这个过程中我查找了相关信息并解释了所编写的代码。

这里是我创建的代码:github.com/10hin/sidecar-injector。

为什么选择Java?

在Kubernetes/容器领域,虽然使用Go语言的比例相当高,但是本次我个人偏好选择了Java。根据我的调查得知,至少编写MutatingWebhook时,只需能够进行JSON和HTTP之间的交互,将JSON作为HTTP请求的正文即可,因此,即使在最坏的情况下,只需使用相应的库来编辑原始JSON即可。

pom.xml 可以用中文翻译为“项目对象模型”。

项目是在start.spring.io上创建的,没有特别纠结。我想“如果不行就放弃”,所以我加上了native-image支持。我认为只需要添加插件,但在这里提前加上会更方便。我添加了Spring Web Reactive作为依赖库。

暫時先不需要訪問Kubernetes(因為這是一個Webhook),但我已經安裝了io.kubernetes:client-java。

また、いろいろ調べてから io.kubernetes:client-java-admission-reviewが存在することに気づいた。とてもありがたい。

如果没有使用API对象的Java SDK,您可以参考client-java存储库中的指南,用于从CRD生成Java源代码。

我认为io.kubernetes:client-java-api被包含为依赖项,但我觉得可能是从client-java推演出的依赖项,所以这个是不必要的。但是,我还没有进行验证。

注射器控制器.java

まともなコードはここだけである。

基本上就是非常普通的Spring Webflux代码。

controllerメソッドの引数/戻り値に一苦労した。結論からいうと、CRDから必要なオブジェクトを生成して引数・戻り値に指定するだけであり、今回は admission.k8s.io/v1/AdmissionReview が使えればよいので、pom.xmlのところでも言及した io.kubernetes:client-java-admission-review に含まれる io.kubernetes.client.admissionreview.models.AdmissionReview を引数と戻り値に使えばよい。

ただそれにたどり着くまでは紆余曲折があった。(ここからこの節の最後まではただの苦労話なので読み飛ばしてよい)

当初はclient-java-proto に含まれる io.kubernetes.client.proto.V1Admission.AdmissionReview を引数や戻り値に使っており、SpringがHTTPリクエストを解析してコントローラーメソッドに渡す前のところで失敗した。

そのあと、HTTP Bodyは生のbyte列(DataBuffer)を受け取るようにし、それを com.google.protobuf.util.JsonFormat1を使ってparse/printしてみるものの、これらはあくまでProtocolBufferの内容をJSONに書き出すだけなので、Kubernetesオブジェクトがやるようなmetadataをつけてくれなかった。具体的には apiVersion/kind フィールドがつかないため、WebHookとしてapiserverから呼び出すとエラーになってしまった。

在进行试验和错误的过程中,我尝试使用GSON编辑JsonFormat返回的字节流,但是后来我意识到可以从AdmissionReview的proto文件中导出OpenAPI Spec(就像Pod和其他k8s对象一样),然后生成Java对象。我开始进行调查,发现了上述指南以及作为示例公开的client-java-admission-review。

建筑

SpringBoot支持使用GraalVM进行native-image编译,以生成原生二进制文件。

コンテナとして起動するにはコンテナイメージの最小化や起動時間・起動時の所要メモリなどでメリットのあるネイティブコンパイルができるとうれしいので試してみた。

紆余曲折している最中は余計な依存を入れてみたりしたものの、あとから見ればそれらは特に必要なく、SpringBootのリファレンス通り、以下のコマンドでビルドすれば十分だった。

$ mvn -Pnative spring-boot:build-image

部署

因为Admission Webhook需要TLS认证(也可以使用自定义认证机构),所以使用CertManager创建了自定义CA和Issuer来生成TLS证书。

在`MutatingWebhookConfiguration`资源中注册`MutatingWebhook`到`apiserver`,但在此过程中需要在`caBundle`字段中设置CA证书。不是直接设置PEM格式的证书,而是将其进行Base64编码后再设置。

这件事,虽然应该在这个地方的代码仓库的README.md文件中写下来,但是却没有做到。

感受

如果知道怎么做的话,就可以更简单地做到,或许就不会想要写这篇文章了。

かなりいろいろなことがJavaでもできることは分かった。どうしてJavaでcontrollerなりを開発するコミュニティや企業が出てこないのだろう。

com.google.protobuf:protobuf-java包含的。
广告
将在 10 秒后关闭
bannerAds