Try   HackMD

kctrl - Package Kubernetes manifest from Git

tags: kctrl

Packaging manifest from Git

In this tutorial, we will see how to create a package from Kuberenetes manifest present in a Git repository. We will again use MongoDb enterprise operator as an example here.

Prerequisites

  1. Install Carvel tools - imgpkg, kapp, kbld, vendir, ytt.
  2. Identify git and the Kubernetes artifact. MongoDb enterprise operator Github Repository mentions that crds.yaml and mongodb-enterprise.yaml are the Kubernetes resources which can be installed directly to the cluster to make the operator available. We will package crds.yaml and mongodb-enterprise.yaml into a Carvel package and make it available for distribution.
  3. Kubernetes cluster (I will be using minikube).
  4. OCI registry where the package bundle and repository bundles will be pushed (I will be using my Docker Hub account).

Initialize Package

$ mkdir tutorial-4
$ cd tutorial-4
$ kctrl pkg init

To initialize, we will use kctrl pkg init.

This command asks a few basic questions regarding how we want to initialize our package. Lets go through them together:

> Enter the package reference name (samplepackage.corp.com):

  • In this question, we need to enter the package name which will be a valid DNS subdomain name. We will use mongodb-operator.carvel.dev as our package name.

> Enter source (1):

  • Here, we need to enter from where to get the Kubernetes manifest or helm chart which needs to be packaged. As mentioned earlier, we will use Kubernetes manifest from this repo. Hence, we will select Option 4.

> Enter Git URL ():

  • In this, we will enter the github URL. We will enter https://github.com/mongodb/mongodb-enterprise-kubernetes.

> Enter Git Reference (origin/main):

  • We need to provide the branch from where we want to fetch our Kubernetes manifest. We will use 1.17.2.

> Enter the paths which contain Kubernetes manifests ():

  • As mentioned above, we will use crds.yaml,mongodb-enterprise.yaml

After entering all the above details, vendir will download the helm chart locally into upstream folder. kctrl will generate two files - package-build.yml and pacakge-resources.yml as output. Package-resources.yml file contain Package, PackageInstall and PackageMetadata while package-build.yml contains PackageBuild. All the values entered above have been recorded in these files. These files will be used by the dev and pkg release command subsequently.

Release the package

kctrl pkg release will be used to release the package.

$ kctrl pkg release -v 1.0.0

This command will create an imgpkg bundle, upload it to the OCI registry, create package.yml and metadata.yml which can be released for consumption eventually. Also, we are versioning our package with -v flag.

> Enter the registry URL ():

  • Here we need to enter the registry URL where we need to push our imgpkg bundle. While entering the registry URL, ensure to change the value from docker.io/rohitagg2020/mongodb-operator-bundle to docker.io/<YOUR_DOCKERHUB_ACCOUNT>/mongodb-operator-bundle. Alternatively, you can enter other valid OCI registry URL.

Now, we have created our Package and PackageMetadata.

Let's see how the Package and PackageMetadata files look like:

$ cat carvel-artifacts/packages/mongodb-operator.carvel.dev/package.yml
apiVersion: data.packaging.carvel.dev/v1alpha1
kind: Package
metadata:
  creationTimestamp: null
  name: mongodb-operator.carvel.dev.1.0.0
spec:
  refName: mongodb-operator.carvel.dev
  releasedAt: "2022-11-10T08:34:33Z"
  template:
    spec:
      deploy:
      - kapp: {}
      fetch:
      - imgpkgBundle:
          image: index.docker.io/rohitagg2020/mongodb-operator-bundle@sha256:234e7f573a31a61653533742730143aedf62bf640d4145bf2220a6375380aabc
      template:
      - ytt:
          paths:
          - upstream
      - kbld:
          paths:
          - '-'
          - .imgpkg/images.yml
  valuesSchema:
    openAPIv3:
      default: null
      nullable: true
  version: 1.0.0
$ cat carvel-artifacts/packages/mongodb-operator.carvel.dev/metadata.yml
apiVersion: data.packaging.carvel.dev/v1alpha1
kind: PackageMetadata
metadata:
  creationTimestamp: null
  name: mongodb-operator.carvel.dev
spec:
  displayName: mongodb-operator
  longDescription: mongodb-operator.carvel.dev
  shortDescription: mongodb-operator.carvel.dev

Next step is to add it to package repository.

These files can be submitted to the version control tools like github, etc. so that next time while running pkg init or pkg release, these values can be picked up as default values.

Add package to the package repository

kctrl can be used to release packages grouped together into a PackageRepository. Let’s bundle the dynatrace package created above into the PackageRepository.

We will reuse the package repository which was created in tutorial-2

kctrl will create a repo bundle from all the packages and metadata present in the packages folder. We will copy the package.yml and metadata.yml created above into the packages folder. We will follow the bundle format as mentioned here. Alternatively, while running pkg release, --repo-output flag can be used to copy the package.yml and metadata.yml in the prescribed PackageRepository bundle format at a specified location.

$ mkdir -p packages/mongodb-operator.carvel.dev
$ cp ../tutorial-3/carvel-artifacts/packages/mongodb-operator.carvel.dev/package.yml packages/mongodb.carvel.dev/1.0.0.yml
$ cp ../tutorial-3/carvel-artifacts/packages/mongodb-operator.carvel.dev/metadata.yml packages/mongodb.carvel.dev/
$ tree
.
└── packages
    └── mongodb-operator.carvel.dev
        β”œβ”€β”€ 1.0.0.yml
        └── metadata.yml
    ...

Now, we will run kctrl pkg repo release to create and release the repository bundle. This repository bundle can be distributed to the the package consumer.

$ kctrl pkg repo release -v 3.0.0

In this command, it will ask for package repository name and where to push our repository bundle. Also, we are versioning our package repository with -v flag.

> Enter the package repository name (sample-repo.carvel.dev):

  • We will use demo-repo.carvel.dev as our package repository name.

> Enter the registry url ():

  • All the packages and metadata yaml files present in the packages folder will be bundled into imgpkg bundle and then pushed to the above registry url. While entering the registry URL, ensure to change the value from docker.io/rohitagg2020/demo-repo-bundle to docker.io/<YOUR_DOCKERHUB_ACCOUNT>/demo-repo-bundle. Alternatively, you can enter other valid OCI registry URL.

Test the package (Optional)

To test the package, we will again use kctrl.

First step is to add the packageRepository to the Kubernetes cluster by using kctrl pkg repo add command. Once the package repository is added, all the packages in that repository becomes available to install.

Then we can install a package by using kctrl pkg install command.

Since package repository and package install are custom resources(CRs), we have to deploy the kapp-controller onto the cluster so that all these CRs become available on the cluster.

Install kapp controller

NOTE: In case you have already installed kapp-controller, skip this section.

To install, kapp-controller, run

$ kapp deploy -a kc -f https://github.com/vmware-tanzu/carvel-kapp-controller/releases/latest/download/release.yml

Add package repository

To add the package repo, we will run

$ kubectl create ns kctrl-test
$ kctrl pkg repo add -r demo-repo --url docker.io/rohitagg2020/demo-repo-bundle:3.0.0 -n kctrl-test

To list the available packages, run

$ kctrl pkg available --list -n kctrl-test

Install package

To install the package, we will run

$ kctrl pkg install -i pkg-install-demo -p mongodb-operator.carvel.dev -v 1.0.0 -n kctrl-test

Confirm package installed successfully

To confirm that package has been installed successfully, list down the pods and ensure that mongodb-operator has been deployed successfully.

$ kubectl get pods -n kctrl-test