Vault Inject Secret to Application Pods
Solution 1: Deployment Vault Agent Injector
- see: https://developer.hashicorp.com/vault/docs/platform/k8s/helm/examples/injector-tls-cert-manager#create-a-certificate-authority-ca
- Notice: Only support watching the same namespace by default. see to: https://github.com/hashicorp/vault-k8s/blob/v1.5.0/deploy/injector-mutating-webhook.yaml#L29-L30
- Prerequisite refer to: Solution 2: Self-Hosting (PKI)
CA
Issuer
kubectl -n default apply -f - <<'EOF'
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: vault-agent-cert
spec:
isCA: false
commonName: "Vault Agent Certificate"
secretName: vault-agent-tls
duration: 24h
renewBefore: 144m # roughly 10% of 24h
privateKey:
algorithm: ECDSA
size: 384
issuerRef:
name: root-ca-issuer
kind: ClusterIssuer
group: cert-manager.io
subject:
organizations:
- "Vault Team of Example Enterprise, Inc."
organizationalUnits:
- "Security Operations"
countries:
- "US"
- "CN"
localities:
- "San Francisco"
provinces:
- "California"
- "Hongkong"
dnsNames:
- localhost
- httpbin
- httpbin.default
- httpbin.default.svc
- httpbin.default.svc.cluster.local
ipAddresses:
- 127.0.0.1
emailAddresses:
- securityadmin@myapp.com
EOF
kubectl -n default get certificate,secret
Configure the Secret Engine on Vault Server UI
Deployment the Vault Agent Injector
- https://github1s.com/hashicorp/vault-helm/blob/main/values.yaml#L240-L241
- If you need to customize the vault injector webhook CA, use the following parameters, but this generally not required and serviceAccount is also used by default.
--set injector.certs.secretName=vault-injector-tls
--set injector.certs.caBundle=ca.crt
--set injector.webhook.annotations="cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/vault-injector-ca-cert"
kubectl delete clusterrole vault-injector-agent-injector-clusterrole
kubectl delete clusterrolebinding vault-injector-agent-injector-binding
kubectl delete clusterrolebinding vault-injector-server-binding
kubectl delete MutatingWebhookConfiguration vault-injector-agent-injector-cfg
helm -n default uninstall vault-injector
helm -n default upgrade --create-namespace -i \
vault-injector hashicorp/vault \
--set server.enabled=false \
--set ui.enabled=false \
--set injector.enabled=true \
--set injector.logLevel=trace \
--set injector.replicas=1 \
--set injector.leaderElector.enabled=false \
--set injector.image.repository=registry.cn-shenzhen.aliyuncs.com/wl4g-k8s/hashicorp_vault-k8s \
--set injector.image.tag=1.4.2 \
--set injector.agentImage.repository=registry.cn-shenzhen.aliyuncs.com/wl4g-k8s/hashicorp_vault \
--set injector.agentImage.tag=1.18.1
Deployment the Application Pods (TLS production)
- Refer to: https://developer.hashicorp.com/vault/docs/platform/k8s/injector/examples
- Notice: The default port
8201
is Raft cluster port, see to: https://github1s.com/hashicorp/vault/blob/v1.18.1/command/operator_raft_join.go#L52-L53
kubectl -n default apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: httpbin
template:
metadata:
labels:
app.kubernetes.io/name: httpbin
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-init-first: "true"
vault.hashicorp.com/agent-inject-status: "update"
vault.hashicorp.com/agent-pre-populate-only: "true"
#vault.hashicorp.com/agent-run-as-same-user: "true"
### Configuration of Inject PostgreSQL Secrets.
vault.hashicorp.com/secret-volume-path-postgresql: "/vault/secrets"
vault.hashicorp.com/agent-inject-file-postgresql: "postgresql-creds.sc"
vault.hashicorp.com/agent-inject-perms-postgresql: "0600"
vault.hashicorp.com/agent-inject-secret-postgresql: "database/1001-myapp/static-creds/postgresql-static"
vault.hashicorp.com/agent-inject-template-postgresql: |
{{- with secret "database/1001-myapp/static-creds/postgresql-static" }}
export PG_URL="postgres://{{ .Data.username }}:{{ .Data.password }}@10.0.0.101:35432/postgres?sslmode=disable"
{{- end }}
### Configuration of Inject Redis Secrets.
vault.hashicorp.com/secret-volume-path-redis: "/vault/secrets"
vault.hashicorp.com/agent-inject-file-redis: "redis-creds.sc"
vault.hashicorp.com/agent-inject-perms-redis: "0600"
vault.hashicorp.com/agent-inject-secret-redis: "kv/1001-myapp/redis-creds"
vault.hashicorp.com/agent-inject-template-redis: |
{{- with secret "kv/1001-myapp/redis-creds" }}
{{- range $k, $v := .Data.data }}
export {{ $k }}="{{ $v }}"
{{ end }}
{{- end }}
### Configuration of Authentication.
vault.hashicorp.com/auth-path: "auth/kubernetes/1001-myapp"
#vault.hashicorp.com/namespace: "ITID/1001-myapp" # by Vault Enterprise Edition
vault.hashicorp.com/role: "myapp-shared-role"
vault.hashicorp.com/ca-cert: "/vault/tls/ca.crt"
vault.hashicorp.com/client-cert: "/vault/tls/tls.crt"
vault.hashicorp.com/client-key: "/vault/tls/tls.key"
vault.hashicorp.com/tls-secret: "vault-agent-tls"
vault.hashicorp.com/service: "https://vault.vault-system.svc:8200"
spec:
containers:
- name: httpbin
image: registry.cn-shenzhen.aliyuncs.com/wl4g/mccutchen_go-httpbin:v2.15.0
imagePullPolicy: IfNotPresent
EOF
kubectl -n default get deploy/httpbin
Check the Injected Secret files of Application Pod
# Define the Tooling alias Commands.
nsentervolume=$'docker_nsentervolume_fn() { local container_id=$1; shift; docker run --rm \
--volumes-from "$container_id" --platform linux/amd64 registry.cn-shenzhen.aliyuncs.com/wl4g-k8s/toolbox-base \
/bin/sh -c "$*"}; docker_nsentervolume_fn'
# List of httpbin container vault-agent mounted secret files.
export CID=$(docker ps | grep httpbin | grep -v _POD_ | grep -v vault-agent | awk '{print $1}')
nsentervolume $CID ls -al /vault/secrets/
#drwxrwxrwt 2 root root 60 Nov 23 14:59 .
#drwxr-xr-x 1 root root 14 Nov 23 16:19 ..
#-rw------- 1 100 1000 81 Nov 23 17:59 postgresql-creds.sc
#-rw------- 1 100 1000 35 Nov 23 17:59 redis-creds.sc
nsentervolume $CID 'cat /vault/secrets/*'
#export PG_URL="postgres://vault:9A5xE5bPoww-94Z9hQl9@10.0.0.101:35432/postgres?sslmode=disable"
#export REDIS_PASSWORD="changeit"
-
Screenshot 1
-
Screenshot 2