Creating An Application Catalogue
Introduction
This guide targets KKP Admins and details adding Applications to a catalogue, so they can be installed by Cluster Admins.
For a more details on Applications refer to our Applications Primer.
Create permissions on the KKP master cluster are required to complete it.
Before an Application is available for install, its installation- and metadata need to be added to the KKP Master Cluster. From the master, they will be automatically replicated to all KKP Seed Clusters.
To organize its catalogue, KKP makes use of a Custom Kubernetes Resource Type called ApplicationDefinition
. This ensures Kubernetes-native management and full GitOps compatibility.
Additionally this mechanism can be used to ensure that only approved Applications can be deployed into a cluster.
Creating an ApplicationDefinition
An ApplicationDefinition represents a single Application and contains all of its versions.
Each ApplicationDefinition maps to one Application in the UI.
It consists of three parts: metadata on the Application itself, templating method, and the templating source.
These will be described in more detail in the subsequent paragraphs; For a complete reference, refer to the ApplicationDefinition Reference section.
Currently ApplicationDefinitions need to be created by hand, but we plan to include a UI importer in an upcoming release.
# Example of an ApplicationDefinition
apiVersion: apps.kubermatic.k8c.io/v1
kind: ApplicationDefinition
metadata:
name: prometheus
spec:
description: Prometheus is a monitoring system and time series database.
method: helm
versions:
- template:
source:
helm:
chartName: prometheus
chartVersion: 15.10.4
url: https://prometheus-community.github.io/helm-charts
version: 2.36.2
- template:
source:
git:
path: charts/prometheus
ref:
branch: master
remote: https://github.com/prometheus-community/helm-charts
version: 0.0.0-dev
Application Metadata is mainly used for presentation and does not affect how an application is deployed:
metadata.name
-> name of the application which will be displayed in the UIspec.versions[].version
-> Version which is displayed in the UI; Each entry of this field must be unique. We strongly recommend to set this to the version of the Application itself not of the chart.
Templating Method
A Templating Method describes how the Kubernetes manifests are being packaged and rendered. Currently helm templating is supported exclusively. Integrations with other templating engines are planned.
Templating Source
Source of the Manifests that should be installed. This controls from where your Application manifests should be fetched. You can combine multiple sources (e.g. helm & git) within one ApplicationDefinition.
A common use-case for combining is to make stable versions (via helm) and a development version (via git) available at the same time.
Helm Source
The Helm Source allows downloading from a Helm HTTP repository or an OCI repository.
The following parameters are required:
url
-> URL to a helm chart repository; If you are unsure about a server, you can always double check if “<your-url>/index.yaml” returns a valid indexchartName
-> Name of the chart within the repositorychartVersion
-> Version of the chart; corresponds to the chartVersion field
Currently the best way to obtain chartName
and chartVersion
for an HTTP repository is to make use of helm search
:
# initial preparation
helm repo add <repo-name> <repo-url>
helm repo update
# listing the names of all charts in a repository
helm search repo <repo-name>
# listing versions of a chart
helm search repo <repo-name>/<chart-name> --versions
# you can also filter for versions. For example if you want to list all prometheus helm charts with a chartversion of 15 or greater, you can run
helm search repo prometheus-community/prometheus --versions --version ">=15"
For OCI repositories, there is currently no helm native search. Instead you have to rely on the capabilities of your OCI registry (for example harbor supports searching for helm-charts directly in their UI).
For private registries, please check the working with private registries section.
Git Source
path
-> path where all manifests are stored; In case of the helm templating method, each chart should be inside its own subdirectory inside pathremote
-> url to the repositoryref
branch
-> branch from which the chart should be pulledtag
-> git tag from which the chart should be pulled; Can not be used in conjunction with commit or branchcommit
-> sha of a commit from which the chart should be pulled; Must be used in conjunction with a branch to ensure shallow cloning
For private git repositories, please check the working with private registries section.
Applying the ApplicationDefinition
After creating an ApplicationDefinition file, you can simply apply it using kubectl in the KKP master cluster. A KKP controller will afterwards ensure that your definition is synched to all KKP Seed Clusters.
# Inside KKP master
kubectl apply -f my-appdef.yml
Working With Private Registries
For working with private registries, the Applications Feature supports storing credentials in Kubernetes secrets in the KKP master and referencing the secrets in your ApplicationDefinitions.
A KKP controller will ensure that the required secrets are synched to your seed clusters. In order for the controller to sync your secrets, they must be annotated with apps.kubermatic.k8c.io/secret-type
and be created in the namespace that KKP is installed in (unless changed, this defaults to “kubermatic”).
Helm OCI Registries
Helm OCI registries are being accessed by using a json configuration similar to the ~/.docker/config.json
on the local machine. It should be noted, that all oci server urls need to be prefixed with oci://
.
- Create a secret containing our credentials
# inside KKP master
kubectl create secret -n <kkp-install-namespace> docker-registry <secret-name> --docker-server=<server> --docker-username=<user> --docker-password=<password>
kubectl annotate secret <secret-name> apps.kubermatic.k8c.io/secret-type="helm"
# example
kubectl create secret -n kubermatic docker-registry oci-cred --docker-server=harbor.example.com/my-project --docker-username=someuser --docker-password=somepaswword
kubectl annotate secret oci-cred apps.kubermatic.k8c.io/secret-type="helm"
- Reference the secret in the ApplicationDefinition
spec:
versions:
- template:
source:
helm:
chartName: examplechart
chartVersion: 0.1.0
credentials:
registryConfigFile:
key: .dockerconfigjson # `kubectl create secret docker-registry` stores by default the creds under this key
name: <secret-name>
url: <server>
Helm Userpass Registries
To use KKP Applications with a helm userpass auth registry, you can configure the following:
- Create a secret containing our credentials
# inside KKP master
kubectl create secret -n <kkp-install-namespace> generic <secret-name> --from-literal=pass=<password> --from-literal=user=<username>
kubectl annotate secret <secret-name> apps.kubermatic.k8c.io/secret-type="helm"
- Reference the secret in the ApplicationDefinition
spec:
versions:
- template:
source:
helm:
chartName: examplechart
chartVersion: 0.1.0
credentials:
password:
key: pass
name: <secret-name>
username:
key: user
name: <secret-name>
url: <server>
Git Repositories
KKP supports three types of authentication for git repositories: Userpass, Token, and SSH-Key.
Their setup is comparable:
- Create a secret containing our credentials
# inside KKP master
# user-pass
kubectl create secret -n <kkp-install-namespace> generic <secret-name> --from-literal=pass=<password> --from-literal=user=<username>
# token
kubectl create secret -n <kkp-install-namespace> generic <secret-name> --from-literal=token=<token>
# ssh-key
kubectl create secret -n <kkp-install-namespace> generic <secret-name> --from-literal=sshKey=<private-ssh-key>
# after creation, annotate
kubectl annotate secret <secret-name> apps.kubermatic.k8c.io/secret-type="git"
- Reference the secret in the ApplicationDefinition
spec:
versions:
- template:
source:
git:
path: <path-inside-git-repo>
ref:
branch: <branch>
remote: <server-url> # for ssh-key, an ssh url must be chosen (e.g. git@example.com/repo.git)
credentials:
method: <password || token || ssh-key>
# user-pass
username:
key: user
name: <secret-name>
password:
key: pass
name: <secret-name>
# token
token:
key: token
name: <secret-name>
# ssh-key
sshKey:
key: sshKey
name: <secret-name>
ApplicationDefinition Reference
The following is an example of ApplicationDefinition, showing all the possible options.
apiVersion: apps.kubermatic.k8c.io/v1
kind: ApplicationDefinitions
metadata:
name: <<appdef-name>>
spec:
# Description of the application. what is its purpose
description: ""
# Method used to install the application
method: helm
# Available version for this application
versions:
- # Template defines how application is installed (source provenance, Method...)
template:
# Defined how the source of the application (e.g Helm chart) is retrieved.
# Exactly one type of source must be defined.
source:
# Install application from a Git repository
git:
# Credentials are optional and holds the git credentials
credentials:
# Authentication method. Either password or token or ssh-key.
# If method is password then username and password must be defined.
# If method is token then token must be defined.
# If method is ssh-key then ssh-key must be defined.
method: password || token || ssh-key
# Password holds the ref and key in the secret for the Password credential.
# The Secret must exist in the namespace where KKP is installed (default is "kubermatic").
# The Secret must be annotated with `apps.kubermatic.k8c.io/secret-type:` set to "helm" or "git".
password:
# The key of the secret to select from. Must be a valid secret key.
key: pass
# Name of the referent.
# This field is effectively required, but due to backwards compatibility is
# allowed to be empty. Instances of this type with an empty value here are
# almost certainly wrong.
# More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: <<secret-name>>
# Specify whether the Secret or its key must be defined
optional: false
# SSHKey holds the ref and key in the secret for the SshKey credential.
# The Secret must exist in the namespace where KKP is installed (default is "kubermatic").
# The Secret must be annotated with `apps.kubermatic.k8c.io/secret-type:` set to "helm" or "git".
sshKey:
# The key of the secret to select from. Must be a valid secret key.
key: private-key
# Name of the referent.
# This field is effectively required, but due to backwards compatibility is
# allowed to be empty. Instances of this type with an empty value here are
# almost certainly wrong.
# More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: <<secret-name>>
# Specify whether the Secret or its key must be defined
optional: false
# Token holds the ref and key in the secret for the token credential.
# The Secret must exist in the namespace where KKP is installed (default is "kubermatic").
# The Secret must be annotated with `apps.kubermatic.k8c.io/secret-type:` set to "helm" or "git".
token:
# The key of the secret to select from. Must be a valid secret key.
key: token
# Name of the referent.
# This field is effectively required, but due to backwards compatibility is
# allowed to be empty. Instances of this type with an empty value here are
# almost certainly wrong.
# More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: <<secret-name>>
# Specify whether the Secret or its key must be defined
optional: false
# Username holds the ref and key in the secret for the username credential.
# The Secret must exist in the namespace where KKP is installed (default is "kubermatic").
# The Secret must be annotated with `apps.kubermatic.k8c.io/secret-type:` set to "helm" or "git".
username:
# The key of the secret to select from. Must be a valid secret key.
key: user
# Name of the referent.
# This field is effectively required, but due to backwards compatibility is
# allowed to be empty. Instances of this type with an empty value here are
# almost certainly wrong.
# More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: <<secret-name>>
# Specify whether the Secret or its key must be defined
optional: false
# Path of the "source" in the repository. default is repository root
path: charts/apache
# Git reference to checkout.
# For large repositories, we recommend to either use Tag, Branch or Branch+Commit.
# This allows a shallow clone, which dramatically speeds up performance
ref:
# Branch to checkout. Only the last commit of the branch will be checkout in order to reduce the amount of data to download.
branch: main
# Commit SHA in a Branch to checkout.
# It must be used in conjunction with branch field.
commit: 8061ceb738db42fe82b4c305b7aa5459d926d03e
# Tag to check out.
# It can not be used in conjunction with commit or branch.
tag: v1.2.3
# URL to the repository. Can be HTTP(s) (e.g. https://example.com/myrepo) or
# SSH (e.g. git://example.com[:port]/path/to/repo.git/).
remote: https://git.example.com/repo || git@example.com/repo
# Install Application from a Helm repository
helm:
# Name of the Chart.
chartName: my-app
# Version of the Chart.
chartVersion: v13.9.0
# Credentials are optional and hold the ref to the secret with Helm credentials.
# Either username / password or registryConfigFile can be defined.
credentials:
# Password holds the ref and key in the secret for the password credential.
# The Secret must exist in the namespace where KKP is installed (default is "kubermatic").
# The Secret must be annotated with `apps.kubermatic.k8c.io/secret-type:` set to "helm" or "git"
password:
# The key of the secret to select from. Must be a valid secret key.
key: pass
# Name of the referent.
# This field is effectively required, but due to backwards compatibility is
# allowed to be empty. Instances of this type with an empty value here are
# almost certainly wrong.
# More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: <<secret-name>>
# Specify whether the Secret or its key must be defined
optional: false
# RegistryConfigFile holds the ref and key in the secret for the registry credential file.
# The value is dockercfg file that follows the same format rules as ~/.docker/config.json.
# The Secret must exist in the namespace where KKP is installed (default is "kubermatic").
# The Secret must be annotated with `apps.kubermatic.k8c.io/secret-type:` set to "helm" or "git"
registryConfigFile:
# The key of the secret to select from. Must be a valid secret key.
key: .dockerconfigjson
# Name of the referent.
# This field is effectively required, but due to backwards compatibility is
# allowed to be empty. Instances of this type with an empty value here are
# almost certainly wrong.
# More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: <<secret-name>>
# Specify whether the Secret or its key must be defined
optional: false
# Username holds the ref and key in the secret for the username credential.
# The Secret must exist in the namespace where KKP is installed (default is "kubermatic").
# The Secret must be annotated with `apps.kubermatic.k8c.io/secret-type:` set to "helm" or "git"
username:
# The key of the secret to select from. Must be a valid secret key.
key: user
# Name of the referent.
# This field is effectively required, but due to backwards compatibility is
# allowed to be empty. Instances of this type with an empty value here are
# almost certainly wrong.
# More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: <<secret-name>>
# Specify whether the Secret or its key must be defined
optional: false
# URL of the Helm repository the following schemes are supported:
# * http://example.com/myrepo (HTTP)
# * https://example.com/myrepo (HTTPS)
# * oci://example.com:5000/myrepo (OCI, HTTPS by default, use plainHTTP to enable unencrypted HTTP)
url: https://charts.example.com || oci://localhost:5000/myrepo
# Version of the application (e.g. v1.2.3)
version: v1.2.3