Installation and integration of Hashicorp Vault on Kubernetes
Vault is a powerful secrets management tool that can be integrated with Kubernetes to provide secure and dynamic secrets management. In this article, we’ll explore how to install Vault in Kubernetes and how to integrate Vault secrets with Kubernetes annotations.
If you don’t know what Vault is, you can see it in this post: https://medium.com/p/41f5a2ddaa32
Installing Vault in Kubernetes
There are different ways to install Vault in Kubernetes, but one common method is using the Helm package manager. Helm simplifies the deployment process by providing a template-based system for creating Kubernetes manifests.
To install Vault in Kubernetes using Helm, follow these steps:
1.- Install Helm: Helm must be installed on your local machine to use it for installing Vault. Follow the official Helm installation guide for your operating system.
2.- Add the HashiCorp Helm repository: Run the following command to add the HashiCorp Helm repository to your Helm installation:
helm repo add hashicorp https://helm.releases.hashicorp.com
3.- Install Vault: Run the following command to install Vault in Kubernetes:
helm install vault hashicorp/vault \
--set "server.dev.enabled=true"
This command installs Vault with the development server enabled, which is useful for testing and development environments. In production environments, you should use a persistent storage backend like Amazon S3 or Azure Blob Storage.
Integrating Vault Secrets with Kubernetes Annotations
Once Vault is installed in Kubernetes, we can use it to manage secrets and integrate them with Kubernetes annotations. Kubernetes annotations are key-value pairs that can be added to Kubernetes objects like pods, deployments, and services. Annotations provide metadata about the object, which can be used for various purposes like monitoring, debugging, and configuration.
To integrate Vault secrets with Kubernetes annotations, follow these steps:
1.- Enable the Kubernetes authentication method in Vault: Run the following command to enable the Kubernetes authentication method in Vault:
vault auth enable kubernetes
2.- Configure the Kubernetes authentication method: Run the following command to configure the Kubernetes authentication method in Vault:
vault write auth/kubernetes/config \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_host="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT_HTTPS" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
This command configures the Kubernetes authentication method to use the Kubernetes service account token, the Kubernetes API server host and port, and the Kubernetes CA certificate.
3.- Create a Vault policy and token: Run the following command to create a Vault policy and token that grants read access to a secret path:
vault policy write myapp-policy - <<EOF
path "secret/myapp/*" {
capabilities = ["read"]
}
EOF
vault token create -policy=myapp-policy -ttl=1h
This command creates a Vault policy named myapp-policy that grants read access to secrets under the secret/myapp/ path, and a Vault token with the policy attached.
4.- Create a Kubernetes secret with the Vault token: Run the following command to create a Kubernetes secret with the Vault token:
kubectl create secret generic vault-auth \
--from-literal "token=$(vault print-token)"
This command creates a Kubernetes secret named vault-auth with the Vault token as a literal value.
5.- Add annotations to a Kubernetes object: Add the following annotations to a Kubernetes object like a pod or deployment to retrieve a secret from Vault and make it available as an environment variable:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-myapp-password: "secret/myapp/password"
vault.hashicorp.com/agent-inject-template-myapp-password: |
{{- with secret "secret/data/myapp-password" -}}
export MY_SECRET_PASSWORD={{ .Data.password }}
{{- end }}
6.- Deploy the Kubernetes object: Deploy the Kubernetes object with the annotations to retrieve the secret from Vault and make it available as an environment variable. The Vault agent sidecar container in the pod automatically retrieves the secret and injects it into the main container as an environment variable.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-myapp-password: "secret/myapp/password"
vault.hashicorp.com/agent-inject-template-myapp-password: |
{{- with secret "secret/myapp/password" }}
MYAPP_PASSWORD={{ .Data.password }}
{{- end }}
spec:
containers:
- name: myapp
image: myapp:v1
env:
- name: MYAPP_PASSWORD
valueFrom:
secretKeyRef:
name: vault-auth
key: token
- name: vault-agent
image: vault:1.7.1
command: ["/bin/sh", "-c"]
args:
- "vault agent -config /etc/vault/config.hcl"
volumeMounts:
- name: vault-config
mountPath: /etc/vault
volumes:
- name: vault-config
configMap:
name: vault-agent-config
This example deployment includes two containers, one for the main application (myapp) and another for the Vault agent sidecar. The annotations are added to the pod template metadata and specify the path of the secret in Vault and the template to retrieve the secret and inject it into the main container as an environment variable.
Conclusion
Integrating Vault with Kubernetes provides a secure and dynamic way to manage secrets in a Kubernetes environment. With Vault, secrets can be centrally managed and accessed through an API or UI, and Kubernetes annotations can be used to inject secrets into applications running in Kubernetes. By following the steps outlined in this article, you can easily install Vault in Kubernetes and integrate it with Kubernetes annotations to manage secrets for your applications.