Edit this page

Using Helm charts and git

Last modified Apr 20, 2023

This is written the 22 of june2021

Helm charts are a simple way to make a standard recipe for deployments on Kubernetes. With Helm you have access to a strong, widely used templating language. Helm Charts are Kubernetes YAML manifests combined into a single package.

There are several of publishers for Helm charts. One source of charts are Artifacthub.io. Artifacthub is a project under CNCF.

Helm charts are typically open source. Before using a Helm chart, verify the template code (you want to know what is deployed!).

KitHosting provides, free of use, Helm charts as well. A public Helm chart consists of two parts. The compressed chart which is ready for use and the source code and documentation.

Chart Description Helm repo Code and documentation Production ready
Service chart Generic chart for making deployments, ingress, persistent volumes, cron jobs etc.
ArgoApps chart Convenience chart for easy adding multiple argo apps from same repo
KitCaddy chart Chart that adds a side car that handles SAML based logins and OIOIDWS calls

The service chart is used in the quickstart example. This service-helmchart is a helm-chart designed to deploy any image, without having to create a designated helmchart.

The KitCaddy charts adds a high performing container build in golang. The container is a reverse proxy that handles SAML2 requests. The side car could be used if you need SAML based authentication. When the user is logged ind a Token is forwarded to your service. This means that, that you dont need to handle SAML2 request yourself. KitCaddy is open source, The source code can be found here

How to use the ArgoApps chart

If you use the template for generating a new git repository you will have a predefined structure in git. In the root of the repository you should have one folder for each application you wish to deploy. Furthermore, you should also have an app folder. The app folder defines the app of apps which provides an easy management of your apps. Using this means you only have to do one setup in Argo, for all your projects, so you do not have to repeat the setup in argo descriped in quickstart and deploy using argo for each deployment.

The app of apps points can point to multiple services (for instance test-website, test-website2 and so on). app of apps is made as convenience method for deploying multiple services.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
my-applications-gitrepository
│
└───apps                  # app of apps
│   │   Chart.yaml
│   │   values-prod.yaml
│   │   values-test.yaml
│   │   values.yaml
│ ....
└───my-new-services       # The new service we want to deploy
│   │   Chart.yaml
│   │   values-prod.yaml
│   │   values-test.yaml
│   │   values.yaml

Links to documentation for argoApps chart can be found above. The following gives a short walk through files in the app folder.

Here we can see that the chart is dependant on the helmchart called argoApps. The documentation for this can be found at our own helm-repository. This helmchart can be configured using values-files.

apiVersion: v2
name: test-kunde
version: 1.0.8
dependencies:
  - name: argoApps
    version: 1.0.8
    repository: https://raw.githubusercontent.com/KvalitetsIT/helm-repo/master/

All the values that are environment-specific are to be stored in another values file. This file right here is for the prod-environment, so we call it values-prod.yaml.

In this file we tell the helm-chart where to find (in the gitrepository) the applications we wish to deploy. In this example, we want to deploy our app of apps called test-kunde-applications, and we want to deploy our test-website called test-website. Each of these deployments should have their own folder in the repository, with their own values-files, and chart (just like the structure higher up)

argoApps:
  applications:
    test-kunde-applications: #Name of the application
      path: apps # path from gitrepo-root to the chart-file
      targetRevision: main #branch
      valueFiles: #Values files to use
        - values.yaml #Shared config
        - values-prod.yaml #environment-specific config

    test-website:
      path: test-website
      targetRevision: main
      valueFiles:
        - values.yaml
        - values-prod.yaml

All the values that are environment-specific are to be stored in another values file. This file right here is for the test-environment, so we call it values-test.yaml.

In this file we tell the helm-chart where to find (in the gitrepository) the applications we wish to deploy. In this example, we want to deploy our app of apps called test-kunde-applications, and we want to deploy our test-website called test-website. Each of these deployments should have their own folder in the repository, with their own values-files, and chart (just like the structure higher up)

argoApps:
  applications:
    test-kunde-applications: #Name of the application
      path: apps # path from gitrepo-root to the chart-file
      targetRevision: main #branch
      valueFiles: #Values files to use
        - values.yaml #Shared config
        - values-test.yaml #environment-specific config

    test-website:
      path: test-website
      targetRevision: main
      valueFiles:
        - values.yaml
        - values-test.yaml

