From 13ffbcd984e72b10c503be6c1dde362b15cdfd37 Mon Sep 17 00:00:00 2001 From: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Date: Mon, 5 Aug 2019 17:15:28 -0400 Subject: [PATCH] doc: add k8s vault-helm doc (#7193) * doc: add k8s vault-helm doc * Replace TODO with security warning * Add TLS example * Add production deployment checklist * Add kube hardening guide * Fix link to configuration values * Update website/source/docs/platform/k8s/helm.html.md Co-Authored-By: Jim Kalafut * Update website/source/docs/platform/k8s/helm.html.md Co-Authored-By: Jim Kalafut * Update website/source/docs/platform/k8s/helm.html.md Co-Authored-By: Jim Kalafut * Update website/source/docs/platform/k8s/helm.html.md Co-Authored-By: Jim Kalafut * Fix typo in example * Update website/source/docs/platform/k8s/helm.html.md Co-Authored-By: Jim Kalafut * Update website/source/docs/platform/k8s/helm.html.md Co-Authored-By: Jim Kalafut * Update website/source/docs/platform/k8s/helm.html.md Co-Authored-By: Jim Kalafut * Remove anchors, add tolerations/selector * Fix rendering of global configuration * Fix sidebar navigation and update links * Add sidebar title to run doc * Add platform index.html * Add relative links * Rename file * Fix titles * Add syntax highlighting to examples * Move platforms in navigation bar --- website/data/docs_basic_categories.yml | 4 + website/data/docs_detailed_categories.yml | 4 + website/source/docs/platform/index.html.md | 13 + website/source/docs/platform/k8s/helm.html.md | 472 ++++++++++++++++++ .../source/docs/platform/k8s/index.html.md | 43 ++ website/source/docs/platform/k8s/run.html.md | 227 +++++++++ website/source/layouts/docs.erb | 13 + 7 files changed, 776 insertions(+) create mode 100644 website/source/docs/platform/index.html.md create mode 100644 website/source/docs/platform/k8s/helm.html.md create mode 100644 website/source/docs/platform/k8s/index.html.md create mode 100644 website/source/docs/platform/k8s/run.html.md diff --git a/website/data/docs_basic_categories.yml b/website/data/docs_basic_categories.yml index ca3f53919..c4563eedb 100644 --- a/website/data/docs_basic_categories.yml +++ b/website/data/docs_basic_categories.yml @@ -38,6 +38,10 @@ description: "Configuring how Vault operates with external systems and applications via plugins." link: "/docs/plugin" title: "Plugin Backends" +- + description: "Topics related to running Vault on specific platforms (such as Kubernetes)." + link: "/docs/platform" + title: "Platforms" - description: "Topics related to Vault Enterprise, Vault's premium varient for professional teams and organizations." link: "/docs/enterprise" diff --git a/website/data/docs_detailed_categories.yml b/website/data/docs_detailed_categories.yml index 06534297a..60d30b254 100644 --- a/website/data/docs_detailed_categories.yml +++ b/website/data/docs_detailed_categories.yml @@ -125,6 +125,10 @@ title: "Plugin Backends" docs: - docs/plugin/index.html +- + title: "Platforms" + docs: + - docs/platform/k8s/index.html - title: "Vault Enterprise" docs: diff --git a/website/source/docs/platform/index.html.md b/website/source/docs/platform/index.html.md new file mode 100644 index 000000000..2bb1cbb66 --- /dev/null +++ b/website/source/docs/platform/index.html.md @@ -0,0 +1,13 @@ +--- +layout: "docs" +page_title: "Platforms" +sidebar_title: "Platforms" +sidebar_current: "docs-platform" +description: |- + This section covers running Vault on various platforms (such as Kubernetes). +--- + +# Platforms + +This section covers running Vault on various platforms (such as Kubernetes) and +explains architecture, configuration, installation and security considerations. diff --git a/website/source/docs/platform/k8s/helm.html.md b/website/source/docs/platform/k8s/helm.html.md new file mode 100644 index 000000000..efc638d9d --- /dev/null +++ b/website/source/docs/platform/k8s/helm.html.md @@ -0,0 +1,472 @@ +--- +layout: "docs" +page_title: "Helm - Kubernetes" +sidebar_current: "docs-platform-k8s-helm" +sidebar_title: "Helm Chart" +description: |- + The Vault Helm chart is the recommended way to install and configure Vault on Kubernetes. +--- + +# Helm Chart + +The [Vault Helm chart](https://github.com/hashicorp/vault-helm) +is the recommended way to install and configure Vault on Kubernetes. +In addition to running Vault itself, the Helm chart is the primary +method for installing and configuring Vault to integrate with other +services such as Consul for High Availability deployments. + +This page assumes general knowledge of [Helm](https://helm.sh/) and +how to use it. Using Helm to install Vault will require that Helm is +properly installed and configured with your Kubernetes cluster. + +-> **Important:** The Helm chart is new and +may still change significantly over time. Please always run Helm with +`--dry-run` before any install or upgrade to verify changes. + +~> **Security Warning:** By default, the chart will install an insecure configuration +of Vault. This provides a less complicated out-of-box experience for new users, +but is not appropriate for a production setup. It is highly recommended to use +a [properly secured Kubernetes cluster](https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/). +See the [architecture reference](/docs/platform/k8s/run.html#architecture) +for a Vault Helm production deployment checklist. + +## Using the Helm Chart + +To use the Helm chart, you must download or clone the +[vault-helm GitHub repository](https://github.com/hashicorp/vault-helm) +and run Helm against the directory. We plan to transition to using a real +Helm repository soon. When running Helm, we highly recommend you always +checkout a specific tagged release of the chart to avoid any +instabilities from master. + +Prior to this, you must have Helm installed and configured both in your +Kubernetes cluster and locally on your machine. The steps to do this are +out of the scope of this document. Please refer to the +[Helm documentation](https://helm.sh/) for more information. + +Example chart usage: + +```sh +# Clone the chart repo +$ git clone https://github.com/hashicorp/vault-helm.git +$ cd vault-helm + +# Checkout a tagged version +$ git checkout v0.1.0 + +# Run Helm +$ helm install --dry-run ./ +``` + +## Configuration (Values) + +The chart is highly customizable using +[Helm configuration values](https://docs.helm.sh/using_helm/#customizing-the-chart-before-installing). +Each value has a default tuned for an optimal getting started experience +with Vault. Before going into production, please review the parameters below +and consider if they're appropriate for your deployment. + +* `global` - These global values affect multiple components of the chart. + + * `enabled` (`boolean: true`) - The master enabled/disabled configuration. If this is true, most components will be installed by default. If this is false, no components will be installed by default and manually opting-in is required, such as by setting `server.enabled` to true. + + * `image` (`string: "vault:latest"`) - The name of the Docker image (including any tag) for the containers running Vault. **This should be pinned to a specific version when running in production.** Otherwise, other changes to the chart may inadvertently upgrade your Vault version. + +* `server` - Values that configure running a Vault server within Kubernetes. + + * `resources` (`string: null`) - The resource requests and limits (CPU, memory, etc.) for each of the server. This should be a multi-line string mapping directly to a Kubernetes [ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#resourcerequirements-v1-core) object. If this isn't specified, then the pods won't request any specific amount of resources. **Setting this is highly recommended.** + + ```yaml + # Resources are defined as a formatted multi-line string: + resources: | + requests: + memory: "10Gi" + limits: + memory: "10Gi" + ``` + + * `extraEnvironmentVars` (`string: null`) - The extra environment variables to be applied to the Vault server. This should be a multi-line key/value string. + + ```yaml + # Extra Environment Variables are defined as key/value strings. + extraEnvironmentVars: + GOOGLE_REGION: global, + GOOGLE_PROJECT: myproject, + GOOGLE_CREDENTIALS: /vault/userconfig/myproject/myproject-creds.json + ``` + + * `extraVolumes` (`array: []`) - A list of extra volumes to mount to Vault servers. This is useful for bringing in extra data that can be referenced by other configurations at a well known path, such as TLS certificates. The value of this should be a list of objects. Each object supports the following keys: + + - `type` (`string: required`) - + Type of the volume, must be one of "configMap" or "secret". Case sensitive. + + - `name` (`string: required`) - + Name of the configMap or secret to be mounted. This also controls the path + that it is mounted to. The volume will be mounted to `/vault/userconfig/`. + + ```yaml + extraVolumes: + - type: "secret" + name: "vault-certs" + ``` + + * `affinity` (`string`) - This value defines the [affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) for server pods. It defaults to allowing only a single pod on each node, which minimizes risk of the cluster becoming unusable if a node is lost. If you need to run more pods per node (for example, testing on Minikube), set this value to `null`. + + ```yaml + # Recommended default server affinity: + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: {{ template "vault.name" . }} + release: "{{ .Release.Name }}" + component: server + topologyKey: kubernetes.io/hostname + ``` + + * `tolerations` (`array []`) - This value defines the [tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) that are acceptable when being scheduled. + + ```yaml + tolerations: + - key: "node.kubernetes.io/unreachable" + operator: "Exists" + effect: "NoExecute" + tolerationSeconds: 6000 + ``` + + * `nodeSelector` (`string`) - This value defines additional node selection criteria for more control over where the Vault servers are deployed. + + ```yaml + nodeSelector: + disktype: ssd + ``` + + * `annotations` (`string`) - This value defines additional annotations for server pods. This should be a formatted as a multi-line string. + + ```yaml + annotations: | + "sample/annotation1": "foo" + "sample/annotation2": "bar" + ``` + + * `extraVolumes` - This configures the `Service` resource created for the Vault server. + + - `enabled` (`boolean: true`) - + Enables a service to allow other pods running in Kubernetes to communicate with the Vault server. + + * `dataStorage` - This configures the volume used for storing Vault data when not using external storage such as Consul. + + - `enabled` (`boolean: true`) - + Enables a persistent volume to be created for storing Vault data when not using an external storage service. + + - `size` (`string: 10Gi`) - + Size of the volume to be created for Vault's data storage when not using an external storage service. + + - `storageClass` (`string: null`) - + Name of the storage class to use when creating the data storage volume. + + - `accessMode` (`string: ReadWriteOnce`) - + Type of access mode of the storage device. See the [official Kubernetes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes) for more information. + + * `auditStorage` - This configures the volume used for storing Vault's audit logs. See the [Vault documentation](/docs/audit) for more information. + + - `enabled` (`boolean: true`) - + Enables a persistent volume to be created for storing Vault's audit logs. + + - `size` (`string: 10Gi`) - + Size of the volume to be created for Vault's audit logs. + + - `storageClass` (`string: null`) - + Name of the storage class to use when creating the audit storage volume. + + - `accessMode` (`string: ReadWriteOnce`) - + Type of access mode of the storage device. + + * `dev` - This configures `dev` mode for the Vault server. + + - `enabled` (`boolean: false`) - + Enables `dev` mode for the Vault server. This mode is useful for experimenting with Vault without needing to unseal. + + ~> **Security Warning:** Never, ever, ever run a "dev" mode server in production. It is insecure and will lose data on every restart (since it stores data in-memory). It is only made for development or experimentation. + + * `standalone` - This configures `standalone` mode for the Vault server. + + - `enabled` (`boolean: true`) - + Enables `standalone` mode for the Vault server. This mode uses the `file` storage backend and requires a volume for persistence (`dataStorage`). + + - `config` (`string: "{}"`) - + A raw string of extra HCL or JSON [configuration](https://www.vaultproject.io/docs/configuration/index.html) for Vault servers. + This will be saved as-is into a ConfigMap that is read by the Vault servers. + This can be used to add additional configuration that isn't directly exposed by the chart. + + ```yaml + # ExtraConfig values are formatted as a multi-line string: + config: | + api_addr = "http://POD_IP:8200" + + listener "tcp" { + tls_disable = 1 + address = "0.0.0.0:8200" + } + + storage "file" { + path = "/vault/data" + } + ``` + + This can also be set using Helm's `--set` flag (vault-helm v0.1.0 and later), using the following syntax: + + ```shell + --set server.standalone.config='{ listener "tcp" { address = "0.0.0.0:8200" }' + ``` + + * `ha` - This configures `ha` mode for the Vault server. + + - `enabled` (`boolean: false`) - + Enables `ha` mode for the Vault server. This mode uses a highly available backend storage (such as Consul) to store Vault's data. By default this is configured to use [Consul Helm](https://github.com/hashicorp/consul-helm). For a complete list of storage backends, see the [Vault documentation](/docs/configuration). + + - `replicas` (`int: 5`) - + The number of pods to deploy to create a highly available cluster of Vault servers. + + - `updatePartition` (`int: 0`) - + If an updatePartition is specified, all Pods with an ordinal that is greater than or equal to the partition will be updated when the StatefulSet’s `.spec.template` is updated. If set to `0`, this disables parition updates. For more information see the [official Kubernetes documentation](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#rolling-updates). + + - `config` (`string: "{}"`) - + A raw string of extra HCL or JSON [configuration](/docs/configuration) for Vault servers. + This will be saved as-is into a ConfigMap that is read by the Vault servers. + This can be used to add additional configuration that isn't directly exposed by the chart. + + ```yaml + # ExtraConfig values are formatted as a multi-line string: + config: | + ui = true + api_addr = "http://POD_IP:8200" + listener "tcp" { + tls_disable = 1 + address = "0.0.0.0:8200" + } + + storage "consul" { + path = "vault" + address = "HOST_IP:8500" + } + ``` + + This can also be set using Helm's `--set` flag (vault-helm v0.1.0 and later), using the following syntax: + + ```shell + --set server.ha.config='{ listener "tcp" { address = "0.0.0.0:8200" }' + ``` + + - `disruptionBudget` - Values that configures the disruption budget policy. See the [official Kubernetes documentation](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for more information. + + - `enabled` (`boolean: true`) - + Enables disruption budget policy to limit the number of pods that are down simultaneously from voluntary disruptions. + + - `maxUnavailable` (`int: null`) - + The maximum number of unavailable pods. By default, this will be automatically + computed based on the `server.replicas` value to be `(n/2)-1`. If you need to set + this to `0`, you will need to add a `--set 'server.disruptionBudget.maxUnavailable=0'` + flag to the helm chart installation command because of a limitation in the Helm + templating language. + +* `ui` - Values that configure the Vault UI. + + - `enabled` (`boolean: false`) - If true, the UI will be enabled. The UI will only be enabled on Vault servers. If `server.enabled` is false, then this setting has no effect. To expose the UI in some way, you must configure `ui.service`. + + - `serviceType` (`string: ClusterIP`) - + The service type to register. This defaults to `ClusterIP`. + The available service types are documented on + [the Kubernetes website](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types). + +## Helm Chart Examples + +The following are different configuration examples to support a variety of +deployment models. + +### Standalone Server with Load Balanced UI + +The below `values.yaml` can be used to set up a single server Vault cluster with a LoadBalancer to allow external access to the UI and API. + +```yaml +global: + enabled: true + image: "vault:1.2.0" + +server: + standalone: + enabled: true + config: | + api_addr = "http://POD_IP:8200" + listener "tcp" { + tls_disable = true + address = "0.0.0.0:8200" + } + + storage "file" { + path = "/vault/data" + } + + service: + enabled: true + + dataStorage: + enabled: true + size: 10Gi + storageClass: null + accessMode: ReadWriteOnce + +ui: + enabled: true + serviceType: LoadBalancer +``` + +### Standalone Server with TLS + +The below `values.yaml` can be used to set up a single server Vault cluster using TLS. +This assumes that a Kubernetes `secret` exists with the server certificate, key and +certificate authority: + +```yaml +global: + enabled: true + image: "vault:1.2.0" + +server: + extraVolumes: + - type: secret + name: vault-server-tls + + extraEnvironmentVars: + VAULT_ADDR: "https://localhost:8200" + + standalone: + enabled: true + config: | + api_addr = "https://POD_IP:8200" + listener "tcp" { + tls_cert_file = "/vault/userconfig/vault-server-tls/vault.crt" + tls_key_file = "/vault/userconfig/vault-server-tls/vault.key" + tls_client_ca_file = "/vault/userconfig/vault-server-tls/vault.ca" + address = "0.0.0.0:8200" + } + + storage "file" { + path = "/vault/data" + } + + service: + enabled: true + + dataStorage: + enabled: true + size: 10Gi + storageClass: null + accessMode: ReadWriteOnce +``` + +### Standalone Server with Audit Storage + +The below `values.yaml` can be used to set up a single server Vault cluster with +auditing enabled. + +```yaml +global: + enabled: true + image: "vault:1.2.0" + +server: + standalone: + enabled: true + config: | + api_addr = "http://POD_IP:8200" + listener "tcp" { + tls_disable = true + address = "0.0.0.0:8200" + } + + storage "file" { + path = "/vault/data" + } + + service: + enabled: true + + dataStorage: + enabled: true + size: 10Gi + storageClass: null + accessMode: ReadWriteOnce + + auditStorage: + enabled: true + size: 10Gi + storageClass: null + accessMode: ReadWriteOnce +``` + +After Vault has been deployed, initialized and unsealed, auditing can be enabled +by running the following command against the Vault pod: + +```bash +$ kubectl exec -ti -- vault audit enable file file_path=/vault/audit/vault_audit.log +``` + +### Highly Available Vault Cluster with Consul + +The below `values.yaml` can be used to set up a five server Vault cluster using +Consul as a highly available storage backend, Google Cloud KMS for Auto Unseal. + +```yaml +global: + enabled: true + image: "vault:1.2.0" + +server: + extraEnvironmentVars: + GOOGLE_REGION: global, + GOOGLE_PROJECT: myproject, + GOOGLE_CREDENTIALS: /vault/userconfig/my-gcp-iam/myproject-creds.json + + extraVolumes: [] + - type: secret + name: my-gcp-iam + load: false + + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: {{ template "vault.name" . }} + release: "{{ .Release.Name }}" + component: server + topologyKey: kubernetes.io/hostname + + service: + enabled: true + + ha: + enabled: false + replicas: 5 + + config: | + ui = true + api_addr = "http://POD_IP:8200" + listener "tcp" { + tls_disable = 1 + address = "0.0.0.0:8200" + } + storage "consul" { + path = "vault" + address = "HOST_IP:8500" + } + + seal "gcpckms" { + project = "myproject" + region = "global" + key_ring = "vault-unseal-kr" + crypto_key = "vault-unseal-key" + } +``` diff --git a/website/source/docs/platform/k8s/index.html.md b/website/source/docs/platform/k8s/index.html.md new file mode 100644 index 000000000..74d19bb08 --- /dev/null +++ b/website/source/docs/platform/k8s/index.html.md @@ -0,0 +1,43 @@ +--- +layout: "docs" +page_title: "Kubernetes" +sidebar_current: "docs-platform-k8s-index" +sidebar_title: "Kubernetes" +description: |- + This section documents the official integration between Vault and Kubernetes. +--- + +# Kubernetes + +Vault can be deployed into Kubernetes using the official HashiCorp Vault Helm chart. +The helm chart allows users to deploy Vault in various configurations: + +* Dev mode: a single in-memory Vault server for testing Vault +* Standalone mode (default): a single Vault server persisting to a volume using the file storage backend +* HA mode: a cluster of Vault servers that use an HA storage backend such as Consul (default) + +## Use Cases + +**Running a Vault Service:** The Vault server cluster can run directly on Kubernetes. +This can be used by applications running within Kubernetes as well as external to +Kubernetes, as long as they can communicate to the server via the network. + +**Accessing and Storing Secrets:** Applications using the Vault service running in +Kubernetes can access and store secrets from Vault using a number of different +[secret engines](/docs/secrets) and [authentication methods](/docs/auth). + +**Running a Highly Available Vault Service:** By using pod affinities, highly available +backend storage (such as Consul) and [auto-unseal](/docs/concepts/seal.html#auto-unseal), +Vault can become a highly available service in Kubernetes. + +**Encryption as a Service:** Applications using the Vault service running in Kubernetes +can leverage the [Transit secret engine](/docs/secrets/transit) +as "encryption as a service". This allows applications to offload encryption needs +to Vault before storage data at rest. + +**Audit Logs for Vault:** Operators can choose to attach a persistent volume +to the Vault cluster which can be used to [store audit logs](/docs/audit). + +**And more!** Vault can run directly on Kubernetes, so in addition to the +native integrations provided by Vault itself, any other tool built for +Kubernetes can choose to leverage Vault. diff --git a/website/source/docs/platform/k8s/run.html.md b/website/source/docs/platform/k8s/run.html.md new file mode 100644 index 000000000..5557f89cd --- /dev/null +++ b/website/source/docs/platform/k8s/run.html.md @@ -0,0 +1,227 @@ +--- +layout: "docs" +page_title: "Running Vault - Kubernetes" +sidebar_current: "docs-platform-k8s-run" +sidebar_title: "Running Vault" +description: |- + Vault can run directly on Kubernetes in various configurations. For pure-Kubernetes worloads, this enables Vault to also exist purely within Kubernetes. +--- + +# Running Vault on Kubernetes + +Vault can run directly on Kubernetes in various modes: `dev,` `standalone` and `ha`. +For pure-Kubernetes workloads, this enables Vault to also exist purely +within Kubernetes. + +This page starts with a large how-to section for various specific tasks. + +## Helm Chart + +The [Vault Helm chart](https://github.com/hashicorp/vault-helm) +is the recommended way to install and configure Vault on Kubernetes. +In addition to running Vault itself, the Helm chart is the primary +method for installing and configuring Vault to integrate with other +services such as Consul for High Availability deployments. + +While the Helm chart exposes dozens of useful configurations and automatically +sets up complex resources, it **does not automatically operate Vault.** +You are still responsible for learning how to monitor, backup, +upgrade, etc. the Vault cluster. + +The Helm chart has no required configuration and will install a Vault +cluster with sane defaults out of the box. Prior to going to production, +it is highly recommended that you +[learn about the configuration options](/docs/platform/k8s/helm.html#configuration-values-). + +~> **Security Warning:** By default, the chart will install an insecure configuration +of Vault. This provides a less complicated out-of-box experience for new users, +but is not appropriate for a production setup. It is highly recommended to use +a [properly secured Kubernetes cluster](https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/). +See the [architecture reference](/docs/platform/k8s/run.html#architecture) +for a production deployment checklist. + +## How-To + +### Installing Vault + +To install Vault, clone the vault-helm repository, checkout the latest release, and install +Vault. You can run `helm install` with the `--dry-run` flag to see the +resources it would configure. In a production environment, you should always +use the `--dry-run` flag prior to making any changes to the Vault cluster +via Helm. See the [chart configuration values](/docs/platform/k8s/helm.html#configuration-values-) +for additional configuration options. + +```sh +# Clone the chart repo +$ git clone https://github.com/hashicorp/vault-helm.git +$ cd vault-helm + +# Checkout a tagged version +$ git checkout v0.1.0 + +# Run Helm +$ helm install --name vault ./ +... +``` + +_That's it._ The Helm chart does everything to setup a Vault-on-Kubernetes deployment. + +### Viewing the Vault UI + +The Vault UI is enabled by default when using the Helm chart. +For security reasons, it isn't exposed via a Service by default so you must +use `kubectl port-forward` to visit the UI. Once the port is forwarded as +shown below, navigate your browser to `http://localhost:8200`. + +``` +$ kubectl port-forward vault-0 8200:8200 +... +``` + +The UI can also be exposed via a Kubernetes Service. To do this, configure +the [`ui.service` chart values](/docs/platform/k8s/helm.html#v-ui). + +### Upgrading Vault on Kubernetes + +To upgrade Vault on Kubernetes, we follow the same pattern as +[generally upgrading Vault](/docs/upgrading.html), except we can use +the Helm chart to update the Vault server Statefulset. It is important to understand +how to [generally upgrade Vault](/docs/upgrading.html) before reading this +section. + +The Vault Statefulset uses `OnDelete` update strategy. It is critical to use `OnDelete` instead +of `RollingUpdate` because standbys must be updated before the active primary. A +failover to an older version of Vault must always be avoided. + +!> **IMPORTANT NOTE:** Always back up your data before upgrading! Vault does not +make backward-compatibility guarantees for its data store. Simply replacing the +newly-installed Vault binary with the previous version will not cleanly +downgrade Vault, as upgrades may perform changes to the underlying data +structure that make the data incompatible with a downgrade. If you need to roll +back to a previous version of Vault, you should roll back your data store as +well. + +#### Upgrading Vault Servers + +To initiate the upgrade, change the `global.image` value to the +desired Vault version. For illustrative purposes, the example below will +use `vault:123.456`. + +```yaml +global: + image: "vault:123.456" +``` + +Next, run the upgrade. You should run this with `--dry-run` first to verify +the changes that will be sent to the Kubernetes cluster. + +``` +$ helm upgrade vault ./ +... +``` + +This should cause no changes (although the resource will be updated). If +everything is stable, `helm upgrade` can be run. + +The `helm upgrade` command should have updated the Statefulset template for +the Vault servers, however, no pods have been deleted. The pods must be manually +deleted to upgrade. Deleting the pods will not delete any persisted data. + +If Vault is not deployed using `ha` mode, the single Vault server may be deleted by +running: + +```bash +$ kubectl delete pod +``` + +If Vault is deployed using `ha` mode, the standby pods must be upgraded first. +To identify which pod is currently the active primary, run the following commad +on each Vault pod: + +```bash +$ kubectl exec -ti -- vault status | grep "HA Mode" +``` + +Next, delete every pod that is not the active primary: + +```bash +$ kubectl delete pod +``` + +If auto-unseal is not being used, the newly scheduled Vault standby pods will need +to be unsealed: + +```bash +$ kubectl exec -ti -- vault operator unseal +``` + +Finally, once the standby nodes have been updated and unsealed, delete the active +primary: + +```bash +$ kubectl delete pod +``` + +Similar to the standby nodes, the former primary will also need to be unsealed: + +```bash +$ kubectl exec -ti -- vault operator unseal +``` + +After a few moments the Vault cluster should elect a new active primary. The Vault +cluster is now upgraded! + + +## Architecture + +We recommend running Vault on Kubernetes with the same +[general architecture](/docs/internals/architecture.html) +as running it anywhere else. There are some benefits Kubernetes can provide +that eases operating a Vault cluster and we document those below. The standard +[production deployment guide](https://learn.hashicorp.com/vault/day-one/production-hardening) is still an +important read even if running Vault within Kubernetes. + +### Production Deployment Checklist + +*End-to-End TLS.* Vault should always be used with TLS in production. If +intermediate load balancers or reverse proxies are used to front Vault, +they should not terminate TLS. This way traffic is always encrypted in transit +to Vault and minimizes risks introduced by intermediate layers. See the +[official documentation](/docs/platform/k8s/helm.html#standalone-server-with-tls) +for example on configuring Vault Helm to use TLS. + +*Single Tenancy.* Vault should be the only main process running on a machine. +This reduces the risk that another process running on the same machine is +compromised and can interact with Vault. This can be accomplished by using Vault +Helm's `affinity` configurable. See the +[official documentation](/docs/platform/k8s/helm.html#highly-available-vault-cluster-with-consul) +for example on configuring Vault Helm to use affinity rules. + +*Enable Auditing.* Vault supports several auditing backends. Enabling auditing +provides a history of all operations performed by Vault and provides a forensics +trail in the case of misuse or compromise. Audit logs securely hash any sensitive +data, but access should still be restricted to prevent any unintended disclosures. +Vault Helm includes a configurable `auditStorage` option that will provision a persistent +volume to store audit logs. See the +[official documentation](/docs/platform/k8s/helm.html#standalone-server-with-audit-storage) +for an example on configuring Vault Helm to use auditing. + +*Immutable Upgrades.* Vault relies on an external storage backend for persistence, +and this decoupling allows the servers running Vault to be managed immutably. +When upgrading to new versions, new servers with the upgraded version of Vault +are brought online. They are attached to the same shared storage backend and +unsealed. Then the old servers are destroyed. This reduces the need for remote +access and upgrade orchestration which may introduce security gaps. See the +[upgrade section](/docs/platform/k8s/run.html#how-to) for instructions +on upgrading Vault on Kubernetes. + +*Upgrade Frequently.* Vault is actively developed, and updating frequently is +important to incorporate security fixes and any changes in default settings such +as key lengths or cipher suites. Subscribe to the Vault mailing list and +GitHub CHANGELOG for updates. + +*Restrict Storage Access.* Vault encrypts all data at rest, regardless of which +storage backend is used. Although the data is encrypted, an attacker with arbitrary +control can cause data corruption or loss by modifying or deleting keys. Access +to the storage backend should be restricted to only Vault to avoid unauthorized +access or operations. diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 75d4cc793..e63239c2b 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -320,6 +320,19 @@ ] }, '----------------', + { + category: 'platform', + content: [ + { + category: 'k8s', + content: [ + 'helm', + 'run' + ] + } + ] + }, + '----------------', { category: 'upgrading', content: [