Editing and Applying Kubernetes Manifests with Kpt

kubernetes

Kpt is Google’s OSS for editing Kubernetes Manifests. Compared to kustomize, which is built into kubectl, it takes an approach of editing Manifests in a WYSIWYG manner using templates and Functions, rather than applying patches to base Manifests.

Generate Kubernetes manifest for each environment with kustomize - sambaiz-net

Install the CLI.

$ brew tap GoogleContainerTools/kpt https://github.com/GoogleContainerTools/kpt.git
$ brew install kpt
$ kpt version
1.0.0-beta.49

Use kpt pkg get to retrieve packages from a git repository.

$ kpt pkg get https://github.com/GoogleContainerTools/kpt/package-examples/[email protected]
$ ls nginx
Kptfile         deployment.yaml svc.yaml

Kptfile contains information about the upstream etc.

$ cat Kptfile 
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
  name: nginx
upstream:
  type: git
  git:
    repo: https://github.com/GoogleContainerTools/kpt
    directory: /package-examples/nginx
    ref: v0.9
  updateStrategy: resource-merge
upstreamLock:
  type: git
  git:
    repo: https://github.com/GoogleContainerTools/kpt
    directory: /package-examples/nginx
    ref: package-examples/nginx/v0.9
    commit: b9ea0bca019dafa9f9f91fd428385597c708518c
info:
  emails:
    - [email protected]
  description: This is an example nginx package.
pipeline:
  validators:
    - image: gcr.io/kpt-fn/kubeval:v0.3
      configMap:
        strict: "true"

kpt pkg update applies upstream changes using a 3-way merge. During this process, annotations and kpt-merge comments are automatically added.

$ cat svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  annotations:
    aaaa: bbbb
spec:
  type: LoadBalancer
  selector:
    app: my-nginx
  ports:
    - protocol: TCP
      port: 8080

$ kpt pkg update
$ git diff svc.yaml
...
 apiVersion: v1
 kind: Service
-metadata:
+metadata: # kpt-merge: /my-nginx-svc
   name: my-nginx-svc
   labels:
     app: my-nginx
   annotations:
     aaaa: bbbb
+    internal.kpt.dev/upstream-identifier: '|Service|default|my-nginx-svc'
 spec:
   type: LoadBalancer
   selector:

kpt fn eval execute Functions, and kpt fn render execute the pipeline in the Kptfile.

$ kpt fn eval --image gcr.io/kpt-fn/search-replace:v0.1 -- by-path='spec.**.app' put-value=my-nginx
$ git diff deployment.yaml 
...
@@ -22,11 +21,11 @@ spec:
   replicas: 4
   selector:
     matchLabels:
-      app: nginx
+      app: my-nginx
   template:
     metadata:
       labels:
-        app: nginx
+        app: my-nginx
     spec:
       containers:
         - name: nginx

kpt live install-resource-group installs the ResourceGroup CRD used for management in the cluster. kpt live init initializes the package and kpt live apply applies it.

$ kpt live install-resource-group
$ kpt live init
$ cat resourcegroup.yaml 
apiVersion: kpt.dev/v1alpha1
kind: ResourceGroup
metadata:
  name: inventory-48465506
  namespace: default
  labels:
    cli-utils.sigs.k8s.io/inventory-id: 3128ef464fed9e269153f7801d6dbcac677e712a-1730792231618652000

$ kpt live apply
inventory update started
inventory update finished
apply phase started
service/my-nginx-svc apply successful
deployment.apps/my-nginx-update apply successful
apply phase finished
reconcile phase started
service/my-nginx-svc reconcile successful
deployment.apps/my-nginx-update reconcile pending
deployment.apps/my-nginx-update reconcile successful
reconcile phase finished
inventory update started
inventory update finished
apply result: 2 attempted, 2 successful, 0 skipped, 0 failed
reconcile result: 2 attempted, 2 successful, 0 skipped, 0 failed, 0 timed out