Skip to content

Context and Configuration

Default Context

As seen in the previous chapter, it is often necessary to include a global cluster context in every Release. Rather than manually specifying this in every deployment manifest, it can be defined as a default context in the global configuration.

Config Resource

Unlike many Kubernetes applications that use ConfigMaps, KuboCD uses a dedicated Config Custom Resource.

kubectl -n kubocd get Config.kubocd.kubotal.io

A single instance usually exists (created during the initial Helm deployment):

NAME     AGE
conf01   5d21h

Inspect its content:

kubectl -n kubocd get Config.kubocd.kubotal.io conf01 -o yaml
apiVersion: kubocd.kubotal.io/v1alpha1
kind: Config
metadata:
  name: conf01
  namespace: kubocd
  ...
spec:
  clusterRoles: []
  defaultContexts: []
  defaultHelmInterval: 30m0s
  defaultHelmTimeout: 3m0s
  defaultNamespaceContexts: []
  defaultOnFailureStrategy: updateOnFailure
  defaultPackageInterval: 30m0s
  imageRedirects: []
  onFailureStrategies:
  ...

Attributes like defaultContexts and defaultPackageInterval are managed here. These will be detailed further in the Reference section.

Note

Using a Custom Resource for configuration provides immediate validation (structural errors are rejected) and allows KuboCD to watch for changes. Once the controller has loaded a new configuration, it reconciles every Release again with it. See Several Configs.

Configuring Default Contexts

Create a new configuration manifest to set the default context:

conf02.yaml
---
apiVersion: kubocd.kubotal.io/v1alpha1
kind: Config
metadata:
  name: conf02
  namespace: kubocd
spec:
  defaultContexts:
    - namespace: contexts
      name: cluster

Apply it:

kubectl apply -f configs/conf02.yaml 

Note: Any warnings can be ignored during this step.

Merging Configurations

KuboCD allows breaking configuration across multiple resources. All Config resources in the controller's namespace (kubocd) are merged to form the global configuration.

Resources are processed in alphabetic order. Several Configs explains how KuboCD combines each field.

Tip

Use kubocd dump config to view the final merged configuration.

Now, we can create a Release without explicitly specifying the context:

podinfo3-ctx-def.yaml
---
apiVersion: kubocd.kubotal.io/v1alpha1
kind: Release
metadata:
  name: podinfo3
  namespace: default
spec:
  description: A first sample release of podinfo
  package:
    repository: quay.io/kubodoc/packages/podinfo
    tag: 6.7.1-p02
  parameters:
    host: podinfo3
kubectl apply -f releases/podinfo3-ctx-def.yaml 

Verify that the context was automatically applied:

kubectl get release podinfo3
NAME       REPOSITORY                         TAG         CONTEXTS           STATUS   READY   WAIT   PRT   AGE   DESCRIPTION
podinfo3   quay.io/kubodoc/packages/podinfo   6.7.1-p02   contexts:cluster   READY    1/1            -     31m   A first sample release of podinfo

And confirm the ingress domain generation:

kubectl get ingress podinfo3-main

Namespaced Default Contexts

KuboCD also supports defining a default context per namespace.

Update the global configuration to enable this feature:

conf03.yaml
---
apiVersion: kubocd.kubotal.io/v1alpha1
kind: Config
metadata:
  name: conf03
  namespace: kubocd
spec:
  defaultNamespaceContexts: 
    - project
kubectl apply -f configs/conf03.yaml 

With this setting, every Release will check its own namespace for a context named project and use it if found.

Create a new namespace project03:

kubectl create ns project03

Create a project-specific context named project in that namespace:

project03.yaml
apiVersion: kubocd.kubotal.io/v1alpha1
kind: Context
metadata:
  name: project
spec:
  description: Context For projet 3
  context:
    project:
      id: p03
    ingress:
      domain: prj03.ingress.kubodoc.local
kubectl -n project03 apply -f contexts/project03.yaml 

Deploy a Release without specifying contexts:

podinfo-prj03.yaml
---
apiVersion: kubocd.kubotal.io/v1alpha1
kind: Release
metadata:
  name: podinfo
