blob: 4ddd1faa43d80063871cd7057b3588b3ae705e26 [file] [log] [blame] [view]
Giorgi Lekveishvili35982662024-04-05 13:05:40 +04001# Jenkins
2
3[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/jenkins)](https://artifacthub.io/packages/helm/jenkinsci/jenkins)
4[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
5[![Releases downloads](https://img.shields.io/github/downloads/jenkinsci/helm-charts/total.svg)](https://github.com/jenkinsci/helm-charts/releases)
6[![Join the chat at https://app.gitter.im/#/room/#jenkins-ci:matrix.org](https://badges.gitter.im/badge.svg)](https://app.gitter.im/#/room/#jenkins-ci:matrix.org)
7
8[Jenkins](https://www.jenkins.io/) is the leading open source automation server, Jenkins provides over 1800 plugins to support building, deploying and automating any project.
9
10This chart installs a Jenkins server which spawns agents on [Kubernetes](http://kubernetes.io) utilizing the [Jenkins Kubernetes plugin](https://plugins.jenkins.io/kubernetes/).
11
12Inspired by the awesome work of [Carlos Sanchez](https://github.com/carlossg).
13
14## Get Repository Info
15
16```console
17helm repo add jenkins https://charts.jenkins.io
18helm repo update
19```
20
21_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._
22
23## Install Chart
24
25```console
26# Helm 3
27$ helm install [RELEASE_NAME] jenkins/jenkins [flags]
28```
29
30_See [configuration](#configuration) below._
31
32_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._
33
34## Uninstall Chart
35
36```console
37# Helm 3
38$ helm uninstall [RELEASE_NAME]
39```
40
41This removes all the Kubernetes components associated with the chart and deletes the release.
42
43_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._
44
45## Upgrade Chart
46
47```console
48# Helm 3
49$ helm upgrade [RELEASE_NAME] jenkins/jenkins [flags]
50```
51
52_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._
53
54Visit the chart's [CHANGELOG](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/CHANGELOG.md) to view the chart's release history.
55For migration between major version check [migration guide](#migration-guide).
56
57## Building weekly releases
58
59The default charts target Long-Term-Support (LTS) releases of Jenkins.
60To use other versions the easiest way is to update the image tag to the version you want.
61You can also rebuild the chart if you want the `appVersion` field to match.
62
63## Configuration
64
65See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing).
66To see all configurable options with detailed comments, visit the chart's [values.yaml](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/values.yaml), or run these configuration commands:
67
68```console
69# Helm 3
70$ helm show values jenkins/jenkins
71```
72
73For a summary of all configurable options, see [VALUES_SUMMARY.md](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md).
74
75### Configure Security Realm and Authorization Strategy
76
77This chart configured a `securityRealm` and `authorizationStrategy` as shown below:
78
79```yaml
80controller:
81 JCasC:
82 securityRealm: |-
83 local:
84 allowsSignup: false
85 enableCaptcha: false
86 users:
87 - id: "${chart-admin-username}"
88 name: "Jenkins Admin"
89 password: "${chart-admin-password}"
90 authorizationStrategy: |-
91 loggedInUsersCanDoAnything:
92 allowAnonymousRead: false
93```
94
95With the configuration above there is only a single user.
96This is fine for getting started quickly, but it needs to be adjusted for any serious environment.
97
98So you should adjust this to suite your needs.
99That could be using LDAP / OIDC / .. as authorization strategy and use globalMatrix as authorization strategy to configure more fine-grained permissions.
100
101### Consider using a custom image
102
103This chart allows the user to specify plugins which should be installed. However, for production use cases one should consider to build a custom Jenkins image which has all required plugins pre-installed.
104This way you can be sure which plugins Jenkins is using when starting up and you avoid trouble in case of connectivity issues to the Jenkins update site.
105
106The [docker repository](https://github.com/jenkinsci/docker) for the Jenkins image contains [documentation](https://github.com/jenkinsci/docker#preinstalling-plugins) how to do it.
107
108Here is an example how that can be done:
109
110```Dockerfile
111FROM jenkins/jenkins:lts
112RUN jenkins-plugin-cli --plugins kubernetes workflow-aggregator git configuration-as-code
113```
114
115NOTE: If you want a reproducible build then you should specify a non-floating tag for the image `jenkins/jenkins:2.249.3` and specify plugin versions.
116
117Once you built the image and pushed it to your registry you can specify it in your values file like this:
118
119```yaml
120controller:
121 image: "registry/my-jenkins"
122 tag: "v1.2.3"
123 installPlugins: false
124```
125
126Notice: `installPlugins` is set to false to disable plugin download. In this case, the image `registry/my-jenkins:v1.2.3` must have the plugins specified as default value for [the `controller.installPlugins` directive](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-plugins) to ensure that the configuration side-car system works as expected.
127
128In case you are using a private registry you can use 'imagePullSecretName' to specify the name of the secret to use when pulling the image:
129
130```yaml
131controller:
132 image: "registry/my-jenkins"
133 tag: "v1.2.3"
134 imagePullSecretName: registry-secret
135 installPlugins: false
136```
137
138### External URL Configuration
139
140If 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.
141The Protocol can be overwritten by specifying `controller.jenkinsUrlProtocol`.
142
143If you are not using the provided ingress you can specify `controller.jenkinsUrl` to change the URL definition.
144
145### Configuration as Code
146
147Jenkins Configuration as Code (JCasC) is now a standard component in the Jenkins project.
148To allow JCasC's configuration from the helm values, the plugin [`configuration-as-code`](https://plugins.jenkins.io/configuration-as-code/) must be installed in the Jenkins Controller's Docker image (which is the case by default as specified by the [default value of the directive `controller.installPlugins`](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-plugins)).
149
150JCasc configuration is passed through Helm values under the key `controller.JCasC`.
151The section ["Jenkins Configuration as Code (JCasC)" of the page "VALUES_SUMMARY.md"](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-configuration-as-code-jcasc) lists all the possible directives.
152
153In particular, you may specify custom JCasC scripts by adding sub-key under the `controller.JCasC.configScripts` for each configuration area where each corresponds to a plugin or section of the UI.
154
155The sub-keys (prior to `|` character) are only labels used to give the section a meaningful name.
156The only restriction is they must conform to RFC 1123 definition of a DNS label, so they may only contain lowercase letters, numbers, and hyphens.
157
158Each key will 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 during Jenkins startup.
159
160The lines after each `|` become the content of the configuration yaml file.
161
162The first line after this is a JCasC root element, e.g. jenkins, credentials, etc.
163
164Best reference is the Documentation link here: `https://<jenkins_url>/configuration-as-code`.
165
166The example below sets custom systemMessage:
167
168```yaml
169controller:
170 JCasC:
171 configScripts:
172 welcome-message: |
173 jenkins:
174 systemMessage: Welcome to our CI\CD server.
175```
176
177More complex example that creates ldap settings:
178
179```yaml
180controller:
181 JCasC:
182 configScripts:
183 ldap-settings: |
184 jenkins:
185 securityRealm:
186 ldap:
187 configurations:
188 - server: ldap.acme.com
189 rootDN: dc=acme,dc=uk
190 managerPasswordSecret: ${LDAP_PASSWORD}
191 groupMembershipStrategy:
192 fromUserRecord:
193 attributeName: "memberOf"
194```
195
196Keep in mind that default configuration file already contains some values that you won't be able to override under configScripts section.
197
198For example, you can not configure Jenkins URL and System Admin email address like this because of conflicting configuration error.
199
200Incorrect:
201
202```yaml
203controller:
204 JCasC:
205 configScripts:
206 jenkins-url: |
207 unclassified:
208 location:
209 url: https://example.com/jenkins
210 adminAddress: example@mail.com
211```
212
213Correct:
214
215```yaml
216controller:
217 jenkinsUrl: https://example.com/jenkins
218 jenkinsAdminEmail: example@mail.com
219```
220
221Further JCasC examples can be found [here](https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos).
222
223#### Breaking out large Config as Code scripts
224
225Jenkins Config as Code scripts can become quite large, and maintaining all of your scripts within one yaml file can be difficult. The Config as Code plugin itself suggests updating the `CASC_JENKINS_CONFIG` environment variable to be a comma separated list of paths for the plugin to traverse, picking up the yaml files as needed.
226However, under the Jenkins helm chart, this `CASC_JENKINS_CONFIG` value is maintained through the templates. A better solution is to split your `controller.JCasC.configScripts` into separate values files, and provide each file during the helm install.
227
228For example, you can have a values file (e.g values_main.yaml) that defines the values described in the `VALUES_SUMMARY.md` for your Jenkins configuration:
229
230```yaml
231jenkins:
232 controller:
233 jenkinsUrlProtocol: https
234 installPlugins: false
235 ...
236```
237
238In a second file (e.g values_jenkins_casc.yaml), you can define a section of your config scripts:
239
240```yaml
241jenkins:
242 controller:
243 JCasC:
244 configScripts:
245 jenkinsCasc: |
246 jenkins:
247 disableRememberMe: false
248 mode: NORMAL
249 ...
250```
251
252And keep extending your config scripts by creating more files (so not all config scripts are located in one yaml file for better maintenance):
253
254values_jenkins_unclassified.yaml
255
256```yaml
257jenkins:
258 controller:
259 JCasC:
260 configScripts:
261 unclassifiedCasc: |
262 unclassified:
263 ...
264```
265
266When installing, you provide all relevant yaml files (e.g `helm install -f values_main.yaml -f values_jenkins_casc.yaml -f values_jenkins_unclassified.yaml ...`). Instead of updating the `CASC_JENKINS_CONFIG` environment variable to include multiple paths, multiple CasC yaml files will be created in the same path `var/jenkins_home/casc_configs`.
267
268#### Config as Code With or Without Auto-Reload
269
270Config as Code changes (to `controller.JCasC.configScripts`) can either force a new pod to be created and only be applied at next startup, or can be auto-reloaded on-the-fly.
271If you set `controller.sidecars.configAutoReload.enabled` to `true`, a second, auxiliary container will be installed into the Jenkins controller pod, known as a "sidecar".
272This watches for changes to configScripts, copies the content onto the Jenkins file-system and issues a POST to `http://<jenkins_url>/reload-configuration-as-code` with a pre-shared key.
273You can monitor this sidecar's logs using command `kubectl logs <controller_pod> -c config-reload -f`.
274If you want to enable auto-reload then you also need to configure rbac as the container which triggers the reload needs to watch the config maps:
275
276```yaml
277controller:
278 sidecars:
279 configAutoReload:
280 enabled: true
281rbac:
282 create: true
283```
284
285### Allow Limited HTML Markup in User-Submitted Text
286
287Some third-party systems (e.g. GitHub) use HTML-formatted data in their payload sent to a Jenkins webhook (e.g. URL of a pull-request being built).
288To display such data as processed HTML instead of raw text set `controller.enableRawHtmlMarkupFormatter` to true.
289This option requires installation of the [OWASP Markup Formatter Plugin (antisamy-markup-formatter)](https://plugins.jenkins.io/antisamy-markup-formatter/).
290This plugin is **not** installed by default but may be added to `controller.additionalPlugins`.
291
292### Change max connections to Kubernetes API
293When using agents with containers other than JNLP, The kubernetes plugin will communicate with those containers using the Kubernetes API. this changes the maximum concurrent connections
294```yaml
295agent:
296 maxRequestsPerHostStr: "32"
297```
298This will change the configuration of the kubernetes "cloud" (as called by jenkins) that is created automatically as part of this helm chart.
299
300### Change container cleanup timeout API
301For tasks that use very large images, this timeout can be increased to avoid early termination of the task while the Kubernetes pod is still deploying.
302```yaml
303agent:
304 retentionTimeout: "32"
305```
306This will change the configuration of the kubernetes "cloud" (as called by jenkins) that is created automatically as part of this helm chart.
307
308### Change seconds to wait for pod to be running
309This will change how long Jenkins will wait (seconds) for pod to be in running state.
310```yaml
311agent:
312 waitForPodSec: "32"
313```
314This will change the configuration of the kubernetes "cloud" (as called by jenkins) that is created automatically as part of this helm chart.
315
316### Mounting Volumes into Agent Pods
317
318Your Jenkins Agents will run as pods, and it's possible to inject volumes where needed:
319
320```yaml
321agent:
322 volumes:
323 - type: Secret
324 secretName: jenkins-mysecrets
325 mountPath: /var/run/secrets/jenkins-mysecrets
326```
327
328The supported volume types are: `ConfigMap`, `EmptyDir`, `HostPath`, `Nfs`, `PVC`, `Secret`.
329Each type supports a different set of configurable attributes, defined by [the corresponding Java class](https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes).
330
331### NetworkPolicy
332
333To make use of the NetworkPolicy resources created by default, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin).
334
335[Install](#install-chart) helm chart with network policy enabled by setting `networkPolicy.enabled` to `true`.
336
337You can use `controller.networkPolicy.internalAgents` and `controller.networkPolicy.externalAgents` stanzas for fine-grained controls over where internal/external agents can connect from.
338Internal ones are allowed based on pod labels and (optionally) namespaces, and external ones are allowed based on IP ranges.
339
340### Script approval list
341
342`controller.scriptApproval` allows to pass function signatures that will be allowed in pipelines.
343Example:
344
345```yaml
346controller:
347 scriptApproval:
348 - "method java.util.Base64$Decoder decode java.lang.String"
349 - "new java.lang.String byte[]"
350 - "staticMethod java.util.Base64 getDecoder"
351```
352
353### Custom Labels
354
355`controller.serviceLabels` can be used to add custom labels in `jenkins-controller-svc.yaml`.
356For example:
357
358```yaml
359ServiceLabels:
360 expose: true
361```
362
363### Persistence
364
365The Jenkins image stores persistence under `/var/jenkins_home` path of the container.
366A dynamically managed Persistent Volume Claim is used to keep the data across deployments, by default.
367This is known to work in GCE, AWS, and minikube. Alternatively, a previously configured Persistent Volume Claim can be used.
368
369It is possible to mount several volumes using `persistence.volumes` and `persistence.mounts` parameters.
370See additional `persistence` values using [configuration commands](#configuration).
371
372#### Existing PersistentVolumeClaim
373
3741. Create the PersistentVolume
3752. Create the PersistentVolumeClaim
3763. [Install](#install-chart) the chart, setting `persistence.existingClaim` to `PVC_NAME`
377
378#### Long Volume Attach/Mount Times
379
380Certain volume type and filesystem format combinations may experience long
381attach/mount times, [10 or more minutes][K8S_VOLUME_TIMEOUT], when using
382`fsGroup`. This issue may result in the following entries in the pod's event
383history:
384
385```console
386Warning FailedMount 38m kubelet, aks-default-41587790-2 Unable to attach or mount volumes: unmounted volumes=[jenkins-home], unattached volumes=[plugins plugin-dir jenkins-token-rmq2g sc-config-volume tmp jenkins-home jenkins-config secrets-dir]: timed out waiting for the condition
387```
388
389In these cases, experiment with replacing `fsGroup` with
390`supplementalGroups` in the pod's `securityContext`. This can be achieved by
391setting the `controller.podSecurityContextOverride` Helm chart value to
392something like:
393
394```yaml
395controller:
396 podSecurityContextOverride:
397 runAsNonRoot: true
398 runAsUser: 1000
399 supplementalGroups: [1000]
400```
401
402This issue has been reported on [azureDisk with ext4][K8S_VOLUME_TIMEOUT] and
403on [Alibaba cloud][K8S_VOLUME_TIMEOUT_ALIBABA].
404
405[K8S_VOLUME_TIMEOUT]: https://github.com/kubernetes/kubernetes/issues/67014
406[K8S_VOLUME_TIMEOUT_ALIBABA]: https://github.com/kubernetes/kubernetes/issues/67014#issuecomment-698770511
407
408#### Storage Class
409
410It is possible to define which storage class to use, by setting `persistence.storageClass` to `[customStorageClass]`.
411If set to a dash (`-`), dynamic provisioning is disabled.
412If the storage class is set to null or left undefined (`""`), the default provisioner is used (gp2 on AWS, standard on GKE, AWS & OpenStack).
413
414### Additional Secrets
415
416Additional secrets and Additional Existing Secrets,
417can be mounted into the Jenkins controller through the chart or created using `controller.additionalSecrets` or `controller.additionalExistingSecrets`.
418A common use case might be identity provider credentials if using an external LDAP or OIDC-based identity provider.
419The secret may then be referenced in JCasC configuration (see [JCasC configuration](#configuration-as-code)).
420
421`values.yaml` controller section, referencing mounted secrets:
422```yaml
423controller:
424 # the 'name' and 'keyName' are concatenated with a '-' in between, so for example:
425 # an existing secret "secret-credentials" and a key inside it named "github-password" should be used in Jcasc as ${secret-credentials-github-password}
426 # 'name' and 'keyName' must be lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-',
427 # and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc')
428 # existingSecret existing secret "secret-credentials" and a key inside it named "github-username" should be used in Jcasc as ${github-username}
429 # When using existingSecret no need to specify the keyName under additionalExistingSecrets.
430 existingSecret: secret-credentials
431
432 additionalExistingSecrets:
433 - name: secret-credentials
434 keyName: github-username
435 - name: secret-credentials
436 keyName: github-password
437 - name: secret-credentials
438 keyName: token
439
440 additionalSecrets:
441 - name: client_id
442 value: abc123
443 - name: client_secret
444 value: xyz999
445 JCasC:
446 securityRealm: |
447 oic:
448 clientId: ${client_id}
449 clientSecret: ${client_secret}
450 ...
451 configScripts:
452 jenkins-casc-configs: |
453 credentials:
454 system:
455 domainCredentials:
456 - credentials:
457 - string:
458 description: "github access token"
459 id: "github_app_token"
460 scope: GLOBAL
461 secret: ${secret-credentials-token}
462 - usernamePassword:
463 description: "github access username password"
464 id: "github_username_pass"
465 password: ${secret-credentials-github-password}
466 scope: GLOBAL
467 username: ${secret-credentials-github-username}
468```
469
470For more information, see [JCasC documentation](https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/secrets.adoc#kubernetes-secrets).
471
472### Secret Claims from HashiCorp Vault
473
474It's possible for this chart to generate `SecretClaim` resources in order to automatically create and maintain Kubernetes `Secrets` from HashiCorp [Vault](https://www.vaultproject.io/) via [`kube-vault-controller`](https://github.com/roboll/kube-vault-controller)
475
476These `Secrets` can then be referenced in the same manner as Additional Secrets above.
477
478This can be achieved by defining required Secret Claims within `controller.secretClaims`, as follows:
479```yaml
480controller:
481 secretClaims:
482 - name: jenkins-secret
483 path: secret/path
484 - name: jenkins-short-ttl
485 path: secret/short-ttl-path
486 renew: 60
487```
488
489### RBAC
490
491RBAC is enabled by default. If you want to disable it you will need to set `rbac.create` to `false`.
492
493### Adding Custom Pod Templates
494
495It is possible to add custom pod templates for the default configured kubernetes cloud.
496Add a key under `agent.podTemplates` for each pod template. Each key (prior to `|` character) is just a label, and can be any value.
497Keys 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.
498There's no need to add the _jnlp_ container since the kubernetes plugin will automatically inject it into the pod.
499For this pod templates configuration to be loaded the following values must be set:
500
501```yaml
502controller.JCasC.defaultConfig: true
503```
504
505The example below creates a python pod template in the kubernetes cloud:
506
507```yaml
508agent:
509 podTemplates:
510 python: |
511 - name: python
512 label: jenkins-python
513 serviceAccount: jenkins
514 containers:
515 - name: python
516 image: python:3
517 command: "/bin/sh -c"
518 args: "cat"
519 ttyEnabled: true
520 privileged: true
521 resourceRequestCpu: "400m"
522 resourceRequestMemory: "512Mi"
523 resourceLimitCpu: "1"
524 resourceLimitMemory: "1024Mi"
525```
526
527Best reference is `https://<jenkins_url>/configuration-as-code/reference#Cloud-kubernetes`.
528
529### Adding Pod Templates Using additionalAgents
530
531`additionalAgents` may be used to configure additional kubernetes pod templates.
532Each additional agent corresponds to `agent` in terms of the configurable values and inherits all values from `agent` so you only need to specify values which differ.
533For example:
534
535```yaml
536agent:
537 podName: default
538 customJenkinsLabels: default
539 # set resources for additional agents to inherit
540 resources:
541 limits:
542 cpu: "1"
543 memory: "2048Mi"
544
545additionalAgents:
546 maven:
547 podName: maven
548 customJenkinsLabels: maven
549 # An example of overriding the jnlp container
550 # sideContainerName: jnlp
551 image: jenkins/jnlp-agent-maven
552 tag: latest
553 python:
554 podName: python
555 customJenkinsLabels: python
556 sideContainerName: python
557 image: python
558 tag: "3"
559 command: "/bin/sh -c"
560 args: "cat"
561 TTYEnabled: true
562```
563
564### Ingress Configuration
565
566This chart provides ingress resources configurable via the `controller.ingress` block.
567
568The simplest configuration looks like the following:
569
570```yaml
571controller:
572 ingress:
573 enabled: true
574 paths: []
575 apiVersion: "extensions/v1beta1"
576 hostName: jenkins.example.com
577```
578
579This snippet configures an ingress rule for exposing jenkins at `jenkins.example.com`
580
581You can define labels and annotations via `controller.ingress.labels` and `controller.ingress.annotations` respectively.
582Additionally, you can configure the ingress tls via `controller.ingress.tls`.
583By default, this ingress rule exposes all paths.
584If needed this can be overwritten by specifying the wanted paths in `controller.ingress.paths`
585
586If you want to configure a secondary ingress e.g. you don't want the jenkins instance exposed but still want to receive webhooks you can configure `controller.secondaryingress`.
587The secondaryingress doesn't expose anything by default and has to be configured via `controller.secondaryingress.paths`:
588
589```yaml
590controller:
591 ingress:
592 enabled: true
593 apiVersion: "extensions/v1beta1"
594 hostName: "jenkins.internal.example.com"
595 annotations:
596 kubernetes.io/ingress.class: "internal"
597 secondaryingress:
598 enabled: true
599 apiVersion: "extensions/v1beta1"
600 hostName: "jenkins-scm.example.com"
601 annotations:
602 kubernetes.io/ingress.class: "public"
603 paths:
604 - /github-webhook
605```
606
607## Prometheus Metrics
608
609If you want to expose Prometheus metrics you need to install the [Jenkins Prometheus Metrics Plugin](https://github.com/jenkinsci/prometheus-plugin).
610It will expose an endpoint (default `/prometheus`) with metrics where a Prometheus Server can scrape.
611
612If you have implemented [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator), you can set `controller.prometheus.enabled` to `true` to configure a `ServiceMonitor` and `PrometheusRule`.
613If you want to further adjust alerting rules you can do so by configuring `controller.prometheus.alertingrules`
614
615If you have implemented Prometheus without using the operator, you can leave `controller.prometheus.enabled` set to `false`.
616
617### Running Behind a Forward Proxy
618
619The controller pod uses an Init Container to install plugins etc. If you are behind a corporate proxy it may be useful to set `controller.initContainerEnv` to add environment variables such as `http_proxy`, so that these can be downloaded.
620
621Additionally, you may want to add env vars for the init container, the Jenkins container, and the JVM (`controller.javaOpts`):
622
623```yaml
624controller:
625 initContainerEnv:
626 - name: http_proxy
627 value: "http://192.168.64.1:3128"
628 - name: https_proxy
629 value: "http://192.168.64.1:3128"
630 - name: no_proxy
631 value: ""
632 - name: JAVA_OPTS
633 value: "-Dhttps.proxyHost=proxy_host_name_without_protocol -Dhttps.proxyPort=3128"
634 containerEnv:
635 - name: http_proxy
636 value: "http://192.168.64.1:3128"
637 - name: https_proxy
638 value: "http://192.168.64.1:3128"
639 javaOpts: >-
640 -Dhttp.proxyHost=192.168.64.1
641 -Dhttp.proxyPort=3128
642 -Dhttps.proxyHost=192.168.64.1
643 -Dhttps.proxyPort=3128
644```
645
646### HTTPS Keystore Configuration
647
648[This configuration](https://wiki.jenkins.io/pages/viewpage.action?pageId=135468777) enables jenkins to use keystore in order to serve HTTPS.
649Here is the [value file section](https://wiki.jenkins.io/pages/viewpage.action?pageId=135468777#RunningJenkinswithnativeSSL/HTTPS-ConfigureJenkinstouseHTTPSandtheJKSkeystore) related to keystore configuration.
650Keystore itself should be placed in front of `jenkinsKeyStoreBase64Encoded` key and in base64 encoded format. To achieve that after having `keystore.jks` file simply do this: `cat keystore.jks | base64` and paste the output in front of `jenkinsKeyStoreBase64Encoded`.
651After enabling `httpsKeyStore.enable` make sure that `httpPort` and `targetPort` are not the same, as `targetPort` will serve HTTPS.
652Do not set `controller.httpsKeyStore.httpPort` to `-1` because it will cause readiness and liveliness prob to fail.
653If you already have a kubernetes secret that has keystore and its password you can specify its' name in front of `jenkinsHttpsJksSecretName`, You need to remember that your secret should have proper data key names `jenkins-jks-file` (or override the key name using `jenkinsHttpsJksSecretKey`)
654and `https-jks-password` (or override the key name using `jenkinsHttpsJksPasswordSecretKey`; additionally you can make it get the password from a different secret using `jenkinsHttpsJksPasswordSecretName`). Example:
655
656```yaml
657controller:
658 httpsKeyStore:
659 enable: true
660 jenkinsHttpsJksSecretName: ''
661 httpPort: 8081
662 path: "/var/jenkins_keystore"
663 fileName: "keystore.jks"
664 password: "changeit"
665 jenkinsKeyStoreBase64Encoded: ''
666```
667### AWS Security Group Policies
668
669To create SecurityGroupPolicies set `awsSecurityGroupPolicies.enabled` to true and add your policies. Each policy requires a `name`, array of `securityGroupIds` and a `podSelector`. Example:
670
671```yaml
672awsSecurityGroupPolicies:
673 enabled: true
674 policies:
675 - name: "jenkins-controller"
676 securityGroupIds:
677 - sg-123456789
678 podSelector:
679 matchExpressions:
680 - key: app.kubernetes.io/component
681 operator: In
682 values:
683 - jenkins-controller
684```
685
686### Agent Direct Connection
687
688Set `directConnection` to `true` to allow agents to connect directly to a given TCP port without having to negotiate a HTTP(S) connection. This can allow you to have agent connections without an external HTTP(S) port. Example:
689
690```yaml
691agent:
692 jenkinsTunnel: "jenkinsci-agent:50000"
693 directConnection: true
694```
695
696## Migration Guide
697
698### From stable repository
699
700Upgrade an existing release from `stable/jenkins` to `jenkins/jenkins` seamlessly by ensuring you have the latest [repository info](#get-repository-info) and running the [upgrade commands](#upgrade-chart) specifying the `jenkins/jenkins` chart.
701
702### Major Version Upgrades
703
704Chart release versions follow [SemVer](../../CONTRIBUTING.md#versioning), where a MAJOR version change (example `1.0.0` -> `2.0.0`) indicates an incompatible breaking change needing manual actions.
705
706See [UPGRADING.md](./UPGRADING.md) for a list of breaking changes