helm

[!NOTE|label:references:]

helm3

$ curl -kL https://git.io/get_helm.sh | bash

# or
$ bash <(curl -k -fsSL https://git.io/get_helm.sh)
# or
$ bash <(curl -k -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3)
$ helm version
version.BuildInfo{Version:"v3.12.0", GitCommit:"c9f554d75773799f72ceef38c51210f1842a1dea", GitTreeState:"clean", GoVersion:"go1.20.3"}
$ helm --help
The Kubernetes package manager

Common actions for Helm:

- helm search:    search for charts
- helm pull:      download a chart to your local directory to view
- helm install:   upload the chart to Kubernetes
- helm list:      list releases of charts

Environment variables:

| Name                               | Description                                                                                       |
|------------------------------------|---------------------------------------------------------------------------------------------------|
| $HELM_CACHE_HOME                   | set an alternative location for storing cached files.                                             |
| $HELM_CONFIG_HOME                  | set an alternative location for storing Helm configuration.                                       |
| $HELM_DATA_HOME                    | set an alternative location for storing Helm data.                                                |
| $HELM_DEBUG                        | indicate whether or not Helm is running in Debug mode                                             |
| $HELM_DRIVER                       | set the backend storage driver. Values are: configmap, secret, memory, sql.                       |
| $HELM_DRIVER_SQL_CONNECTION_STRING | set the connection string the SQL storage driver should use.                                      |
| $HELM_MAX_HISTORY                  | set the maximum number of helm release history.                                                   |
| $HELM_NAMESPACE                    | set the namespace used for the helm operations.                                                   |
| $HELM_NO_PLUGINS                   | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.                                        |
| $HELM_PLUGINS                      | set the path to the plugins directory                                                             |
| $HELM_REGISTRY_CONFIG              | set the path to the registry config file.                                                         |
| $HELM_REPOSITORY_CACHE             | set the path to the repository cache directory                                                    |
| $HELM_REPOSITORY_CONFIG            | set the path to the repositories file.                                                            |
| $KUBECONFIG                        | set an alternative Kubernetes configuration file (default "~/.kube/config")                       |
| $HELM_KUBEAPISERVER                | set the Kubernetes API Server Endpoint for authentication                                         |
| $HELM_KUBECAFILE                   | set the Kubernetes certificate authority file.                                                    |
| $HELM_KUBEASGROUPS                 | set the Groups to use for impersonation using a comma-separated list.                             |
| $HELM_KUBEASUSER                   | set the Username to impersonate for the operation.                                                |
| $HELM_KUBECONTEXT                  | set the name of the kubeconfig context.                                                           |
| $HELM_KUBETOKEN                    | set the Bearer KubeToken used for authentication.                                                 |
| $HELM_KUBEINSECURE_SKIP_TLS_VERIFY | indicate if the Kubernetes API server's certificate validation should be skipped (insecure)       |
| $HELM_KUBETLS_SERVER_NAME          | set the server name used to validate the Kubernetes API server certificate                        |
| $HELM_BURST_LIMIT                  | set the default burst limit in the case the server contains many CRDs (default 100, -1 to disable)|

Helm stores cache, configuration, and data based on the following configuration order:
  $ curl -fsSL \
      https://get.helm.sh/helm-v2.14.3-linux-amd64.tar.gz \
      | sudo tar -xzv --strip-components=1 -C /usr/local/bin/

  $ while read -r _i; do
      sudo chmod +x "/usr/local/bin/${_i}"
  done < <(echo helm tiller)
- If a HELM_*_HOME environment variable is set, it will be used
- Otherwise, on systems supporting the XDG base directory specification, the XDG variables will be used
- When no other location is set a default location will be used based on the operating system

By default, the default directories depend on the Operating System. The defaults are listed below:

| Operating System | Cache Path                | Configuration Path             | Data Path               |
|------------------|---------------------------|--------------------------------|-------------------------|
| Linux            | $HOME/.cache/helm         | $HOME/.config/helm             | $HOME/.local/share/helm |
| macOS            | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm      |
| Windows          | %TEMP%\helm               | %APPDATA%\helm                 | %APPDATA%\helm          |

Usage:
  helm [command]

Available Commands:
  completion  generate autocompletion scripts for the specified shell
  create      create a new chart with the given name
  dependency  manage a chart's dependencies
  env         helm client environment information
  get         download extended information of a named release
  help        Help about any command
  history     fetch release history
  install     install a chart
  lint        examine a chart for possible issues
  list        list releases
  package     package a chart directory into a chart archive
  plugin      install, list, or uninstall Helm plugins
  pull        download a chart from a repository and (optionally) unpack it in local directory
  push        push a chart to remote
  registry    login to or logout from a registry
  repo        add, list, remove, update, and index chart repositories
  rollback    roll back a release to a previous revision
  search      search for a keyword in charts
  show        show information of a chart
  status      display the status of the named release
  template    locally render templates
  test        run tests for a release
  uninstall   uninstall a release
  upgrade     upgrade a release
  verify      verify that a chart at the given path has been signed and is valid
  version     print the client version information

Flags:
      --burst-limit int                 client-side default throttling limit (default 100)
      --debug                           enable verbose output
  -h, --help                            help for helm
      --kube-apiserver string           the address and the port for the Kubernetes API server
      --kube-as-group stringArray       group to impersonate for the operation, this flag can be repeated to specify multiple groups.
      --kube-as-user string             username to impersonate for the operation
      --kube-ca-file string             the certificate authority file for the Kubernetes API server connection
      --kube-context string             name of the kubeconfig context to use
      --kube-insecure-skip-tls-verify   if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure
      --kube-tls-server-name string     server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used
      --kube-token string               bearer token used for authentication
      --kubeconfig string               path to the kubeconfig file
  -n, --namespace string                namespace scope for this request
      --registry-config string          path to the registry config file (default "/home/marslo/.config/helm/registry/config.json")
      --repository-cache string         path to the file containing cached repository indexes (default "/home/marslo/.cache/helm/repository")
      --repository-config string        path to the file containing repository names and URLs (default "/home/marslo/.config/helm/repositories.yaml")

Use "helm [command] --help" for more information about a command.

helm2

$ curl -fsSL \
       https://get.helm.sh/helm-v2.14.3-linux-amd64.tar.gz |
       sudo tar -xzv --strip-components=1 -C /usr/local/bin/

$ while read -r _i; do
    sudo chmod +x "/usr/local/bin/${_i}"
  done < <(echo helm tiller)

install plugin

$ echo '-k' >> ~/.curlrc
$ helm plugin install https://github.com/databus23/helm-diff

install apps

[!NOTE|label:references:]

configuration

init

[!TIP|label:NOT suitable for helm3]

$ helm init
$ helm init --client-only

$ kubectl create serviceaccount -n kube-system tiller
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
$ kubectl patch deploy -n kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'

$ helm repo add jenkins https://charts.jenkins.io
$ helm repo update
  • search

    $ helm repo update
    $ helm search repo jenkins

$ kubectl get secrets <secret_name> \
              --namespace <namespace> \
              -o jsonpath="{.data.jenkins-admin-password}" |
          base64 --decode
$ kubectl get secrets <secret_name> \
              --namespace <namespace> \
              -o jsonpath="{.data.jenkins-admin-user}" |
          base64 --decode

usage

[!NOTE|label:references:]

install Jenkins

$ helm repo add jenkins https://charts.jenkins.io
"jenkins" has been added to your repositories

$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "jenkins" chart repository
Update Complete. ⎈Happy Helming!⎈

$ helm repo list
NAME    URL
jenkins https://charts.jenkins.io

$ helm search repo jenkins
NAME            CHART VERSION APP VERSION DESCRIPTION
jenkins/jenkins 4.3.24        2.401.1     Jenkins - Build great things at any scale! The ...

$ helm show values jenkins/jenkins
$ helm show chart  jenkins/jenkins
$ helm show readme jenkins/jenkins
# or
$ helm show all jenkins/jenkins

$ helm --version=4.4.1 upgrade -i --reset-values -f=/path/to/value.yml staging-jenkins jenkins/jenkins
$ helm repo update
$ helm search repo -l jenkins
NAME                                    CHART VERSION   APP VERSION     DESCRIPTION

jenkins/jenkins                         4.6.4           2.414.1         Jenkins - Build great things at any scale! The ...
jenkins/jenkins                         4.6.3           2.414.1         Jenkins - Build great things at any scale! The ...
jenkins/jenkins                         4.6.2           2.414.1         Jenkins - Build great things at any scale! The ...
jenkins/jenkins                         4.6.1           2.414.1         Jenkins - Build great things at any scale! The ...
jenkins/jenkins                         4.6.0           2.414.1         Jenkins - Build great things at any scale! The ...
jenkins/jenkins                         4.5.1           2.414.1         Jenkins - Build great things at any scale! The ...
jenkins/jenkins                         4.5.0           2.401.3         Jenkins - Build great things at any scale! The ...
...

troubleshooting

  • Error: UPGRADE FAILED: "staging-jenkins" has no deployed releases

    $ /usr/local/bin/helm --version=4.5.0 upgrade -i --reset-values -f=/tmp/tmpqxn6qkck.yml staging-jenkins jenkins/jenkins
    Error: UPGRADE FAILED: "staging-jenkins" has no deployed releases
    • solution

      $ helm uninstall staging-jenkins
      release "staging-jenkins" uninstalled
      
      $ /usr/local/bin/helm --version=4.5.0 upgrade -i --reset-values -f=/tmp/tmpqxn6qkck.yml staging-jenkins jenkins/jenkins
      Release "staging-jenkins" does not exist. Installing it now.
      NAME: staging-jenkins
      LAST DEPLOYED: Tue Sep 19 23:05:30 2023
      NAMESPACE: devops
      STATUS: deployed
      REVISION: 1
      NOTES:
      1. Get your 'admin' user password by running:
        kubectl exec --namespace devops -it svc/staging-jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo
      2. Get the Jenkins URL to visit by running these commands in the same shell:
        echo http://127.0.0.1:8080
        kubectl --namespace devops port-forward svc/staging-jenkins 8080:8080
      
      3. Login with the password from step 1 and the username: admin
      4. Configure security realm and authorization strategy
      5. Use Jenkins Configuration as Code by specifying configScripts in your values.yaml file, see documentation: http://127.0.0.1:8080/configuration-as-code and examples: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos
      
      For more information on running Jenkins on Kubernetes, visit:
      https://cloud.google.com/solutions/jenkins-on-container-engine
      
      For more information about Jenkins Configuration as Code, visit:
      https://jenkins.io/projects/jcasc/
      
      NOTE: Consider using a custom image with pre-installed plugins
  • tls: failed to verify certificate: x509

    [!NOTE|label:references:]

    $ helm repo add grafana https://grafana.github.io/helm-charts
    Error: looks like "https://grafana.github.io/helm-charts" is not a valid chart repository or cannot be reached: Get "https://grafana.github.io/helm-charts/index.yaml": tls: failed to verify certificate: x509: certificate signed by unknown authority
    • solution:

      $ helm repo add grafana --insecure-skip-tls-verify https://grafana.github.io/helm-charts
      "grafana" has been added to your repositories

check

$ kubectl get po staging-jenkins-0 -o 'jsonpath={.spec.containers[*].name}'
jenkins config-reload

$ kubectl get po staging-jenkins-0 -o 'jsonpath={.spec.containers[?(@.name=="jenkins")].image}'
jenkins/jenkins:2.401.2-lts-jdk11

$ kubectl get po staging-jenkins-0 -o 'jsonpath={.spec.containers[*].image}'
jenkins/jenkins:2.401.2-lts-jdk11 kiwigrid/k8s-sidecar:1.24.4

# format:
# --as=system:serviceaccount:<namespace>:<serviceaccount>
$ kubectl --as=system:serviceaccount:devops:staging-jenkins auth can-i get configmap/staging-jenkins-jcasc
yes
STDOUT:

Release "staging-jenkins" has been upgraded. Happy Helming!
NAME: staging-jenkins
LAST DEPLOYED: Tue Jul 18 19:21:46 2023
NAMESPACE: devops
STATUS: deployed
REVISION: 21
NOTES:
1. Get your 'admin' user password by running:
  kubectl exec --namespace devops -it svc/staging-jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo
2. Get the Jenkins URL to visit by running these commands in the same shell:
  echo http://127.0.0.1:8080
  kubectl --namespace devops port-forward svc/staging-jenkins 8080:8080
3. Login with the password from step 1 and the username: admin
4. Configure security realm and authorization strategy
5. Use Jenkins Configuration as Code by specifying configScripts in your values.yaml file, see documentation: http://127.0.0.1:8080/configuration-as-code and examples: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos

For more information on running Jenkins on Kubernetes, visit:
https://cloud.google.com/solutions/jenkins-on-container-engine

For more information about Jenkins Configuration as Code, visit:
https://jenkins.io/projects/jcasc/

NOTE: Consider using a custom image with pre-installed plugins
$ helm show values jenkins/jenkins
# Default values for jenkins.
# This is a YAML-formatted file.
# Declare name/value pairs to be passed into your templates.
# name: value

## Overrides for generated resource names
# See templates/_helpers.tpl
# nameOverride:
# fullnameOverride:
# namespaceOverride:

# For FQDN resolving of the controller service. Change this value to match your existing configuration.
# ref: https://github.com/kubernetes/dns/blob/master/docs/specification.md
clusterZone: "cluster.local"

renderHelmLabels: true

controller:
  # Used for label app.kubernetes.io/component
  componentName: "jenkins-controller"
  image: "jenkins/jenkins"
  # tag: "2.401.1-jdk11"
  tagLabel: jdk11
  imagePullPolicy: "Always"
  imagePullSecretName:
  # Optionally configure lifetime for controller-container
  lifecycle:
  #  postStart:
  #    exec:
  #      command:
  #      - "uname"
  #      - "-a"
  disableRememberMe: false
  numExecutors: 0
  # configures the executor mode of the Jenkins node. Possible values are: NORMAL or EXCLUSIVE
  executorMode: "NORMAL"
  # This is ignored if enableRawHtmlMarkupFormatter is true
  markupFormatter: plainText
  customJenkinsLabels: []
  # The default configuration uses this secret to configure an admin user
  # If you don't need that user or use a different security realm then you can disable it
  adminSecret: true

  hostNetworking: false
  # When enabling LDAP or another non-Jenkins identity source, the built-in admin account will no longer exist.
  # If you disable the non-Jenkins identity store and instead use the Jenkins internal one,
  # you should revert controller.adminUser to your preferred admin user:
  adminUser: "admin"
  # adminPassword: <defaults to random>
  admin:
    existingSecret: ""
    userKey: jenkins-admin-user
    passwordKey: jenkins-admin-password
  # This values should not be changed unless you use your custom image of jenkins or any devired from. If you want to use
  # Cloudbees Jenkins Distribution docker, you should set jenkinsHome: "/var/cloudbees-jenkins-distribution"
  jenkinsHome: "/var/jenkins_home"
  # This values should not be changed unless you use your custom image of jenkins or any devired from. If you want to use
  # Cloudbees Jenkins Distribution docker, you should set jenkinsRef: "/usr/share/cloudbees-jenkins-distribution/ref"
  jenkinsRef: "/usr/share/jenkins/ref"
  # Path to the jenkins war file which is used by jenkins-plugin-cli.
  jenkinsWar: "/usr/share/jenkins/jenkins.war"
  # Overrides the default arguments passed to the war
  # overrideArgs:
  #   - --httpPort=8080
  resources:
    requests:
      cpu: "50m"
      memory: "256Mi"
    limits:
      cpu: "2000m"
      memory: "4096Mi"
  # Share process namespace to allow sidecar containers to interact with processes in other containers in the same pod
  shareProcessNamespace: false
  # Overrides the init container default values
  # initContainerResources:
  #   requests:
  #     cpu: "50m"
  #     memory: "256Mi"
  #   limits:
  #     cpu: "2000m"
  #     memory: "4096Mi"
  # Environment variables that get added to the init container (useful for e.g. http_proxy)
  # initContainerEnv:
  #   - name: http_proxy
  #     value: "http://192.168.64.1:3128"
  # containerEnv:
  #   - name: http_proxy
  #     value: "http://192.168.64.1:3128"
  # Set min/max heap here if needed with:
  # javaOpts: "-Xms512m -Xmx512m"
  # jenkinsOpts: ""
  # If you are using the ingress definitions provided by this chart via the `controller.ingress` block the configured hostname will be the ingress hostname starting with `https://` or `http://` depending on the `tls` configuration.
  # The Protocol can be overwritten by specifying `controller.jenkinsUrlProtocol`.
  # jenkinsUrlProtocol: "https"
  # If you are not using the provided ingress you can specify `controller.jenkinsUrl` to change the url definition.
  # jenkinsUrl: ""
  # If you set this prefix and use ingress controller then you might want to set the ingress path below
  # jenkinsUriPrefix: "/jenkins"
  # Enable pod security context (must be `true` if podSecurityContextOverride, runAsUser or fsGroup are set)
  usePodSecurityContext: true
  # Note that `runAsUser`, `fsGroup`, and `securityContextCapabilities` are
  # being deprecated and replaced by `podSecurityContextOverride`.
  # Set runAsUser to 1000 to let Jenkins run as non-root user 'jenkins' which exists in 'jenkins/jenkins' docker image.
  # When setting runAsUser to a different value than 0 also set fsGroup to the same value:
  runAsUser: 1000
  fsGroup: 1000
  # If you have PodSecurityPolicies that require dropping of capabilities as suggested by CIS K8s benchmark, put them here
  securityContextCapabilities: {}
  #  drop:
  #    - NET_RAW
  # Completely overwrites the contents of the `securityContext`, ignoring the
  # values provided for the deprecated fields: `runAsUser`, `fsGroup`, and
  # `securityContextCapabilities`.  In the case of mounting an ext4 filesystem,
  # it might be desirable to use `supplementalGroups` instead of `fsGroup` in
  # the `securityContext` block: https://github.com/kubernetes/kubernetes/issues/67014#issuecomment-589915496
  # podSecurityContextOverride:
  #   runAsUser: 1000
  #   runAsNonRoot: true
  #   supplementalGroups: [1000]
  #   # capabilities: {}
  # Container securityContext
  containerSecurityContext:
    runAsUser: 1000
    runAsGroup: 1000
    readOnlyRootFilesystem: true
    allowPrivilegeEscalation: false
  servicePort: 8080
  targetPort: 8080
  # For minikube, set this to NodePort, elsewhere use LoadBalancer
  # Use ClusterIP if your setup includes ingress controller
  serviceType: ClusterIP
  # Use Local to preserve the client source IP and avoids a second hop for LoadBalancer and Nodeport type services,
  # but risks potentially imbalanced traffic spreading.
  serviceExternalTrafficPolicy:
  # Jenkins controller service annotations
  serviceAnnotations: {}
  # Jenkins controller custom labels
  statefulSetLabels: {}
  #   foo: bar
  #   bar: foo
  # Jenkins controller service labels
  serviceLabels: {}
  #   service.beta.kubernetes.io/aws-load-balancer-backend-protocol: https
  # Put labels on Jenkins controller pod
  podLabels: {}
  # Used to create Ingress record (should be used with ServiceType: ClusterIP)
  # nodePort: <to set explicitly, choose port between 30000-32767
  # Enable Kubernetes Startup, Liveness and Readiness Probes
  # if Startup Probe is supported, enable it too
  # ~ 2 minutes to allow Jenkins to restart when upgrading plugins. Set ReadinessTimeout to be shorter than LivenessTimeout.
  healthProbes: true
  probes:
    startupProbe:
      httpGet:
        path: '{{ default "" .Values.controller.jenkinsUriPrefix }}/login'
        port: http
      periodSeconds: 10
      timeoutSeconds: 5
      failureThreshold: 12
    livenessProbe:
      failureThreshold: 5
      httpGet:
        path: '{{ default "" .Values.controller.jenkinsUriPrefix }}/login'
        port: http
      periodSeconds: 10
      timeoutSeconds: 5
      # If Startup Probe is not supported on your Kubernetes cluster, you might want to use "initialDelaySeconds" instead.
      # It delays the initial liveness probe while Jenkins is starting
      # initialDelaySeconds: 60
    readinessProbe:
      failureThreshold: 3
      httpGet:
        path: '{{ default "" .Values.controller.jenkinsUriPrefix }}/login'
        port: http
      periodSeconds: 10
      timeoutSeconds: 5
      # If Startup Probe is not supported on your Kubernetes cluster, you might want to use "initialDelaySeconds" instead.
      # It delays the initial readyness probe while Jenkins is starting
      # initialDelaySeconds: 60

  # PodDisruptionBudget config
  podDisruptionBudget:
    enabled: false
    # For Kubernetes v1.5+, use 'policy/v1beta1'
    # For Kubernetes v1.21+, use 'policy/v1'
    apiVersion: "policy/v1beta1"
    annotations: {}
    labels: {}
    # maxUnavailable: "0"

  agentListenerEnabled: true
  agentListenerPort: 50000
  agentListenerHostPort:
  agentListenerNodePort:
  agentListenerExternalTrafficPolicy:
  agentListenerLoadBalancerSourceRanges:
  - 0.0.0.0/0
  disabledAgentProtocols:
    - JNLP-connect
    - JNLP2-connect
  csrf:
    defaultCrumbIssuer:
      enabled: true
      proxyCompatability: true
  # Kubernetes service type for the JNLP agent service
  # agentListenerServiceType is the Kubernetes Service type for the JNLP agent service,
  # either 'LoadBalancer', 'NodePort', or 'ClusterIP'
  # Note if you set this to 'LoadBalancer', you *must* define annotations to secure it. By default
  # this will be an external load balancer and allowing inbound 0.0.0.0/0, a HUGE
  # security risk:  https://github.com/kubernetes/charts/issues/1341
  agentListenerServiceType: "ClusterIP"
  # Optionally assign an IP to the LoadBalancer agentListenerService LoadBalancer
  # GKE users: only regional static IPs will work for Service Load balancer.
  agentListenerLoadBalancerIP:
  agentListenerServiceAnnotations: {}

  # Example of 'LoadBalancer' type of agent listener with annotations securing it
  # agentListenerServiceType: LoadBalancer
  # agentListenerServiceAnnotations:
  #   service.beta.kubernetes.io/aws-load-balancer-internal: "True"
  #   service.beta.kubernetes.io/load-balancer-source-ranges: "172.0.0.0/8, 10.0.0.0/8"

  # LoadBalancerSourcesRange is a list of allowed CIDR values, which are combined with ServicePort to
  # set allowed inbound rules on the security group assigned to the controller load balancer
  loadBalancerSourceRanges:
  - 0.0.0.0/0
  # Optionally assign a known public LB IP
  # loadBalancerIP: 1.2.3.4
  # Optionally configure a JMX port
  # requires additional javaOpts, ie
  # javaOpts: >
  #   -Dcom.sun.management.jmxremote.port=4000
  #   -Dcom.sun.management.jmxremote.authenticate=false
  #   -Dcom.sun.management.jmxremote.ssl=false
  # jmxPort: 4000
  # Optionally configure other ports to expose in the controller container
  extraPorts: []
  # - name: BuildInfoProxy
  #   port: 9000
  #   targetPort: 9010 (Optional: Use to explicitly set targetPort if different from port)

  # List of plugins to be install during Jenkins controller start
  installPlugins:
    - kubernetes:3900.va_dce992317b_4
    - workflow-aggregator:596.v8c21c963d92d
    - git:5.0.0
    - configuration-as-code:1625.v27444588cc3d

  # Set to false to download the minimum required version of all dependencies.
  installLatestPlugins: true

  # Set to true to download latest dependencies of any plugin that is requested to have the latest version.
  installLatestSpecifiedPlugins: false

  # List of plugins to install in addition to those listed in controller.installPlugins
  additionalPlugins: []

  # Enable to initialize the Jenkins controller only once on initial installation.
  # Without this, whenever the controller gets restarted (Evicted, etc.) it will fetch plugin updates which has the potential to cause breakage.
  # Note that for this to work, `persistence.enabled` needs to be set to `true`
  initializeOnce: false

  # Enable to always override the installed plugins with the values of 'controller.installPlugins' on upgrade or redeployment.
  # overwritePlugins: true

  # Configures if plugins bundled with `controller.image` should be overwritten with the values of 'controller.installPlugins' on upgrade or redeployment.
  overwritePluginsFromImage: true

  # Configures the restrictions for naming projects. Set this key to null or empty to skip it in the default config.
  projectNamingStrategy: standard

  # Enable HTML parsing using OWASP Markup Formatter Plugin (antisamy-markup-formatter), useful with ghprb plugin.
  # The plugin is not installed by default, please update controller.installPlugins.
  enableRawHtmlMarkupFormatter: false
  # Used to approve a list of groovy functions in pipelines used the script-security plugin. Can be viewed under /scriptApproval
  scriptApproval: []
  #  - "method groovy.json.JsonSlurperClassic parseText java.lang.String"
  #  - "new groovy.json.JsonSlurperClassic"
  # List of groovy init scripts to be executed during Jenkins controller start
  initScripts: []
  #  - |
  #    print 'adding global pipeline libraries, register properties, bootstrap jobs...'

  # 'name' is a name of an existing secret in same namespace as jenkins,
  # 'keyName' is the name of one of the keys inside current secret.
  # the 'name' and 'keyName' are concatenated with a '-' in between, so for example:
  # an existing secret "secret-credentials" and a key inside it named "github-password" should be used in Jcasc as ${secret-credentials-github-password}
  # 'name' and 'keyName' must be lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-',
  # and must start and end with an alphanumeric character (e.g. 'my-name',  or '123-abc')
  # existingSecret existing secret "secret-credentials" and a key inside it named "github-username" should be used in Jcasc as ${github-username}
  # When using existingSecret no need to specify the keyName under additionalExistingSecrets.
  existingSecret:

  additionalExistingSecrets: []
  #  - name: secret-name-1
  #    keyName: username
  #  - name: secret-name-1
  #    keyName: password

  additionalSecrets: []
  #  - name: nameOfSecret
  #    value: secretText

  # Generate SecretClaim resources in order to create Kubernetes secrets from HashiCorp Vault using kube-vault-controller.
  # 'name' is name of the secret that will be created in Kubernetes. The Jenkins fullname is prepended to this value.
  # 'path' is the fully qualified path to the secret in Vault
  # 'type' is an optional Kubernetes secret type. Defaults to 'Opaque'
  # 'renew' is an optional secret renewal time in seconds
  secretClaims: []
  # - name: secretName        # required
  #   path: testPath          # required
  #   type: kubernetes.io/tls # optional
  #   renew: 60               # optional

  # Name of default cloud configuration.
  cloudName: "kubernetes"

  # Below is the implementation of Jenkins Configuration as Code.  Add a key under configScripts for each configuration area,
  # where each corresponds to a plugin or section of the UI.  Each key (prior to | character) is just a label, and can be any value.
  # Keys are only used to give the section a meaningful name.  The only restriction is they may only contain RFC 1123 \ DNS label
  # characters: lowercase letters, numbers, and hyphens.  The keys become the name of a configuration yaml file on the controller in
  # /var/jenkins_home/casc_configs (by default) and will be processed by the Configuration as Code Plugin.  The lines after each |
  # become the content of the configuration yaml file.  The first line after this is a JCasC root element, eg jenkins, credentials,
  # etc.  Best reference is https://<jenkins_url>/configuration-as-code/reference.  The example below creates a welcome message:
  JCasC:
    defaultConfig: true
    configUrls: []
    # - https://acme.org/jenkins.yaml
    # Remote URL:s for configuration files.
    configScripts: {}
    #  welcome-message: |
    #    jenkins:
    #      systemMessage: Welcome to our CI\CD server.  This Jenkins is configured and managed 'as code'.
    # Allows adding to the top-level security JCasC section. For legacy,  default the chart includes apiToken configurations
    security:
      apiToken:
        creationOfLegacyTokenEnabled: false
        tokenGenerationOnCreationEnabled: false
        usageStatisticsEnabled: true
    # Ignored if securityRealm is defined in controller.JCasC.configScripts
    securityRealm: |-
      local:
        allowsSignup: false
        enableCaptcha: false
        users:
        - id: "${chart-admin-username}"
          name: "Jenkins Admin"
          password: "${chart-admin-password}"
    # Ignored if authorizationStrategy is defined in controller.JCasC.configScripts
    authorizationStrategy: |-
      loggedInUsersCanDoAnything:
        allowAnonymousRead: false
  # Optionally specify additional init-containers
  customInitContainers: []
  # - name: custom-init
  #   image: "alpine:3.7"
  #   imagePullPolicy: Always
  #   command: [ "uname", "-a" ]

  sidecars:
    configAutoReload:
      # If enabled: true, Jenkins Configuration as Code will be reloaded on-the-fly without a reboot.  If false or not-specified,
      # jcasc changes will cause a reboot and will only be applied at the subsequent start-up.  Auto-reload uses the
      # http://<jenkins_url>/reload-configuration-as-code endpoint to reapply config when changes to the configScripts are detected.
      enabled: true
      image: kiwigrid/k8s-sidecar:1.23.1
      imagePullPolicy: IfNotPresent
      resources: {}
        #   limits:
        #     cpu: 100m
        #     memory: 100Mi
        #   requests:
        #     cpu: 50m
        #     memory: 50Mi
      # How many connection-related errors to retry on
      reqRetryConnect: 10
      # env:
      #   - name: REQ_TIMEOUT
      #     value: "30"
      # SSH port value can be set to any unused TCP port.  The default, 1044, is a non-standard SSH port that has been chosen at random.
      # Is only used to reload jcasc config from the sidecar container running in the Jenkins controller pod.
      # This TCP port will not be open in the pod (unless you specifically configure this), so Jenkins will not be
      # accessible via SSH from outside of the pod.  Note if you use non-root pod privileges (runAsUser & fsGroup),
      # this must be > 1024:
      sshTcpPort: 1044
      # folder in the pod that should hold the collected dashboards:
      folder: "/var/jenkins_home/casc_configs"
      # If specified, the sidecar will search for JCasC config-maps inside this namespace.
      # Otherwise the namespace in which the sidecar is running will be used.
      # It's also possible to specify ALL to search in all namespaces:
      # searchNamespace:
      containerSecurityContext:
        readOnlyRootFilesystem: true
        allowPrivilegeEscalation: false

    # Allows you to inject additional/other sidecars
    other: []
    ## The example below runs the client for https://smee.io as sidecar container next to Jenkins,
    ## that allows to trigger build behind a secure firewall.
    ## https://jenkins.io/blog/2019/01/07/webhook-firewalls/#triggering-builds-with-webhooks-behind-a-secure-firewall
    ##
    ## Note: To use it you should go to https://smee.io/new and update the url to the generete one.
    # - name: smee
    #   image: docker.io/twalter/smee-client:1.0.2
    #   args: ["--port", "{{ .Values.controller.servicePort }}", "--path", "/github-webhook/", "--url", "https://smee.io/new"]
    #   resources:
    #     limits:
    #       cpu: 50m
    #       memory: 128Mi
    #     requests:
    #       cpu: 10m
    #       memory: 32Mi
  # Name of the Kubernetes scheduler to use
  schedulerName: ""
  # Node labels and tolerations for pod assignment
  # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
  # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
  nodeSelector: {}

  terminationGracePeriodSeconds:

  terminationMessagePath:
  terminationMessagePolicy:

  tolerations: []

  affinity: {}
  # Leverage a priorityClass to ensure your pods survive resource shortages
  # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
  priorityClassName:

  podAnnotations: {}
  # Add StatefulSet annotations
  statefulSetAnnotations: {}

  # StatefulSet updateStrategy
  # ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies
  updateStrategy: {}

  ingress:
    enabled: false
    # Override for the default paths that map requests to the backend
    paths: []
    # - backend:
    #     serviceName: ssl-redirect
    #     servicePort: use-annotation
    # - backend:
    #     serviceName: >-
    #       {{ template "jenkins.fullname" . }}
    #     # Don't use string here, use only integer value!
    #     servicePort: 8080
    # For Kubernetes v1.14+, use 'networking.k8s.io/v1beta1'
    # For Kubernetes v1.19+, use 'networking.k8s.io/v1'
    apiVersion: "extensions/v1beta1"
    labels: {}
    annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
    # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
    # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
    # ingressClassName: nginx
    # Set this path to jenkinsUriPrefix above or use annotations to rewrite path
    # path: "/jenkins"
    # configures the hostname e.g. jenkins.example.com
    hostName:
    tls:
    # - secretName: jenkins.cluster.local
    #   hosts:
    #     - jenkins.cluster.local

  # often you want to have your controller all locked down and private
  # but you still want to get webhooks from your SCM
  # A secondary ingress will let you expose different urls
  # with a differnt configuration
  secondaryingress:
    enabled: false
    # paths you want forwarded to the backend
    # ex /github-webhook
    paths: []
    # For Kubernetes v1.14+, use 'networking.k8s.io/v1beta1'
    # For Kubernetes v1.19+, use 'networking.k8s.io/v1'
    apiVersion: "extensions/v1beta1"
    labels: {}
    annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
    # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
    # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
    # ingressClassName: nginx
    # configures the hostname e.g. jenkins-external.example.com
    hostName:
    tls:
    # - secretName: jenkins-external.example.com
    #   hosts:
    #     - jenkins-external.example.com

  # If you're running on GKE and need to configure a backendconfig
  # to finish ingress setup, use the following values.
  # Docs: https://cloud.google.com/kubernetes-engine/docs/concepts/backendconfig
  backendconfig:
    enabled: false
    apiVersion: "extensions/v1beta1"
    name:
    labels: {}
    annotations: {}
    spec: {}

  # Openshift route
  route:
    enabled: false
    labels: {}
    annotations: {}
    # path: "/jenkins"

  # controller.hostAliases allows for adding entries to Pod /etc/hosts:
  # https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/
  hostAliases: []
  # - ip: 192.168.50.50
  #   hostnames:
  #     - something.local
  # - ip: 10.0.50.50
  #   hostnames:
  #     - other.local

  # Expose Prometheus metrics
  prometheus:
    # If enabled, add the prometheus plugin to the list of plugins to install
    # https://plugins.jenkins.io/prometheus
    enabled: false
    # Additional labels to add to the ServiceMonitor object
    serviceMonitorAdditionalLabels: {}
    # Set a custom namespace where to deploy ServiceMonitor resource
    # serviceMonitorNamespace: monitoring
    scrapeInterval: 60s
    # This is the default endpoint used by the prometheus plugin
    scrapeEndpoint: /prometheus
    # Additional labels to add to the PrometheusRule object
    alertingRulesAdditionalLabels: {}
    # An array of prometheus alerting rules
    # See here: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
    # The `groups` root object is added by default, simply add the rule entries
    alertingrules: []
    # Set a custom namespace where to deploy PrometheusRule resource
    prometheusRuleNamespace: ""

    # RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds
    # relabelings for a few standard Kubernetes fields. The original scrape job’s name
    # is available via the __tmp_prometheus_job_name label.
    # More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
    relabelings: []
    # MetricRelabelConfigs to apply to samples before ingestion.
    metricRelabelings: []

  googlePodMonitor:
    # If enabled, It creates Google Managed Prometheus scraping config
    enabled: false
    # Set a custom namespace where to deploy PodMonitoring resource
    # serviceMonitorNamespace: ""
    scrapeInterval: 60s
    # This is the default endpoint used by the prometheus plugin
    scrapeEndpoint: /prometheus

  # Can be used to disable rendering controller test resources when using helm template
  testEnabled: true

  httpsKeyStore:
    jenkinsHttpsJksSecretName: ''
    enable: false
    disableSecretMount: false
    httpPort: 8081
    path: "/var/jenkins_keystore"
    fileName: "keystore.jks"
    password: "password"
    # Convert keystore.jks files content to base64 ( cat keystore.jks | base64 ) and put the output here
    jenkinsKeyStoreBase64Encoded: |
        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

agent:
  enabled: true
  defaultsProviderTemplate: ""
  # URL for connecting to the Jenkins controller
  jenkinsUrl:
  # connect to the specified host and port, instead of connecting directly to the Jenkins controller
  jenkinsTunnel:
  kubernetesConnectTimeout: 5
  kubernetesReadTimeout: 15
  maxRequestsPerHostStr: "32"
  namespace:
  image: "jenkins/inbound-agent"
  tag: "3107.v665000b_51092-5"
  workingDir: "/home/jenkins/agent"
  nodeUsageMode: "NORMAL"
  customJenkinsLabels: []
  # name of the secret to be used for image pulling
  imagePullSecretName:
  componentName: "jenkins-agent"
  websocket: false
  directConnection: false
  privileged: false
  runAsUser:
  runAsGroup:
  hostNetworking: false
  resources:
    requests:
      cpu: "512m"
      memory: "512Mi"
    limits:
      cpu: "512m"
      memory: "512Mi"
  # You may want to change this to true while testing a new image
  alwaysPullImage: false
  # Controls how agent pods are retained after the Jenkins build completes
  # Possible values: Always, Never, OnFailure
  podRetention: "Never"
  # Disable if you do not want the Yaml the agent pod template to show up
  # in the job Console Output. This can be helpful for either security reasons
  # or simply to clean up the output to make it easier to read.
  showRawYaml: true
  # You can define the volumes that you want to mount for this container
  # Allowed types are: ConfigMap, EmptyDir, HostPath, Nfs, PVC, Secret
  # Configure the attributes as they appear in the corresponding Java class for that type
  # https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes
  volumes: []
  # - type: ConfigMap
  #   configMapName: myconfigmap
  #   mountPath: /var/myapp/myconfigmap
  # - type: EmptyDir
  #   mountPath: /var/myapp/myemptydir
  #   memory: false
  # - type: HostPath
  #   hostPath: /var/lib/containers
  #   mountPath: /var/myapp/myhostpath
  # - type: Nfs
  #   mountPath: /var/myapp/mynfs
  #   readOnly: false
  #   serverAddress: "192.0.2.0"
  #   serverPath: /var/lib/containers
  # - type: PVC
  #   claimName: mypvc
  #   mountPath: /var/myapp/mypvc
  #   readOnly: false
  # - type: Secret
  #   defaultMode: "600"
  #   mountPath: /var/myapp/mysecret
  #   secretName: mysecret
  # Pod-wide environment, these vars are visible to any container in the agent pod

  # You can define the workspaceVolume that you want to mount for this container
  # Allowed types are: DynamicPVC, EmptyDir, HostPath, Nfs, PVC
  # Configure the attributes as they appear in the corresponding Java class for that type
  # https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace
  workspaceVolume: {}
  ## DynamicPVC example
  # type: DynamicPVC
  # configMapName: myconfigmap
  ## EmptyDir example
  # type: EmptyDir
  # memory: false
  ## HostPath example
  # type: HostPath
  # hostPath: /var/lib/containers
  ## NFS example
  # type: Nfs
  # readOnly: false
  # serverAddress: "192.0.2.0"
  # serverPath: /var/lib/containers
  ## PVC example
  # type: PVC
  # claimName: mypvc
  # readOnly: false
  #
  # Pod-wide environment, these vars are visible to any container in the agent pod
  envVars: []
  # - name: PATH
  #   value: /usr/local/bin
  # Mount a secret as environment variable
  secretEnvVars: []
  # - key: PATH
  #   optional: false # default: false
  #   secretKey: MY-K8S-PATH
  #   secretName: my-k8s-secret
  nodeSelector: {}
  # Key Value selectors. Ex:
  # jenkins-agent: v1

  # Executed command when side container gets started
  command:
  args: "${computer.jnlpmac} ${computer.name}"
  # Side container name
  sideContainerName: "jnlp"
  # Doesn't allocate pseudo TTY by default
  TTYEnabled: false
  # Max number of spawned agent
  containerCap: 10
  # Pod name
  podName: "default"
  # Allows the Pod to remain active for reuse until the configured number of
  # minutes has passed since the last step was executed on it.
  idleMinutes: 0
  # Raw yaml template for the Pod. For example this allows usage of toleration for agent pods.
  # https://github.com/jenkinsci/kubernetes-plugin#using-yaml-to-define-pod-templates
  # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
  yamlTemplate: ""
  # yamlTemplate: |-
  #   apiVersion: v1
  #   kind: Pod
  #   spec:
  #     tolerations:
  #     - key: "key"
  #       operator: "Equal"
  #       value: "value"
  # Defines how the raw yaml field gets merged with yaml definitions from inherited pod templates: merge or override
  yamlMergeStrategy: "override"
  # Timeout in seconds for an agent to be online
  connectTimeout: 100
  # Annotations to apply to the pod.
  annotations: {}

  # Add additional containers to the agents.
  # Containers specified here are added to all agents. Set key empty to remove container from additional agents.
  additionalContainers: []
  #  - sideContainerName: dind
  #    image: docker
  #    tag: dind
  #    command: dockerd-entrypoint.sh
  #    args: ""
  #    privileged: true
  #    resources:
  #      requests:
  #        cpu: 500m
  #        memory: 1Gi
  #      limits:
  #        cpu: 1
  #        memory: 2Gi

  # Disable the default Jenkins Agent configuration.
  # Useful when configuring agents only with the podTemplates value, since the default podTemplate populated by values mentioned above will be excluded in the rendered template.
  disableDefaultAgent: false

  # Below is the implementation of custom pod templates for the default configured kubernetes cloud.
  # Add a key under podTemplates for each pod template. Each key (prior to | character) is just a label, and can be any value.
  # Keys are only used to give the pod template a meaningful name.  The only restriction is they may only contain RFC 1123 \ DNS label
  # characters: lowercase letters, numbers, and hyphens. Each pod template can contain multiple containers.
  # For this pod templates configuration to be loaded the following values must be set:
  # controller.JCasC.defaultConfig: true
  # Best reference is https://<jenkins_url>/configuration-as-code/reference#Cloud-kubernetes. The example below creates a python pod template.
  podTemplates: {}
  #  python: |
  #    - name: python
  #      label: jenkins-python
  #      serviceAccount: jenkins
  #      containers:
  #        - name: python
  #          image: python:3
  #          command: "/bin/sh -c"
  #          args: "cat"
  #          ttyEnabled: true
  #          privileged: true
  #          resourceRequestCpu: "400m"
  #          resourceRequestMemory: "512Mi"
  #          resourceLimitCpu: "1"
  #          resourceLimitMemory: "1024Mi"

# Here you can add additional agents
# They inherit all values from `agent` so you only need to specify values which differ
additionalAgents: {}
#  maven:
#    podName: maven
#    customJenkinsLabels: maven
#    # An example of overriding the jnlp container
#    # sideContainerName: jnlp
#    image: jenkins/jnlp-agent-maven
#    tag: latest
#  python:
#    podName: python
#    customJenkinsLabels: python
#    sideContainerName: python
#    image: python
#    tag: "3"
#    command: "/bin/sh -c"
#    args: "cat"
#    TTYEnabled: true

persistence:
  enabled: true
  ## A manually managed Persistent Volume and Claim
  ## Requires persistence.enabled: true
  ## If defined, PVC must be created manually before volume will be bound
  existingClaim:
  ## jenkins data Persistent Volume Storage Class
  ## If defined, storageClassName: <storageClass>
  ## If set to "-", storageClassName: "", which disables dynamic provisioning
  ## If undefined (the default) or set to null, no storageClassName spec is
  ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
  ##   GKE, AWS & OpenStack)
  ##
  storageClass:
  annotations: {}
  labels: {}
  accessMode: "ReadWriteOnce"
  size: "8Gi"
  volumes:
  #  - name: nothing
  #    emptyDir: {}
  mounts:
  #  - mountPath: /var/nothing
  #    name: nothing
  #    readOnly: true

networkPolicy:
  # Enable creation of NetworkPolicy resources.
  enabled: false
  # For Kubernetes v1.4, v1.5 and v1.6, use 'extensions/v1beta1'
  # For Kubernetes v1.7, use 'networking.k8s.io/v1'
  apiVersion: networking.k8s.io/v1
  # You can allow agents to connect from both within the cluster (from within specific/all namespaces) AND/OR from a given external IP range
  internalAgents:
    allowed: true
    podLabels: {}
    namespaceLabels: {}
      # project: myproject
  externalAgents: {}
  #   ipCIDR: 172.17.0.0/16
  #   except:
  #     - 172.17.1.0/24

## Install Default RBAC roles and bindings
rbac:
  create: true
  readSecrets: false

serviceAccount:
  create: true
  # The name of the service account is autogenerated by default
  name:
  annotations: {}
  extraLabels: {}
  imagePullSecretName:


serviceAccountAgent:
  # Specifies whether a ServiceAccount should be created
  create: false
  # The name of the ServiceAccount to use.
  # If not set and create is true, a name is generated using the fullname template
  name:
  annotations: {}
  extraLabels: {}
  imagePullSecretName:

## Backup cronjob configuration
## Ref: https://github.com/maorfr/kube-tasks
backup:
  # Backup must use RBAC
  # So by enabling backup you are enabling RBAC specific for backup
  enabled: false
  # Used for label app.kubernetes.io/component
  componentName: "backup"
  # Schedule to run jobs. Must be in cron time format
  # Ref: https://crontab.guru/
  schedule: "0 2 * * *"
  labels: {}
  serviceAccount:
    create: true
    name:
    annotations: {}
    # Example for authorization to AWS S3 using kube2iam or IRSA
    # Can also be done using environment variables
    # iam.amazonaws.com/role: "jenkins"
    # "eks.amazonaws.com/role-arn": "arn:aws:iam::123456789012:role/jenkins-backup"
  # Set this to terminate the job that is running/failing continously and set the job status to "Failed"
  activeDeadlineSeconds: ""
  image:
    repository: "maorfr/kube-tasks"
    tag: "0.2.0"
  imagePullSecretName:
  # Additional arguments for kube-tasks
  # Ref: https://github.com/maorfr/kube-tasks#simple-backup
  extraArgs: []
  # Add existingSecret for AWS credentials
  existingSecret: {}
  ## Example for using an existing secret
   # jenkinsaws:
  ## Use this key for AWS access key ID
     # awsaccesskey: jenkins_aws_access_key
  ## Use this key for AWS secret access key
     # awssecretkey: jenkins_aws_secret_key
  # Add additional environment variables
   # jenkinsgcp:
  ## Use this key for GCP credentials
     # gcpcredentials: credentials.json
  env: []
  # Example environment variable required for AWS credentials chain
  # - name: "AWS_REGION"
  #   value: "us-east-1"
  resources:
    requests:
      memory: 1Gi
      cpu: 1
    limits:
      memory: 1Gi
      cpu: 1
  # Destination to store the backup artifacts
  # Supported cloud storage services: AWS S3, Minio S3, Azure Blob Storage, Google Cloud Storage
  # Additional support can added. Visit this repository for details
  # Ref: https://github.com/maorfr/skbn
  destination: "s3://jenkins-data/backup"
  # By enabling only the jenkins_home/jobs folder gets backed up, not the whole jenkins instance
  onlyJobs: false
  # Enable backup pod security context (must be `true` if runAsUser or fsGroup are set)
  usePodSecurityContext: true
  # When setting runAsUser to a different value than 0 also set fsGroup to the same value:
  runAsUser: 1000
  fsGroup: 1000
  securityContextCapabilities: {}
  #  drop:
  #    - NET_RAW
cronJob:
  apiVersion: batch/v1

checkDeprecation: true

awsSecurityGroupPolicies:
  enabled: false
  policies:
    - name: ""
      securityGroupIds: []
      podSelector: {}

# Here you can configure unit tests values when executing the helm unittest in the CONTRIBUTING.md
helmtest:
  # A testing framework for bash
  bats:
    # Bash Automated Testing System (BATS)
    image: "bats/bats"
    tag: "1.9.0"

  • chart

    $ helm show chart jenkins/jenkins
    annotations:
      artifacthub.io/category: integration-delivery
      artifacthub.io/images: |
        - name: jenkins
          image: jenkins/jenkins:2.401.2-jdk11
        - name: k8s-sidecar
          image: kiwigrid/k8s-sidecar:1.24.4
        - name: inbound-agent
          image: jenkins/inbound-agent:3107.v665000b_51092-15
        - name: backup
          image: maorfr/kube-tasks:0.2.0
      artifacthub.io/license: Apache-2.0
      artifacthub.io/links: |
        - name: Chart Source
          url: https://github.com/jenkinsci/helm-charts/tree/main/charts/jenkins
        - name: Jenkins
          url: https://www.jenkins.io/
        - name: support
          url: https://github.com/jenkinsci/helm-charts/issues
    apiVersion: v2
    appVersion: 2.401.2
    description: Jenkins - Build great things at any scale! The leading open source automation
      server, Jenkins provides hundreds of plugins to support building, deploying and
      automating any project.
    home: https://jenkins.io/
    icon: https://get.jenkins.io/art/jenkins-logo/logo.svg
    keywords:
    - jenkins
    - ci
    - devops
    maintainers:
    - email: maor.friedman@redhat.com
      name: maorfr
    - email: mail@torstenwalter.de
      name: torstenwalter
    - email: garridomota@gmail.com
      name: mogaal
    - email: wmcdona89@gmail.com
      name: wmcdona89
    - email: timjacomb1@gmail.com
      name: timja
    name: jenkins
    sources:
    - https://github.com/jenkinsci/jenkins
    - https://github.com/jenkinsci/docker-inbound-agent
    - https://github.com/maorfr/kube-tasks
    - https://github.com/jenkinsci/configuration-as-code-plugin
    version: 4.4.1
  • values

    $ helm show values jenkins/jenkins

install with tolerations

[!NOTE|label:references:]

history

# get RELEASE_NAME
$ helm list
NAME            NAMESPACE  REVISION  UPDATED                                 STATUS    CHART         APP VERSION
staging-jenkins devops  11        2023-09-27 23:39:38.982931215 -0700 PDT deployed  jenkins-4.5.0 2.401.3

# get history
$ helm history staging-jenkins
REVISION  UPDATED                   STATUS      CHART         APP VERSION DESCRIPTION
2         Wed Sep 27 19:20:35 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
3         Wed Sep 27 20:18:10 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
4         Wed Sep 27 21:16:24 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
5         Wed Sep 27 21:18:01 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
6         Wed Sep 27 21:22:02 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
7         Wed Sep 27 21:31:07 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
8         Wed Sep 27 21:32:55 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
9         Wed Sep 27 21:35:42 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
10        Wed Sep 27 23:02:57 2023  superseded  jenkins-4.5.0 2.401.3     Upgrade complete
11        Wed Sep 27 23:39:38 2023  deployed    jenkins-4.5.0 2.401.3     Upgrade complete

status

# get RELEASE_NAME
$ helm list
NAME            NAMESPACE  REVISION  UPDATED                                 STATUS    CHART         APP VERSION
staging-jenkins devops     11        2023-09-27 23:39:38.982931215 -0700 PDT deployed  jenkins-4.5.0 2.401.3

# get status
$ helm status staging-jenkins
NAME: staging-jenkins
LAST DEPLOYED: Wed Sep 27 23:39:38 2023
NAMESPACE: devops
STATUS: deployed
REVISION: 11
NOTES:
1. Get your 'admin' user password by running:
  kubectl exec --namespace devops -it svc/staging-jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo
2. Get the Jenkins URL to visit by running these commands in the same shell:
  echo http://127.0.0.1:8080
  kubectl --namespace devops port-forward svc/staging-jenkins 8080:8080

3. Login with the password from step 1 and the username: admin
4. Configure security realm and authorization strategy
5. Use Jenkins Configuration as Code by specifying configScripts in your values.yaml file, see documentation: http://127.0.0.1:8080/configuration-as-code and examples: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos

For more information on running Jenkins on Kubernetes, visit:
https://cloud.google.com/solutions/jenkins-on-container-engine

For more information about Jenkins Configuration as Code, visit:
https://jenkins.io/projects/jcasc/

NOTE: Consider using a custom image with pre-installed plugins

get

get all

# get RELEASE_NAME
$ helm list
NAME            NAMESPACE  REVISION  UPDATED                                 STATUS    CHART         APP VERSION
staging-jenkins devops  11        2023-09-27 23:39:38.982931215 -0700 PDT deployed  jenkins-4.5.0 2.401.3

# get all including yaml
$ helm get all staging-jenkins

others

HELM VERSIONSUPPORTED KUBERNETES VERSIONS

3.11.x

1.26.x - 1.23.x

3.10.x

1.25.x - 1.22.x

3.9.x

1.24.x - 1.21.x

3.8.x

1.23.x - 1.20.x

3.7.x

1.22.x - 1.19.x

3.6.x

1.21.x - 1.18.x

3.5.x

1.20.x - 1.17.x

3.4.x

1.19.x - 1.16.x

3.3.x

1.18.x - 1.15.x

3.2.x

1.18.x - 1.15.x

3.1.x

1.17.x - 1.14.x

3.0.x

1.16.x - 1.13.x

2.16.x

1.16.x - 1.15.x

2.15.x

1.15.x - 1.14.x

2.14.x

1.14.x - 1.13.x

2.13.x

1.13.x - 1.12.x

2.12.x

1.12.x - 1.11.x

2.11.x

1.11.x - 1.10.x

2.10.x

1.10.x - 1.9.x

2.9.x

1.10.x - 1.9.x

2.8.x

1.9.x - 1.8.x

2.7.x

1.8.x - 1.7.x

2.6.x

1.7.x - 1.6.x

2.5.x

1.6.x - 1.5.x

2.4.x

1.6.x - 1.5.x

2.3.x

1.5.x - 1.4.x

2.2.x

1.5.x - 1.4.x

2.1.x

1.5.x - 1.4.x

2.0.x

1.4.x - 1.3.x

Last updated