Secretos de Kubernetes con Hashicorp Vault & External Secrets Operator.

Secretos de Kubernetes con Hashicorp Vault & External Secrets Operator.

¿Como manejar los secretos con ESO, en Kubernetes?

En entradas anteriores vimos como manejar secretos de manera dinamica y estatica. En esta nueva entrada vamos a jugar con External Secrets Operator o ESO, para manejar secretos contra Hashicorp Vault. Una buena practica para que los desarrolladores no dejen los secretos en texto claro.

Este operador es capaz de conectarse a varias bóvedas de contraseñas, solo resta leer la documentación.

Este es un esquema que resumen lo que vamos a realizar. Para ello vamos a usar un cluster en minikube.

Instalación de Hashicorp Vault

Vamos a usar Helm Charts para la instalación y luego configuramos el cliente para agregar una key value. Aca les dejo el repositorio con los archivos de configuración necesarios.

helm repo add hashicorp https://helm.releases.hashicorp.com 
helm install vault hashicorp/vault --namespace vault --create-namespace -f hashicorp-vault/values.yaml

Si revisamos values.yaml vamos a ver que el entorno es Dev con un Token para la conexión. Lo ideal es que este token sea desplegado por nuestro pipeline, esto es meramente para el PoC.

kubectl port-forward vault-0 8200:8200 -n vault

Una vez realizado el comando hacemos el login y agregamos la entrada.

export VAULT_TOKEN="root"
export VAULT_ADDR='http://127.0.0.1:8200'

vault login -address=http://127.0.0.1:8200 -tls-skip-verify

vault kv put secret/dev/app username="admin" password="p4ssw0d"

Aca la entrada en UI.

Ahora instalamos External Secrets Operator.

helm repo add external-secrets https://charts.external-secrets.io

helm install external-secrets 
external-secrets/external-secrets 
--namespace external-secrets 
--create-namespace 
--set installCRDs=true

Ya una vez desplegado Vault y ESO, desplegamos el Secret para autenticar contra Vault y sumamos la dirección del pod, de Vault, en ClusterSecretStore.

---
apiVersion: v1
kind: Secret
metadata:
  name: vault-token-global
  namespace: external-secrets
stringData:
  # Solo para prueba, no usar en ambientes productivos.
  token: root

Actualizamos la dirección ip del ClusterIP.

Cambiamos el server a la dirección del pod vualt-0.

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: vault-backend-global
spec:
  provider:
    vault:
      server: "http://172.17.0.3:8200"
      path: secret
      version: v2
      auth:
        # Puntero al Secreto Token para accesar a Vault
        # https://www.vaultproject.io/docs/auth/token
        tokenSecretRef:
          name: "vault-token-global"
          key: "token"
          namespace: external-secrets

Ahora creamos un namespace app para desplegar el External Secret.

kubectl create ns app
namespace/app created

kubectl apply -f basic-secret.yaml -n app
externalsecret.external-secrets.io/basic-credentials created

El basic-secret.yaml contiene los siguientes campos.

apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
  name: basic-credentials
spec:
  refreshInterval: "15s" # Intervalo de Refresco
  secretStoreRef: # Accesso a la Boveda
    name: vault-backend-global
    kind: ClusterSecretStore
  target:
    name: basic-credentials
  data:
  - secretKey: password
    remoteRef:
      key: dev/app
      property: password

  - secretKey: username
    remoteRef:
      key: dev/app
      property: username

Revisamos...

Ahora podemos revisar como se genero el Secret para ser usado.

¡Ya tenemos ESO trabajando con Vault, para tener nuestros secretos de Kubernetes protegidos! Ahora a probarlo.