This post is for beginners. Here are some background information that you should know before reading this article:
- Java language programming knowledge;
- Understand the working mechanism of Operator/Controller on Kubernetes platform;
Can also be synchronous reference Kubernetes official blog content: Kubernetes. IO/blog / 2019/1…
Photo: He Zibo and Jin Min after sharing at KubeCon NA2019
Technical expert of Ant Financial: _(adohe@github) _Maintainer of Kubernetes, SIG CLI Co-chair (including Kubectl and its extensions, Kustomize and client runtime), also focus on security container, multi-tenant and other fields.
Jinmin Ant Financial Software Engineer: _(yue9944882@github) _Kubernetes SIG API-Machinery maintainer and its sub-domain Owner (CRD service implementation, APIAggregation SDK suite, control surface flow control, OpenAPiv2/3, Java SDK, etc.) and is the Techincal Committee of OpenAPI’s open source ecosystem tool chain, Openapitools.org.
This post is based on KubeCon NA2019. This presentation will share ant Financial fintech’s practice and transformation of extending cloud native Java capabilities to the cloud, and open the harvest to the Kubernetes community.
Share the profile
Developing deployment operators on the Kubernetes platform has been the default paradigm for expanding development capabilities on Kubernetes. It was the CoreOS engineers who first proposed the Operator development concept and received a good response in the community. After a period of twists and turns, polishing and practice, we see a variety of operators emerging today. In fact, Operator power is often best achieved in combination with the extended capabilities of the Kubernetes API. So its widespread dissemination in turn has evolved the ability of the CustomResourceDefinition on Kubernetes to host third-party API models. A rising tide lifts all boats, which is why the community has focused their efforts on Kubernetes Extensibility building since V1.14.
With the increasing audience of Operator, the community has also derived tool-chain projects for Operator development and improvement, such as Operator-SDK, KubeBuilder, Metacontroller and other excellent open source projects. But these projects are mostly for Go language developers, although more and more developers to Go is a fact, but Go language is not as mature as other mainstream programming languages, but slowly spread Kubernetes and other open source projects in the industrial practice of “forced” Go language base library repair and stability, Such as http2’s underlying network library [1]. Similarly, our first in-house Operator runtime framework for the Java language was “forced” by the business, and received a lot of feedback from the Kubernetes community in its early days, leading to its full open development today.
Why do you need to use a Java development Operator
If you’re on the ropes about whether to use Java development operators and put them into practice, let’s compare and contrast the following aspects to see what appeals to you:
- Adaptive inventory Systems: If all of your infrastructure’s underlying systems were developed in Java before you logged on to Kubernetes, you have a natural base for using Java Operators. Conversely, “translating” the storage system interfaces into Go language one by one consumes a lot of manpower and leads to the cost of maintaining the Go language library continuously and synchronously.
- Heap memory snapshot: Compared with Java, Go language is difficult to do a complete snapshot analysis of the memory of running programs. PProf related tool chain can only do a summary output of memory usage. Although it can also help analysis to lock out the leaking object types, but the granularity is limited. On the other hand, Java heap snapshot analysis has mature tool chain support, through a full heap snapshot can be directly locked out such as the backlog in the WorkQueue, or even in the flow limiter key-by-key transient state. You can also quickly lock the problem if the Operator is silent and does not respond.
- Performance diagnostics/online debugging: With the help of tool chains such as JMX, we directly collect the detailed health of the Java virtual machine in the form of Prometheus Metrics, although the Go program can also expose its runtime Metrics, But by comparison, Java Metrics is much more powerful at analyzing GC state and heap distribution. In addition, remote debugging of the Java Operator is more user-friendly.
- Threading model: Significantly different from Java, Routine in Go doesn’t “kill” you directly from the outside. You implement it indirectly, using channels/Contexts, etc. The thread model in the Java virtual machine has lifecycle management similar to that in the operating system, where developers can interfere with the lifecycle of threads with white-box operations. This is important for some business scenarios.
- OOP paradigms: The design philosophy of the Go language itself does not recognize object-oriented programming, but in Kubernetes projects with numerous API models, maintainers have to turn to using code generators to generate large amounts of template code for those models in bulk. One of Java’s strengths is generic programming, which can completely replace the work of code generators. The same set of code can be freely adapted to various models, from Pod to Service, and so on.
- Third-party developer ecosystem: After decades of evolution, Java has amassed a much richer library of third-party tools than Go, at least for now.
Quick overview of sample code
The following two code snippets show you all the work required to develop a Java Operator in detail. Developers who have worked with Kubernetes Client-Go have a general idea of how to use the Kubernetes client-Go name:
How to construct an Informer instance github.com/kubernetes-…
(How to construct an Operator instance) https://github.com/kubernetes-client/java/blob/master/examples/src/main/java/io/kubernetes/client/examples/ControllerExa mple.java
What additional considerations do I need to take into account when developing Java Operator
Simply coding operators is not the end of the story, but there are other things you need to be aware of. Here’s what we learned in practice:
- Rigorously managing THE CRD Yaml definition: As mentioned at the beginning, when the Java Operator operates on a custom resource such as a CRD, we naturally need to operate/maintain the Java model corresponding to that CRD. This first introduces the issue of good maintenance of CRD Yaml (details will not be covered here), as well as the issue of how CRD Yaml is mapped to a Java model. The latter can be managed manually, or your CRD Yaml can be converted into a seamless Java model in one step via a code generator. At the heart of Kubernetes is the API model. The community’s own API changes are reviewed as a top priority, and we should be more careful when extending the management API model on our own.
- Pay attention to the Operator shutdown steps: Currently there is no graceful exit for operators in the Go language, but that doesn’t mean we don’t need one. Under Java’s thread-management model, we can fine-tune the behavior of an Operator when it shuts down, such as releasing tasks in the queue completely before going offline.
- Decouple Operator as a independently deployed component: When developing Java programs, developers tend to declare Operator as, for example, “Spring Bean” and inject it into an RPC service. However, this is not recommended because the life cycle of an Operator should be to exit the restart when its Lease is renewed, and the restart operation of RPC services is usually more expensive. They don’t match.
Future expansion/road map
In addition to the continuous parallel porting of the existing capabilities of Client-Go to Java clients, we are planning the following as a roadmap for the future:
- Operator expansion ability in large-scale cluster;
- Scalability of multiple clusters for Kuberentes community standards;
- Distributed object/task tracking under Operator;
conclusion
This article describes how to quickly get started using the Java development Operator. Interested readers can use the official example to experience the local development environment. The Kubernetes community’s Java client has evolved thanks to the community’s contributions and feedback, and thanks to red Hat’s Fabric8 client, developers can enjoy a smoother development interface experience. More ideas and suggestions for the future development of Java in Kubernetes community Friends welcome to leave a footprint in our warehouse: github.com/kubernetes-… . At the same time, we also welcome friends who are committed to the cloud native field to join us, and we will explore and innovate together!
[1] More context reference: github.com/kubernetes/…
[2] Generating Java models from CRD Yaml reference: github.com/kubernetes-…
Financial Class Distributed Architecture (Antfin_SOFA)