All the values that are shared between the environments are to be stored in the values.yaml file.

argoApps:
  server: https://kubernetes.default.svc
  repoUrl: https://github.com/KvalitetsIT/kithosting-test-kunde.git

  namespaceArgo: infrastructure
  namespace: test-kunde
  project: test-kunde

How to use the Service chart

If you use the template for generating a new git repository you will have a predefined structure in git.

When using the service-helmchart, you create a new folder in you applications-repository. Here you add a chart-file and values-files. Furthermore we recommend that you add a app of apps if the deployment repository consists of multiple services.

This results in the following structure. There is a github template that can be used to generate the structure and files quickstart

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
my-applications-gitrepository
│
└───apps                  # app of apps
│   │   Chart.yaml
│   │   values-prod.yaml
│   │   values-test.yaml
│   │   values.yaml
│ ....
└───my-new-services       # The new service we want to deploy
│   │   Chart.yaml
│   │   values-prod.yaml
│   │   values-test.yaml
│   │   values.yaml

In your app of apps you add the following

my-service:
  path: my-service
  targetRevision: main
  valueFiles:
    - values.yaml
    - values-test.yaml
apiVersion: v2
name: test-kunde
version: 1.18.11
dependencies:
  - name: service
    version: 1.18.11
    repository: https://raw.githubusercontent.com/KvalitetsIT/helm-repo/master/

Below is an example of a values file that creates and runs a container with a given image. Furthermore it creates:

  • ReadinessProbe ensures that no traffic is sent to the container before it has started up
  • Livenessprobe ensures that the container stays alive, and if it dies another container will be created
  • Certificate automatically uses letsencrypt to get a valid certificate for my domain
service:
  replicaCount: 2
  docReplicaCount: 1
  namespace: my-namespace #!!change this to correct namespace!!
  image:
    repository: image-i-wanna-run #!!change this to correct image!!
    pullPolicy: IfNotPresent
    # Overrides the image tag whose default is the chart appVersion.
    tag: 0.1.0

  deployment:
    enabled: true
    containerPort: 80
    livenessProbe:
      httpGet:
        path: /
        port: 80
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
      successThreshold: 1
      timeoutSeconds: 1

  docDeployment:
    enabled: false
    containerPort: 80
    env: []

  imagePullSecrets: []
  nameOverride: ""
  fullnameOverride: ""

  serviceAccount:
    # Specifies whether a service account should be created
    create: false
    # Annotations to add to the service account
    annotations: {}
    # The name of the service account to use.
    # If not set and create is true, a name is generated using the fullname template
    name: ""

  podAnnotations: {}

  podSecurityContext: {}
    # fsGroup: 2000

  securityContext: {}
    # capabilities:
    #   drop:
    #   - ALL
    # readOnlyRootFilesystem: true
    # runAsNonRoot: true
    # runAsUser: 1000

  service:
    enabled: true
    type: ClusterIP
    port: 8080
    targetPort: 80
    annotations: {}

  docService:
    enabled: false
    type: ClusterIP
    port: 80
    targetPort: container-port
    annotations: {}

  certificate:
    mydomain.dk: #!!change this to your own domain!!
      namespace: my-namespace #!!change this to correct namespace!!
      spec:
        secretName: mydomain.dk #!!change this to your own domain!!
        issuerRef:
          name: letsencrypt-prod
          kind: ClusterIssuer
          group: cert-manager.io
        dnsNames:
          - mydomain.dk #!!change this to your own domain!!

  ingress:
    enabled: true
    annotations: {}
      # kubernetes.io/ingress.class: nginx
      # kubernetes.io/tls-acme: "true"
    hosts:
      - host: mydomain.dk #!!change this to your own domain!!
        paths:
          - path: /
    tls:
      - hosts:
          - mydomain.dk #!!change this to your own domain!!
        secretName: mydomain.dk #!!change this to your own domain!!

  docIngress:
    enabled: false

  resources: {}

  autoscaling:
    enabled: false
    minReplicas: 1
    maxReplicas: 100
    targetCPUUtilizationPercentage: 80
    # targetMemoryUtilizationPercentage: 80

  nodeSelector: {}

  tolerations: []

  affinity: {}

To understand the Helm templating furher take a look at the Helm website