Integrate a Kubernetes cluster with an external Vault

Prerequisites

Start Vault

Use this script to create a external vault server on a linux hosts.


vault server -dev -dev-root-token-id password -dev-listen-address 0.0.0.0:8200 > vault.log 2>&1 &

export VAULT_ADDR=http://0.0.0.0:8200

vault login password

vault kv put secret/devwebapp/config username='giraffe' password='salsa'

Install the vault helm chart

  1. Add Vault helm repo
helm repo add hashicorp https://helm.releases.hashicorp.com
  1. Install the latest version of the Vault agent running in external mode.
helm install vault hashicorp/vault \
    --create-namespace --namespace vault
    --set "global.externalVaultAddr=${VAULT_ADDR}"
  1. Create a long-lived token for vault serviceaccount.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: vault-token-g955r
  namespace: vault
  annotations:
    kubernetes.io/service-account.name: vault
type: kubernetes.io/service-account-token
EOF

Configure kubernetes auth method

  1. Create ServiceAccount in default namespace
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: internal-app
  namespace: default
EOF

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: internal-app2
  namespace: default
EOF
  1. Create new kubernetes auth method
export VAULT_ADDR=http://0.0.0.0:8200
vault auth enable kubernetes

# token name of vault serviceaccount
VAULT_SECRET_NAME=$(kubectl get secrets -n vault --output=json | jq -r '.items[].metadata | select(.name|startswith("vault-token-")).name')

# token of vault serviceaccount
TOKEN_REVIEW_JWT=$(kubectl get secret $VAULT_SECRET_NAME -n vault --output='go-template=' | base64 --decode)

# ca cert of kubernetes cluster
KUBE_CA_CERT=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.certificate-authority-data}' | base64 --decode)

# URL of kubernetes cluster
KUBE_HOST=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.server}')

# Configure the Kubernetes authentication method to use the service account token and kubernetes host, etc.
vault write auth/kubernetes/config \
     token_reviewer_jwt="$TOKEN_REVIEW_JWT" \
     kubernetes_host="$KUBE_HOST" \
     kubernetes_ca_cert="$KUBE_CA_CERT" \
     issuer="https://kubernetes.default.svc.cluster.local"

# Create a vault policy
vault policy write devwebapp - <<EOF
path "secret/data/devwebapp/config" {
  capabilities = ["read"]
}
EOF

# Create two kubernetes authentication role.
vault write auth/kubernetes/role/devweb-app \
     bound_service_account_names=internal-app \
     bound_service_account_namespaces=default \
     policies=devwebapp \
     ttl=24h

vault write auth/kubernetes/role/devweb-app2 \
     bound_service_account_names=internal-app2 \
     bound_service_account_namespaces=default \
     policies=devwebapp \
     ttl=24h

Create two exmaple applications

After we setup the auth method for Vault server with two different roles that bind to kubernetes service accout, we can create two pods that use different service account to retrieve vault secrets.

apiVersion: v1
kind: Pod
metadata:
  name: devwebapp-with-annotations
  labels:
    app: devwebapp-with-annotations
  annotations:
    vault.hashicorp.com/agent-inject: 'true'
    vault.hashicorp.com/role: 'devweb-app'
    vault.hashicorp.com/agent-inject-secret-credentials.txt: 'secret/data/devwebapp/config'
    vault.hashicorp.com/secret-volume-path-credentials.txt: '/tmp'
spec:
  serviceAccountName: internal-app
  containers:
    - name: app
      image: burtlo/devwebapp-ruby:k8s
---
apiVersion: v1
kind: Pod
metadata:
  name: devwebapp2-with-annotations
  labels:
    app: devwebapp2-with-annotations
  annotations:
    vault.hashicorp.com/agent-inject: 'true'
    vault.hashicorp.com/role: 'devweb-app2'
    vault.hashicorp.com/agent-inject-secret-credentials.txt: 'secret/data/devwebapp/config'
    vault.hashicorp.com/secret-volume-path-credentials.txt: '/tmp'
spec:
  serviceAccountName: internal-app2
  containers:
    - name: app
      image: burtlo/devwebapp-ruby:k8s
Tags: kubernetes
Share: X (Twitter) Facebook LinkedIn