Install Vault to Kubernetes with Integrated Storage
Running Vault on Kubernetes is generally the same as running it anywhere else. Kubernetes, as a container orchestration engine, eases some of the operational burdens and Helm charts provide the benefit of a refined interface when it comes to deploying Vault in a variety of different modes.
In this tutorial, you will set up Vault and its dependencies with a Helm chart. You will then integrate a web application that uses the Kubernetes service account token to authenticate with Vault and retrieve a secret.
Prerequisites
This tutorial requires the Kubernetes command-line interface (CLI) and the Helm CLI installed, minikube, the Vault Helm charts, the sample web application, and additional configuration to bring it all together.
First, follow the directions to install minikube, including VirtualBox or similar.
Next, install kubectl CLI and helm CLI.
NOTE: This tutorial was last tested in May 2022 on a macOS 12.2.1 using this configuration.
Docker version.
Display minikube version.
Helm version.
These are recommended software versions and the output displayed may vary depending on your environment and the software versions you use.
Start minikube
Minikube is a CLI tool that provisions and manages the lifecycle of single-node Kubernetes clusters running inside Virtual Machines (VM) on your local system.
Start a Kubernetes cluster.
The initialization process takes several minutes as it retrieves any necessary dependencies and executes various container images.
Verify the status of the minikube cluster.
Install the Vault Helm chart
Vault manages the secrets that are written to these mountable volumes. To provide these secrets a single Vault server is required. For this demonstration Vault can be run in development mode to automatically handle initialization, unsealing, and setup of a KV secrets engine.
Add the HashiCorp Helm repository.
Update all the repositories to ensure
helm
is aware of the latest versions.To verify, search repositories for vault in charts.
Create a file named
helm-vault-raft-values.yml
with the following contents:Recommendation
If you are using Prometheus for monitoring and alerting, we recommend to set the
cluster_name
in the HCL configuration. With the Vault Helm chart, this is accomplished with the config parameter.Install the latest version of the Vault Helm chart with Integrated Storage.
Example output:
This creates three Vault server instances with an Integrated Storage (Raft) backend.
The Vault pods and Vault Agent Injector pod are deployed in the default namespace.
Display all the pods within the default namespace. This may take a moment.
Initialize
vault-0
with one key share and one key threshold.The
operator init
command generates a root key that it disassembles into key shares-key-shares=1
and then sets the number of key shares required to unseal Vault-key-threshold=1
. These key shares are written to the output as unseal keys in JSON format-format=json
. Here the output is redirected to a file namedcluster-keys.json
.Display the unseal key found in
cluster-keys.json
.Insecure operation
Do not run an unsealed Vault in production with a single key share and a single key threshold. This approach is only used here to simplify the unsealing process for this demonstration.Create a variable named
VAULT_UNSEAL_KEY
to capture the Vault unseal key.After initialization, Vault is configured to know where and how to access the storage, but does not know how to decrypt any of it. Unsealing is the process of constructing the root key necessary to read the decryption key to decrypt the data, allowing access to the Vault.
Unseal Vault running on the
vault-0
pod.Insecure operation
Providing the unseal key with the command writes the key to your shell's history. This approach is only used here to simplify the unsealing process for this demonstration.The
operator unseal
command reports that Vault is initialized and unsealed.Example output:
The Vault server is initialized and unsealed.
Join the
vault-1
pod to the Raft cluster.Join the
vault-2
pod to the Raft cluster.Use the unseal key from above to unseal vault-1.
Use the unseal key from above to unseal vault-2.
Set a secret in Vault
The web application that you deploy in the Launch a web
application section, expects Vault to store a
username and password at the path secret/webapp/config
. To create this secret
requires you to login with the root token, enable the key-value secret
engine, and store a
secret username and password at that defined path.
Vault generated an initial root token when it was initialized.
Display the root token found in
cluster-keys.json
.Start an interactive shell session on the
vault-0
pod.Your system prompt is replaced with a new prompt
/ $
.Vault is now ready for you to login with the initial root token.
Vault requires clients to authenticate first before it allows any further actions. An unsealed Vault starts with the Token Auth Method enabled and generates an initial root token.
Login with the root token when prompted.
Enable an instance of the kv-v2 secrets engine at the path
secret
.Learn more
This tutorial focuses on Vault's integration with Kubernetes and not interacting with the key-value secrets engine. For more information refer to the Versioned Key/value secrets engine tutorial.
Create a secret at path
secret/webapp/config
with ausername
andpassword
.Verify that the secret is defined at the path
secret/webapp/config
.You successfully created the secret for the web application.
Exit the
vault-0
pod.
Configure Kubernetes authentication
The initial root token is a privileged user that can perform any operation at any path. The web application only requires the ability to read secrets defined at a single path. This application should authenticate and be granted a token with limited access.
We recommend that root tokens are used only for initial setup of an authentication method and policies. Afterwards they should be revoked. This tutorial does not show you how to revoke the root token.
Vault provides a Kubernetes authentication method that enables clients to authenticate with a Kubernetes Service Account Token.
Start an interactive shell session on the
vault-0
pod.Your system prompt is replaced with a new prompt
/ $
.Enable the Kubernetes authentication method.
Vault accepts this service token from any client within the Kubernetes cluster. During authentication, Vault verifies that the service account token is valid by querying a configured Kubernetes endpoint.
Configure the Kubernetes authentication method to use the location of the Kubernetes API.
For the best compatibility with recent Kubernetes versions, ensure you are using Vault v1.9.3 or greater.
Successful output from this command resembles this example:
The environment variable
KUBERNETES_PORT_443_TCP_ADDR
is defined and references the internal network address of the Kubernetes host.For a client to access the secret data defined, at
secret/webapp/config
, requires that the read capability be granted for the pathsecret/data/webapp/config
. This is an example of a policy. A policy defines a set of capabilities.Write out the policy named
webapp
that enables theread
capability for secrets at pathsecret/data/webapp/config
.Successful output from this command resembles this example:
Define an auth method role that uses the webapp policy. A role binds policies and environment parameters together to create a login for the web application.
Create a Kubernetes authentication role, named
webapp
, that connects the Kubernetes service account name andwebapp
policy.Successful output from this command resembles this example:
The role connects the Kubernetes service account,
vault
, and namespace,default
, with the Vault policy,webapp
. The tokens returned after authentication are valid for 24 hours.Exit the
vault-0
pod.
Launch a web application
You have created a web application, published it to DockerHub, and created a Kubernetes deployment that will run the application in your existing cluster. The example web application performs the single function of listening for HTTP requests. During a request it reads the Kubernetes service token, logs into Vault, and then requests the secret.
Use your preferred text editor and review the contents of
deployment-01-webapp.yml
.deployment-01-webapp.ymlThe web application deployment defines a list of environment variables.
JWT_PATH
sets the path of the JSON web token (JWT) issued by Kubernetes. This token is used by the web application to authenticate with Vault.VAULT_ADDR
sets the address of the Vault service. The Helm chart defined a Kubernetes service namedvault
that forwards requests to its endpoints (i.e. The pods namedvault-0
,vault-1
, andvault-2
).SERVICE_PORT
sets the port that the service listens for incoming HTTP requests.
Deploy the webapp in Kubernetes by applying the file
deployment-01-webapp.yml
.The webapp runs as a pod within the default namespace.
Get all the pods within the default namespace.
The webapp pod is displayed here as the pod prefixed with
webapp
.The deployment of the service requires the retrieval of the web application container from Docker Hub. This displays the STATUS of
ContainerCreating
. The pod reports that it is not ready (0/1
).Wait until the webapp pod is running and ready (
1/1
).The webapp pod runs an HTTP service that is listening on port 8080.
In another terminal, port forward all requests made to
http://localhost:8080
to the webapp pod on port 8080.In the original terminal, perform a
curl
request athttp://localhost:8080
.The web application running on port 8080 in the webapp pod:
- authenticates with the Kubernetes service account token
- receives a Vault token with the read capability at the
secret/data/webapp/config
path - retrieves the secrets from
secret/data/webapp/config
path - displays the secrets as JSON
Clean up
First, stop the running local Kubernetes cluster.
This deactivates minikube, and all pods still exist at this point.
Delete the local Kubernetes cluster.
Be aware that minikube delete
removes the minikube deployment including all pods. Be sure you want everything removed before continuing.
Next steps
You launched Vault in high-availability mode with a Helm chart. Learn more about the Vault Helm chart by reading the documentation or exploring the project source code.
Also, you can run vault on Kubernetes on different platforms. Explore setting up Vault in high-availability with Integrated Storage in the Vault Installation to Google Kubernetes Engine via Helm tutorial.
Then you deployed a web application that authenticated and requested a secret directly from Vault. Explore how pods can retrieve secrets through the Vault Injector service via annotations or secrets mounted on ephemeral volumes.