Mastering Kubernetes with GitOps, Declarative Configurations, and Kpt
When approaching a technology as complex and robust as Kubernetes, it can be easy to get lost in layers of abstraction. Helm charts and Kustomize can potentially obfuscate the fundamental concepts that newcomers should grasp. The end product—a Kubernetes manifest—should be our primary focus, and that's where Kpt excels.
Moving Past Abstraction Layers
Abstractions like Helm charts and Kustomize simplify the Kubernetes configuration process, but their usage can often obscure the actual, final configuration. Both employ an indirect approach: Helm uses a templating system, while Kustomize employs transformations. In both cases, the final Kubernetes configuration doesn't materialize until the deployment step. This abstraction can create additional cognitive load, making it difficult for newcomers to reconcile the final configurations with their original counterparts.
Embracing GitOps and Declarative Configurations
With GitOps and declarative configurations, you're embracing a straightforward, reliable approach to configuration management. Declarative configurations, represented by Kubernetes manifests, define the desired state of resources without detailing the specific steps to achieve that state.
One principle of GitOps is that configurations should be declarative. Helm and Kustomize, with their templating systems and transformations, obscure this principle. Rather than providing clear, direct manifests, they add an abstraction layer that makes it challenging to understand the actual configuration.
By contrast, with tools like Kpt or even plain Kubernetes manifests, the configurations stored in your Git repository directly represent what will be deployed in your cluster. They allow for a clearer understanding of what the configuration is, offer the flexibility to modify any part of the configuration, and adhere more strictly to the principles of GitOps. In this approach, Git becomes the single source of truth for both your application code and infrastructure, simplifying the Kubernetes configuration management process significantly.
Leverage Kpt for Kubernetes Configuration Management
Kpt is a fantastic tool that amplifies the power of raw Kubernetes manifests by providing capabilities for configuration management and customization. The real power of Kpt is in its CLI tool and the Kpt functions catalog, which provide a set of building blocks for working with Kubernetes configurations.
Kpt as a CLI Tool
Kpt, as a CLI tool, provides a powerful set of functionalities to enhance your interaction with Kubernetes manifests. The kpt fn commands are central to Kpt's power, allowing you to execute function chains to manipulate configurations. Functions in the Kpt catalog enable complex transformations and validations that extend beyond the capabilities of kubectl or yaml processors.
Additionally, commands such as kpt pkg get and kpt pkg update make it straightforward to fetch and update Kpt packages from Git repositories. This seamless integration with Git repositories aligns perfectly with the GitOps workflow, facilitating the process of maintaining your infrastructure as code.
Through these functionalities, Kpt ensures that you have precise control over your Kubernetes configurations while maintaining simplicity and clarity.
Kpt as a Package Manager
Kpt works as a Kubernetes package manager, letting you fetch, update, and apply configurations. You can get the basic configuration of a package, customize it for different environments, and still pull future changes from the upstream source. Here's a diagram explaining this:
Kpt and Declarative Configuration Customization
Kpt provides a function pipeline to customize declarative configurations. The pipeline allows you to define a sequence of operations in a declarative manner within the Kptfile. These operations, also known as "functions," manipulate the package's configuration resources.
Let's consider the apply-setters function, one of many functions available in the kpt function catalog. You can define this function in the Kptfile's pipeline section to configure certain fields across your resources:
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: my-pkg
pipeline:
mutators:
- image: gcr.io/kpt-fn/apply-setters:v0.2.0
configMap:
image: nginx:1.14.2
replicas: 5The apply-setters function here is a "mutator," which means it modifies the package's resources.
When you run kpt fn render my-pkg, Kpt executes the pipeline functions in the order they are defined in the Kptfile. This rendering process reads the resources of the package (including sub-packages), applies the functions, and then writes the output back to the original configuration files. This way, the functions in the pipeline are used to transform the package resources from their initial state to the desired state.
The following configuration file defines a Kubernetes Deployment for an Nginx server. The image field of the Nginx container and the replicas field under spec both have setter comments: # kpt-set: ${image} and # kpt-set: ${replicas} respectively. These setter comments mean that these fields' values can be manipulated by the apply-setters function from Kpt.
When you run kpt fn render my-pkg, the function will update the Deployment manifest as follows:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 5 # kpt-set: ${replicas}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: "nginx:1.14.2" # kpt-set: ${image}
ports:
- containerPort: 80The resulting configurations, written back to your local files, are the ones that will be applied to your Kubernetes cluster. They are also immediately available for review or additional changes. This process provides a high level of transparency and control, allowing you to see exactly what will be deployed to the cluster.
Imperative function execution
In addition to the declarative function execution, Kpt also supports imperative function execution for one-off operations. For instance, if you have a one-off change that needs to be applied across resources, you can use an imperative command, like so:
kpt fn eval --image gcr.io/kpt-fn/apply-setters:v0.1 -- 'image=nginx:1.14.2'This command applies the apply-setters function across your resources, replacing the image field value with nginx:1.14.2. The changes are applied in place, providing immediate visibility into the impact of the function.
Conclusion
Mastering Kubernetes starts with understanding its core components, and Kpt helps make this journey easier. It allows users to interact directly with Kubernetes manifests, fostering a clearer understanding of Kubernetes configurations. Through its robust package management capabilities and support for declarative configurations, Kpt streamlines Kubernetes configuration management, aligning perfectly with the GitOps paradigm. Whether you're a newcomer learning the ropes or an expert seeking granular control, Kpt is a powerful tool for managing your Kubernetes infrastructure.