spec:
  description: A release of podinfo on project03
  package:
    repository: quay.io/kubodoc/packages/podinfo
    tag: 6.7.1-p02
    interval: 30m
  parameters:
    host: podinfo
  debug:
    dumpContext: true
    dumpParameters: true
kubectl -n project03 apply -f releases/podinfo-prj03.yaml

Verify that both default contexts (global cluster and local project) are used:

kubectl -n project03 get release podinfo
NAME      REPOSITORY                         TAG         CONTEXTS                             STATUS   READY   WAIT   PRT   AGE   DESCRIPTION
podinfo   quay.io/kubodoc/packages/podinfo   6.7.1-p02   contexts:cluster,project03:project   READY    1/1            -     10m   A release of podinfo on project03

Context Ordering

The order in which contexts are merged is critical, as later values override earlier ones. The precedence order is:

  1. Global Default Contexts (in list order).
  2. Namespace Default Contexts (if they exist).
  3. Release-Specific Contexts (in list order).

Warning

Referencing a non-existent context in spec.contexts results in an error. Missing namespace default contexts are ignored silently.

Tip

Use kubocd dump context to inspect the resolved context for a specific namespace.

Disabling Default Contexts

If you need to disable default context merging for a specific Release, use the skipDefaultContext: true flag in the Release specification.


Configuration via Helm Chart

In a real setup, you can define these configurations directly during the KuboCD installation via Helm values.

Example values1-ctrl.yaml:

values1-ctrl.yaml
extraNamespaces:
  - name: contexts
config:
  enabled: true
  content:
    defaultContexts:
      - name: cluster
        namespace: contexts
    defaultNamespaceContexts:
      - project
contexts:
  - name: cluster
    namespace: contexts
    protected: true
    description: Context specific to the cluster 'kubodoc'
    context:
      ingress:
        className: nginx
        domain: ingress.kubodoc.local
      storageClass:
        data: standard
        workspace: standard
      certificateIssuer:
        public: cluster-self
        internal: cluster-self

Upgrade the deployment:

helm -n kubocd upgrade kubocd-ctrl oci://quay.io/kubocd/charts/kubocd-ctrl:v0.4.3 --values helm-values/values1-ctrl.yaml

Adoption Error

If you manually created the contexts namespace and cluster context earlier, Helm will fail to adopt them. Delete them first:

kubectl -n contexts delete context.kubocd.kubotal.io cluster
kubectl delete ns contexts

Then re-run the upgrade.

Once managed by Helm, you can remove the manual config resources:

kubectl -n kubocd delete config.kubocd.kubotal.io conf02
kubectl -n kubocd delete config.kubocd.kubotal.io conf03

Controller Limits

The controller refuses a package that goes past its limits, and bounds the packages it keeps loaded in memory. Each limit is a flag of the controller, which the controller.additionalArgs value of the kubocd-ctrl chart passes:

controller:
  additionalArgs:
    - --maxPackageArtifactSize=52428800
Flag Default What it bounds
--maxPackageArtifactSize 20971520 (20 MiB) The bytes of the archive of a package, as source-controller serves it.
--maxPackageContentSize 41943040 (40 MiB) The bytes that the files of the archive hold once extracted.
--maxPackageEntries 1000 The entries of the archive: files, folders and links. The folders that a name needs count too, and a name of more than 32 levels is refused.
--maxPackageManifestSize 1048576 (1 MiB) The bytes of the original.yaml of a package, and of its status.yaml, each.
--maxCachedPackages 100 The packages that the controller keeps loaded in memory. Past it, the oldest one leaves, and is loaded again from its files when a Release needs it.
--maxCachedPackagesSize 4194304 (4 MiB) The bytes of original.yaml and status.yaml that the packages kept loaded in memory come from.

The values are integers, in bytes for the sizes. A value that is not positive, or more than 1048576 entries, stops the controller at startup with a message.

A package past one of the first four limits puts its Release in ERROR, for instance:

unable to fetch artifact: the package artifact is 31457280 bytes, more than the limit of 20971520 bytes
error while parsing package original.yaml file: the file is more than the limit of 1048576 bytes

The controller schedules no retry on these errors: a new package, a change of the Release or a restart of the controller reconciles it again. A fetch of a package that lasts more than 5 minutes fails, and is tried again later.