1---
2layout: "docs"
3page_title: "Helm - Kubernetes"
4sidebar_current: "docs-platform-k8s-helm"
5description: |-
6  The Consul Helm chart is the recommended way to install and configure Consul on Kubernetes. In addition to running Consul itself, the Helm chart is the primary method for installing and configuring Consul integrations with Kubernetes such as catalog syncing, Connect injection, and more.
7---
8
9# Helm Chart
10
11The [Consul Helm chart](https://github.com/hashicorp/consul-helm)
12is the recommended way to install and configure Consul on Kubernetes.
13In addition to running Consul itself, the Helm chart is the primary
14method for installing and configuring Consul integrations with
15Kubernetes such as catalog syncing, Connect injection, and more.
16
17This page assumes general knowledge of [Helm](https://helm.sh/) and
18how to use it. Using Helm to install Consul will require that Helm is
19properly installed and configured with your Kubernetes cluster.
20
21-> **Important:** The Helm chart is new and
22may still change significantly over time. Please always run Helm with
23`--dry-run` before any install or upgrade to verify changes.
24
25~> **Security Warning:** By default, the chart will install an insecure configuration
26of Consul. This provides a less complicated out-of-box experience for new users,
27but is not appropriate for a production setup. It is highly recommended to use
28a properly secured Kubernetes cluster or make sure that you understand and enable
29the [recommended security features](/docs/internals/security.html). Currently,
30some of these features are not supported in the Helm chart and require additional
31manual configuration.
32
33## Using the Helm Chart
34
35To use the Helm chart, you must download or clone the
36[consul-helm GitHub repository](https://github.com/hashicorp/consul-helm)
37and run Helm against the directory. We plan to transition to using a real
38Helm repository soon. When running Helm, we highly recommend you always
39checkout a specific tagged release of the chart to avoid any
40instabilities from master.
41
42Prior to this, you must have Helm installed and configured both in your
43Kubernetes cluster and locally on your machine. The steps to do this are
44out of the scope of this document, please read the
45[Helm documentation](https://helm.sh/) for more information.
46
47Example chart usage:
48
49```sh
50# Clone the chart repo
51$ git clone https://github.com/hashicorp/consul-helm.git
52$ cd consul-helm
53
54# Checkout a tagged version
55$ git checkout v0.1.0
56
57# Run Helm
58$ helm install --dry-run ./
59```
60
61~> **Warning:** By default, the chart will install _everything_: a
62Consul server cluster, client agents on all nodes, feature components, etc.
63This provides a nice out-of-box experience for new users, but may not be
64appropriate for a production setup. Consider setting the `global.enabled`
65value to `false` and opt-in to the various components.
66
67## Configuration (Values)
68
69The chart is highly customizable using
70[Helm configuration values](https://docs.helm.sh/using_helm/#customizing-the-chart-before-installing).
71Each value has a sane default tuned for an optimal getting started experience
72with Consul. Before going into production, please review the parameters below
73and consider if they're appropriate for your deployment.
74
75* <a name="v-global" href="#v-global">`global`</a> - These values are global values that affect multiple components of the chart.
76
77  - <a name="v-global-enabled" href="#v-global-enabled">`enabled`</a> (`boolean: true`) -
78  The master enabled/disabled configuration. If this is true, most components
79  will be installed by default. If this is false, no components will be installed
80  by default and manually opt-in is required, such as by setting
81  <a href="#v-">`server.enabled`</a> to true.
82
83
84  - <a name="v-global-domain" href="#v-global-domain">`domain`</a> (`string: "consul"`) -
85  The domain Consul uses for DNS queries. This is used to configure agents both
86  for DNS listening but also to know what domain to join the cluster.
87  This should be consistent throughout the chart, but can be overridden
88  per-component as well.
89
90  - <a name="v-global-image" href="#v-global-image">`image`</a> (`string: "consul:latest"`) -
91  The name of the Docker image (including any tag) for the containers running
92  Consul agents. **This should be pinned to a specific version when running
93  in production.** Otherwise, other changes to the chart may inadvertently
94  upgrade your Consul version.
95
96  - <a name="v-global-imagek8s" href="#v-global-imagek8s">`imageK8S`</a> (`string: "hashicorp/consul-k8s:latest"`) -
97  The name of the Docker image (including any tag) for the
98  [consul-k8s](https://github.com/hashicorp/consul-k8s) binary. This is
99  used by components such as catalog sync. **This should be pinned to a specific
100  version when running in production.** Otherwise, other changes to the chart may
101  inadvertently upgrade the version.
102
103  - <a name="v-global-datacenter" href="#v-global-datacenter">`datacenter`</a> (`string: "dc1"`) -
104  The name of the datacenter that the agent cluster should register as.
105  This may not be changed once the cluster is bootstrapped and running,
106  since Consul doesn't yet support an automatic way to change this value.
107
108
109* <a name="v-server" href="#v-server">`server`</a> - Values that configure
110  running a Consul server cluster within Kubernetes.
111
112  - <a name="v-server-enabled" href="#v-server-enabled">`enabled`</a> (`boolean: global.enabled`) -
113  If true, the chart will install all the resources necessary for a Consul
114  server cluster. If you're running Consul externally and want agents within
115  Kubernetes to join that cluster, this should probably be false.
116
117  - <a name="v-server-image" href="#v-server-image">`image`</a> (`string: global.image`) -
118  The name of the Docker image (including any tag) for the containers running
119  Consul server agents.
120
121  - <a name="v-server-replicas" href="#v-server-replicas">`replicas`</a> (`integer: 3`) -
122  The number of server agents to run. This determines the fault tolerance
123  of the cluster. Please see the [deployment table](/docs/internals/consensus.html#deployment-table)
124  for more information.
125
126  - <a name="v-server-bootstrapexpect" href="#v-server-bootstrapexpect">`bootstrapExpect`</a> (`integer: 3`) -
127  For new clusters, this is the number of servers to wait for before
128  performing the initial leader election and bootstrap of the cluster. This
129  must be less than or equal to `server.replicas`. This value is only
130  used when bootstrapping new clusters, it has no effect during ongoing cluster
131  maintenance.
132
133  - <a name="v-server-storage" href="#v-server-storage">`storage`</a> (`string: 10Gi`) -
134  This defines the disk size for configuring the servers' StatefulSet storage. For dynamically
135  provisioned storage classes, this is the desired size. For manually defined persistent
136  volumes, this should be set to the disk size of the attached volume.
137
138  - <a name="v-server-storageclass" href="#v-server-storageclass">`storageClass`</a> (`string: null`) -
139  The StorageClass to use for the servers' StatefulSet storage. It must be able to be dynamically
140  provisioned if you want the storage to be automatically created. For example, to use
141  [Local](https://kubernetes.io/docs/concepts/storage/storage-classes/#local)
142  storage classes, the PersistentVolumeClaims would need to be manually created. A `null` value will
143  use the Kubernetes cluster's default StorageClass. If a default StorageClass does not exist,
144  you will need to create one.
145
146  - <a name="v-server-connect" href="#v-server-connect">`connect`</a> (`boolean: true`) -
147  This will enable/disable [Connect](/docs/connect/index.html). Setting this
148  to true _will not_ automatically secure pod communication, this setting will
149  only enable usage of the feature. Consul will automatically initialize a new
150  CA and set of certificates. Additional Connect settings can be configured
151  by setting the `server.extraConfig` value.
152
153  - <a name="v-server-resources" href="#v-server-resources">`resources`</a> (`string: null`) -
154  The resource requests (CPU, memory, etc.) for each of the server agents.
155  This should be a multi-line string mapping directly to a Kubernetes
156  [ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#resourcerequirements-v1-core) object. If this isn't specified, then the pods
157  won't request any specific amount of resources. **Setting this is highly
158  recommended.**
159
160          ```yaml
161          # Resources are defined as a formatted multi-line string:
162          resources: |
163            requests:
164              memory: "10Gi"
165            limits:
166             memory: "10Gi"
167          ```
168
169  - <a name="v-server-updatepartition" href="#v-server-updatepartition">`updatePartition`</a> (`integer: 0`) -
170  This value is used to carefully control a rolling update of Consul server
171  agents. This value specifies the
172  [partition](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions)
173  for performing a rolling update. Please read the linked Kubernetes
174  documentation for more information.
175
176  - <a name="v-server-disruptionbudget" href="#v-server-disruptionbudget">`disruptionBudget`</a> -
177  This configures the
178  [PodDisruptionBudget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)
179  for the server cluster.
180
181      * <a name="v-server-disruptionbudget-enabled" href="#v-server-disruptionbudget-enabled">`enabled`</a> (`boolean: true`) -
182      This will enable/disable registering a PodDisruptionBudget for
183      the server cluster. If this is enabled, it will only register the
184      budget so long as the server cluster is enabled.
185
186      * <a name="v-server-disruptionbudget-maxunavailable" href="#v-server-disruptionbudget-maxunavailable">`maxUnavailable`</a> (`integer: null`) -
187      The maximum number of unavailable pods. By default, this will be automatically
188      computed based on the `server.replicas` value to be `(n/2)-1`. If you need to set
189      this to `0`, you will need to add a `--set 'server.disruptionBudget.maxUnavailable=0'`
190      flag to the helm chart installation command because of a limitation in the Helm
191      templating language.
192
193  - <a name="v-server-extraconfig" href="#v-server-extraconfig">`extraConfig`</a> (`string: "{}"`) -
194  A raw string of extra JSON or HCL configuration for Consul servers. This
195  will be saved as-is into a ConfigMap that is read by the Consul server agents.
196  This can be used to add additional configuration that isn't directly exposed
197  by the chart.
198
199  - <a name="v-server-extravolumes" href="#v-server-extravolumes">`extraVolumes`</a> (`array: []`) -
200  A list of extra volumes to mount for server agents. This is useful for bringing
201  in extra data that can be referenced by other configurations at a well known
202  path, such as TLS certificates or Gossip encryption keys.
203  The value of this should be a list of objects. Each object supports the following keys:
204
205      * <a name="v-server-extravolumes-type" href="#v-server-extravolumes-type">`type`</a> (`string: required`) -
206      Type of the volume, must be one of "configMap" or "secret". Case sensitive.
207
208      * <a name="v-server-extravolumes-name" href="#v-server-extravolumes-name">`name`</a> (`string: required`) -
209      Name of the configMap or secret to be mounted. This also controls the path
210      that it is mounted to. The volume will be mounted to `/config/userconfig/<name>`.
211
212      * <a name="v-server-extravolumes-load" href="#v-server-extravolumes-load">`load`</a> (`boolean: false`) -
213      If true, then the agent will be configured to automatically load HCL/JSON
214      configuration files from this volume with `-config-dir`. This defaults
215      to false.
216
217  - <a name="v-server-affinity" href="#v-server-affinity">`affinity`</a> (`string`) -
218  This value defines the [affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)
219  for server pods. It defaults to allowing only a single pod on each node,
220  which minimizes risk of the cluster becoming unusable if a node is lost.
221  If you need to run more pods per node (for example, testing on Minikube),
222  set this value to `null`.
223
224          ```yaml
225          # Recommended default server affinity:
226          affinity: |
227            podAntiAffinity:
228              requiredDuringSchedulingIgnoredDuringExecution:
229                - labelSelector:
230                    matchLabels:
231                      app: {{ template "consul.name" . }}
232                      release: "{{ .Release.Name }}"
233                      component: server
234                  topologyKey: kubernetes.io/hostname
235          ```
236
237* <a name="v-client" href="#v-client">`client`</a> - Values that configure
238  running a Consul client agent on Kubernetes nodes.
239
240  - <a name="v-client-enabled" href="#v-client-enabled">`enabled`</a> (`boolean: global.enabled`) -
241  If true, the chart will install all the resources necessary for a Consul
242  client on every Kubernetes node. This _does not_ require `server.enabled`,
243  since the agents can be configured to join an external cluster.
244
245  - <a name="v-client-image" href="#v-client-image">`image`</a> (`string: global.image`) -
246  The name of the Docker image (including any tag) for the containers running
247  Consul client agents.
248
249  - <a name="v-client-join" href="#v-client-join">`join`</a> (`array<string>: null`) -
250  A list of valid [`-retry-join` values](/docs/agent/options.html#retry-join).
251  If this is `null` (default),
252  then the clients will attempt to automatically join the server cluster
253  running within Kubernetes. This means that with `server.enabled` set to true,
254  clients will automatically join that cluster. If `server.enabled` is not
255  true, then a value must be specified so the clients can join a valid cluster.
256
257  - <a name="v-client-grpc" href="#v-client-grpc">`grpc`</a> (`boolean: false`) -
258  If true, agents will enable their GRPC listener on port 8502 and expose
259  it to the host. This will use slightly more resources, but is required for
260  [Connect](/docs/platform/k8s/connect.html).
261
262  - <a name="v-client-resources" href="#v-client-resources">`resources`</a> (`string: null`) -
263  The resource requests (CPU, memory, etc.) for each of the client agents.
264  This should be a multi-line string mapping directly to a Kubernetes
265  [ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#resourcerequirements-v1-core) object. If this isn't specified, then the pods
266  won't request any specific amount of resources.
267
268          ```yaml
269          # Resources are defined as a formatted multi-line string:
270          resources: |
271            requests:
272              memory: "10Gi"
273            limits:
274             memory: "10Gi"
275          ```
276
277  - <a name="v-client-extraconfig" href="#v-client-extraconfig">`extraConfig`</a> (`string: "{}"`) -
278  A raw string of extra JSON or HCL configuration for Consul clients. This
279  will be saved as-is into a ConfigMap that is read by the Consul agents.
280  This can be used to add additional configuration that isn't directly exposed
281  by the chart.
282
283  - <a name="v-client-extravolumes" href="#v-client-extravolumes">`extraVolumes`</a> (`array: []`) -
284  A list of extra volumes to mount for client agents. This is useful for bringing
285  in extra data that can be referenced by other configurations at a well known
286  path, such as TLS certificates or Gossip encryption keys.
287  The value of this should be a list of objects. Each object supports the following keys:
288
289      * <a name="v-client-extravolumes-type" href="#v-client-extravolumes-type">`type`</a> (`string: required`) -
290      Type of the volume, must be one of "configMap" or "secret". Case sensitive.
291
292      * <a name="v-client-extravolumes-name" href="#v-client-extravolumes-name">`name`</a> (`string: required`) -
293      Name of the configMap or secret to be mounted. This also controls the path
294      that it is mounted to. The volume will be mounted to `/config/userconfig/<name>`.
295
296      * <a name="v-client-extravolumes-load" href="#v-client-extravolumes-load">`load`</a> (`boolean: false`) -
297      If true, then the agent will be configured to automatically load HCL/JSON
298      configuration files from this volume with `-config-dir`. This defaults
299      to false.
300
301* <a name="v-dns" href="#v-dns">`dns`</a> - Values that configure the Consul DNS service.
302
303  - <a name="v-dns-enabled" href="#v-dns-enabled">`enabled`</a> (`boolean: global.enabled`) -
304  If true, a `consul-dns` service will be created that exposes port 53 for
305  TCP and UDP to the running Consul agents (servers and clients). This can
306  then be used to [configure kube-dns](/docs/platform/k8s/dns.html). The Helm
307  chart _does not_ automatically configure kube-dns.
308
309* <a name="v-synccatalog" href="#v-synccatalog">`syncCatalog`</a> - Values that
310  configure running the [service sync](/docs/platform/k8s/service-sync.html)
311  process.
312
313  - <a name="v-synccatalog-enabled" href="#v-synccatalog-enabled">`enabled`</a> (`boolean: false`) -
314  If true, the chart will install all the resources necessary for the
315  catalog sync process to run.
316
317  - <a name="v-synccatalog-image" href="#v-synccatalog-image">`image`</a> (`string: global.imageK8S`) -
318  The name of the Docker image (including any tag) for
319  [consul-k8s](/docs/platform/k8s/index.html#quot-consul-k8s-quot-project)
320  to run the sync program.
321
322  - <a name="v-synccatalog-default" href="#v-synccatalog-default">`default`</a> (`boolean: true`) -
323  If true, all valid services in K8S are synced by default. If false,
324  the service must be [annotated](/docs/platform/k8s/service-sync.html#sync-enable-disable)
325  properly to sync. In either case an annotation can override the default.
326
327  - <a name="v-synccatalog-toconsul" href="#v-synccatalog-toconsul">`toConsul`</a> (`boolean: true`) -
328  If true, will sync Kubernetes services to Consul. This can be disabled to
329  have a one-way sync.
330
331  - <a name="v-synccatalog-tok8s" href="#v-synccatalog-tok8s">`toK8S`</a> (`boolean: true`) -
332  If true, will sync Consul services to Kubernetes. This can be disabled to
333  have a one-way sync.
334
335  - <a name="v-synccatalog-k8sprefix" href="#v-synccatalog-k8sprefix">`k8sPrefix`</a> (`string: ""`) -
336  A prefix to prepend to all services registered in Kubernetes from Consul.
337  This defaults to `""` where no prefix is prepended; Consul services are
338  synced with the same name to Kubernetes. (Consul -> Kubernetes sync only)
339
340  - <a name="v-synccatalog-k8stag" href="#v-synccatalog-k8stag">`k8sTag`</a> (`string: null`) -
341  An optional tag that is applied to all of the Kubernetes services
342  that are synced into Consul. If nothing is set, this defaults to "k8s".
343  (Kubernetes -> Consul sync only)
344
345  - <a name="v-synccatalog-clusterip-sync" href="#v-synccatalog-clusterip-sync">`syncClusterIPServices`</a> (`boolean: true`) -
346  If true, will sync Kubernetes ClusterIP services to Consul. This can be disabled to
347  have the sync ignore ClusterIP-type services.
348
349  - <a name="v-synccatalog-nodeport-sync" href="#v-synccatalog-nodeport-sync">`nodePortSyncType`</a> (`string: ExternalFirst`) -
350  Configures the type of syncing that happens for NodePort services.
351  The only valid options are: `ExternalOnly`, `InternalOnly`, and `ExternalFirst`.
352  `ExternalOnly` will only use a node's ExternalIP address for the sync, otherwise the
353  service will not be synced. `InternalOnly` uses the node's InternalIP address.
354  `ExternalFirst` will preferentially use the node's ExternalIP address, but
355  if it doesn't exist, it will use the node's InternalIP address instead.
356
357* <a name="v-ui" href="#v-ui">`ui`</a> - Values that configure the Consul UI.
358
359  - <a name="v-ui-enabled" href="#v-ui-enabled">`enabled`</a> (`boolean: global.enabled`) -
360  If true, the UI will be enabled. This will only _enable_ the UI, it doesn't
361  automatically register any service for external access. The UI will only
362  be enabled on server agents. If `server.enabled` is false, then this setting
363  has no effect. To expose the UI in some way, you must configure
364  `ui.service`.
365
366  - <a name="v-ui-service" href="#v-ui-service">`service`</a> -
367  This configures the `Service` resource registered for the Consul UI.
368
369      * <a name="v-ui-service-enabled" href="#v-ui-service-enabled">`enabled`</a> (`boolean: true`) -
370      This will enable/disable registering a Kubernetes Service for the Consul UI.
371      This value only takes effect if `ui.enabled` is true and taking effect.
372
373      * <a name="v-ui-service-type" href="#v-ui-service-type">`type`</a> (`string: null`) -
374      The service type to register. This defaults to `null` which doesn't set
375      an explicit service type, which typically is defaulted to "ClusterIP"
376      by Kubernetes. The available service types are documented on
377      [the Kubernetes website](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types).
378
379* <a name="v-connectinject" href="#v-connectinject">`connectInject`</a> - Values that
380  configure running the [Connect injector](/docs/platform/k8s/connect.html).
381
382  - <a name="v-connectinject-enabled" href="#v-connectinject-enabled">`enabled`</a> (`boolean: false`) -
383  If true, the chart will install all the resources necessary for the
384  Connect injector process to run. This will enable the injector but will
385  require pods to opt-in with an annotation by default.
386
387  - <a name="v-connectinject-image" href="#v-connectinject-image">`image`</a> (`string: global.imageK8S`) -
388  The name of the Docker image (including any tag) for the
389  [consul-k8s](https://github.com/hashicorp/consul-k8s) binary.
390
391  - <a name="v-connectinject-default" href="#v-connectinject-default">`default`</a> (`boolean: false`) -
392  If true, the injector will inject the Connect sidecar into all pods by
393  default. Otherwise, pods must specify the
394  [injection annotation](/docs/platform/k8s/connect.html#consul-hashicorp-com-connect-inject)
395  to opt-in to Connect injection. If this is true, pods can use the same
396  annotation to explicitly opt-out of injection.
397
398  - <a name="v-connectinject-imageConsul" href="#v-connectinject-imageConsul">`imageConsul`</a> (`string: global.image`) -
399  The name of the Docker image (including any tag) for Consul. This is used
400  for proxy service registration, Envoy configuration, etc.
401
402  - <a name="v-connectinject-imageEnvoy" href="#v-connectinject-imageEnvoy">`imageEnvoy`</a> (`string: ""`) -
403  The name of the Docker image (including any tag) for the Envoy sidecar.
404  `envoy` must be on the executable path within this image. This Envoy
405  version must be compatible with the Consul version used by the injector.
406  This defaults to letting the injector choose the Envoy image, which is
407  usually `envoy/envoy-alpine`.
408
409  - <a name="v-connectinject-namespaceselector" href="#v-connectinject-namespaceselector">`namespaceSelector`</a> (`string: ""`) -
410  A [selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)
411  for restricting injection to only matching namespaces. By default
412  all namespaces except the system namespace will have injection enabled.
413
414  - <a name="v-connectinject-certs" href="#v-connectinject-certs">`certs`</a> -
415  The certs section configures how the webhook TLS certs are configured.
416  These are the TLS certs for the Kube apiserver communicating to the
417  webhook. By default, the injector will generate and manage its own certs,
418  but this requires the ability for the injector to update its own
419  `MutatingWebhookConfiguration`. In a production environment, custom certs
420  should probably be used. Configure the values below to enable this.
421
422      * <a name="v-connectinject-certs-secretname" href="#v-connectinject-certs-secretname">`secretName`</a> (`string: null`) -
423      secretName is the name of the Kubernetes secret that has the TLS certificate and
424      private key to serve the injector webhook. If this is null, then the
425      injector will default to its automatic management mode.
426
427      * <a name="v-connectinject-cabundle" href="#v-connectinject-cabundle">`caBundle`</a> (`string: ""`) -
428      The PEM-encoded CA public certificate bundle for the TLS certificate served by the
429      injector. This must be specified as a string and can't come from a
430      secret because it must be statically configured on the Kubernetes
431      `MutatingAdmissionWebhook` resource. This only needs to be specified
432      if `secretName` is not null.
433
434      * <a name="v-connectinject-certs-certname" href="#v-connectinject-certs-certname">`certName`</a> (`string: "tls.crt"`) -
435      The name of the certificate file within the `secretName` secret.
436
437      * <a name="v-connectinject-certs-keynamkeyname" href="#v-connectinject-certs-keyname">`keyName`</a> (`string: "tls.key"`) -
438      The name of the private key for the certificate file within the
439      `secretName` secret.
440
441## Customizing the Helm Chart
442
443Given the wide variety of use cases, it won't be possible to support every
444configuration option in the Helm chart's `values.yaml` file without making
445it difficult to understand and use. For additional
446flexibility in changing values that aren't listed above, consider using
447third-party tools such as [kustomize](https://github.com/kubernetes-sigs/kustomize)
448and [ship](https://github.com/replicatedhq/ship).
449