Skip to content

Commit

Permalink
Vault i Kubernetes
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudowski committed Feb 27, 2020
1 parent c660d49 commit 8f4763d
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 0 deletions.
200 changes: 200 additions & 0 deletions sezon-2/7-vault/README.md
@@ -0,0 +1,200 @@
# Vault na Kubernetes

Znajdziesz tutaj komendy do uruchomienia Vault.

## 1. Instalacja Vault z Helm Chart

```shell
CHARTDIR=/tmp/vault-helm

git clone https://github.com/hashicorp/vault-helm $CHARTDIR

DNSDOMAIN="$(minikube ip).nip.io"

helm install vault -f vault-values.yaml \
--set server.ingress.hosts[0].host=vault.${DNSDOMAIN} \
$CHARTDIR

echo http://vault.${DNSDOMAIN}


cat << EOF
##################
# Komenda do zalogowania na poda z vaultem
kubectl exec -ti vault-0 sh
# Inicjalizacja
vault operator init
# NIE ZAPOMNIJ zapisać informacji które powyższa komenda zwróci!
# Użyj 3 tokenów do "odpieczętowania" vaulta komendą
vault operator unseal
# Eksport zmiennych na twoim kliencie
export VAULT_ADDR=http://vault.${DNSDOMAIN}
export VAULT_TOKEN=<ROOT_TOKEN_GENERATED_DURING_INIT>
EOF
```

## 2. Konfiguracja Vaulta

*Oparte głównie na wpisie z oficjalnego bloga https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar*


```shell
## Część Kubernetesowa - wykonaj z poda vaulta

## Potrzebujesz też tokenu root:
## export VAULT_TOKEN=<ROOT_TOKEN>

cat <<EOF > /home/vault/app-policy.hcl
path "secret*" {
capabilities = ["read"]
}
EOF

vault policy write app /home/vault/app-policy.hcl

vault auth enable kubernetes

vault write auth/kubernetes/config \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_host=https://${KUBERNETES_PORT_443_TCP_ADDR}:443 \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt


# allow access from all namespaces with 'app' sa only
vault write auth/kubernetes/role/myapp \
bound_service_account_names=app \
bound_service_account_namespaces='*' \
policies=app \
ttl=1h

# not enabled by default?
vault secrets enable -path=secret kv

# create secret

vault kv put secret/helloworld username=hellovault password=P@ssw0rd123
```

## 3. Instalacja aplikacji

```shell
kubectl apply -f krazy-cow.yaml
```

Weryfikacja - nie powinno być żadnych danych w `/vault/secrets`:

```shell
kubectl iexec krazy-cow -- ls -l /vault/secrets
```

Dodanie anotacji agenta vaulta do aplikacji:

```shell
kubectl patch deployment krazy-cow --patch "$(cat krazy-cow-patch.yaml)"
```

Ponowna weryfikacja

```shell
kubectl iexec krazy-cow -- ls -l /vault/secrets
kubectl iexec krazy-cow -- cat /vault/secrets/helloworld
```

Zmiana szablonu dla wynikowego pliku:

```shell
kubectl patch deployment krazy-cow --patch "$(cat krazy-cow-patch2.yaml)"
```

## 4. Vault i dynamiczne poświadczenia (credentials) do bazy danych

Instalacja bazy

```shell
helm install mydb \
--set postgresqlPassword=secretpassword,postgresqlDatabase=mydatabase \
--set service.type=NodePort,service.nodePort=32543 \
stable/postgresql
```

Włączenie silnika obsługi baz danych na vault

```shell
vault secrets enable database
```


Konfiguracja połączenia do bazy z vaulta

```shell
vault write database/config/postgresql \
plugin_name=postgresql-database-plugin \
allowed_roles=readonly \
connection_url=postgresql://postgres:secretpassword@$(minikube ip):32543/postgres?sslmode=disable
```

Utworzenie szablonu roli, którą będzie tworzył vault na bazie danych

```shell
cat << EOF > /tmp/vault-postgres.sql
CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}";
EOF

vault write database/roles/readonly db_name=postgresql \
creation_statements=@/tmp/vault-postgres.sql \
default_ttl=30s max_ttl=60s
```

Utworzenie polityki zezwalającej na pobieranie danych logowania do bazy

```shell
cat << EOF > /tmp/postgres-policy.hcl
path "database/creds/readonly" {
capabilities = [ "read" ]
}
EOF

vault policy write dbapps /tmp/postgres-policy.hcl


vault write auth/kubernetes/role/myapp \
bound_service_account_names=app \
bound_service_account_namespaces='*' \
policies=app,dbapps \
ttl=1h
```

### Weryfikacja

Pobranie tokena

```shell
APP_TOKEN=$(vault token create -policy="dbapps" -field=token)
VAULT_TOKEN="$APP_TOKEN" vault read database/creds/readonly
```

Uruchomienie testowego kontenera z postgresql

```shell
kubectl run -i --tty --rm debug --image=postgres:alpine --restart=Never -- sh
```

Dodanie aplikacji z konfiguracją

```shell
kubectl apply -f krazy-cow.yaml
kubectl patch deployment krazy-cow --patch "$(cat krazy-cow-patch3.yaml)"
```

Dane do logowania powinny być w `/vault/secrets` wewnątrz poda.
7 changes: 7 additions & 0 deletions sezon-2/7-vault/krazy-cow-patch.yaml
@@ -0,0 +1,7 @@
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-helloworld: "secret/helloworld"
vault.hashicorp.com/role: "myapp"
11 changes: 11 additions & 0 deletions sezon-2/7-vault/krazy-cow-patch2.yaml
@@ -0,0 +1,11 @@
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-helloworld: "secret/helloworld"
vault.hashicorp.com/role: "myapp"
vault.hashicorp.com/agent-inject-template-helloworld: |
{{- with secret "secret/helloworld" -}}
{{ .Data.username }}:{{ .Data.password }}
{{- end }}
7 changes: 7 additions & 0 deletions sezon-2/7-vault/krazy-cow-patch3.yaml
@@ -0,0 +1,7 @@
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-dbcreds: "database/creds/readonly"
vault.hashicorp.com/role: "myapp"
29 changes: 29 additions & 0 deletions sezon-2/7-vault/krazy-cow.yaml
@@ -0,0 +1,29 @@
# app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: krazy-cow
labels:
app: vault-agent-demo
spec:
selector:
matchLabels:
app: vault-agent-demo
replicas: 1
template:
metadata:
annotations:
labels:
app: vault-agent-demo
spec:
serviceAccountName: app
containers:
- name: app
image: cloudowski/krazy-cow:0.4.1
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: app
labels:
app: vault-agent-demo
44 changes: 44 additions & 0 deletions sezon-2/7-vault/vault-values.yaml
@@ -0,0 +1,44 @@
server:
ingress:
enabled: true
hosts:
- host: chart-example.local
paths:
- /

authDelegator:
enabled: true

dataStorage:
enabled: true
size: 1Gi
storageClass: null

dev:
enabled: false

# past a single replica.
standalone:
enabled: "true"

# config is a raw string of default configuration when using a Stateful
# deployment. Default is to use a PersistentVolumeClaim mounted at /vault/data
# and store data there. This is only used when using a Replica count of 1, and
# using a stateful set. This should be HCL.
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "file" {
path = "/vault/data"
}
ui:
enabled: true
serviceType: "ClusterIP"
serviceNodePort: null
externalPort: 8200

0 comments on commit 8f4763d

Please sign in to comment.