mirror of
https://github.com/marcel-dempers/docker-development-youtube-series.git
synced 2025-06-06 17:01:30 +00:00
Merge pull request #3 from marcel-dempers/hashicorpvault
Hashicorpvault
This commit is contained in:
commit
eeeb23d625
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,6 @@
|
|||||||
c#/src/bin/
|
c#/src/bin/
|
||||||
c#/src/obj/
|
c#/src/obj/
|
||||||
node_modules/
|
node_modules/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
*.pem
|
||||||
|
*.csr
|
||||||
|
39
hashicorp/vault/example-apps/basic-secret/deployment.yaml
Normal file
39
hashicorp/vault/example-apps/basic-secret/deployment.yaml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: basic-secret
|
||||||
|
labels:
|
||||||
|
app: basic-secret
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: basic-secret
|
||||||
|
replicas: 1
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
vault.hashicorp.com/agent-inject: "true"
|
||||||
|
vault.hashicorp.com/tls-skip-verify: "true"
|
||||||
|
vault.hashicorp.com/agent-inject-secret-helloworld: "secret/basic-secret/helloworld"
|
||||||
|
vault.hashicorp.com/agent-inject-template-helloworld: |
|
||||||
|
{{- with secret "secret/basic-secret/helloworld" -}}
|
||||||
|
{
|
||||||
|
"username" : "{{ .Data.username }}",
|
||||||
|
"password" : "{{ .Data.password }}"
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
vault.hashicorp.com/role: "basic-secret-role"
|
||||||
|
labels:
|
||||||
|
app: basic-secret
|
||||||
|
spec:
|
||||||
|
serviceAccountName: basic-secret
|
||||||
|
containers:
|
||||||
|
- name: app
|
||||||
|
image: jweissig/app:0.0.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: basic-secret
|
||||||
|
labels:
|
||||||
|
app: basic-secret
|
50
hashicorp/vault/example-apps/basic-secret/readme.md
Normal file
50
hashicorp/vault/example-apps/basic-secret/readme.md
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# Basic Secret Injection
|
||||||
|
|
||||||
|
|
||||||
|
In order for us to start using secrets in vault, we need to setup a policy.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
#Create a role for our app
|
||||||
|
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 sh
|
||||||
|
|
||||||
|
vault write auth/kubernetes/role/basic-secret-role \
|
||||||
|
bound_service_account_names=basic-secret \
|
||||||
|
bound_service_account_namespaces=vault-example \
|
||||||
|
policies=basic-secret-policy \
|
||||||
|
ttl=1h
|
||||||
|
```
|
||||||
|
|
||||||
|
The above maps our Kubernetes service account, used by our pod, to a policy.
|
||||||
|
Now lets create the policy to map our service account to a bunch of secrets
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 sh
|
||||||
|
cat <<EOF > /home/vault/app-policy.hcl
|
||||||
|
path "secret/basic-secret/*" {
|
||||||
|
capabilities = ["read"]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
vault policy write basic-secret-policy /home/vault/app-policy.hcl
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Now our service account for our pod can access all secrets under `secret/basic-secret/*`
|
||||||
|
Lets create some secrets.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 sh
|
||||||
|
vault secrets enable -path=secret/ kv
|
||||||
|
vault kv put secret/basic-secret/helloworld username=dbuser password=sUp3rS3cUr3P@ssw0rd
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Lets deploy our app and see if it works:
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example apply -f ./hashicorp/vault/example-apps/basic-secret/deployment.yaml
|
||||||
|
kubectl -n vault-example get pods
|
||||||
|
```
|
@ -0,0 +1,38 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dynamic-postgres
|
||||||
|
labels:
|
||||||
|
app: dynamic-postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dynamic-postgres
|
||||||
|
replicas: 1
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
vault.hashicorp.com/agent-inject: "true"
|
||||||
|
vault.hashicorp.com/tls-skip-verify: "true"
|
||||||
|
vault.hashicorp.com/agent-inject-secret-sql-role: "database/creds/sql-role"
|
||||||
|
vault.hashicorp.com/agent-inject-template-sql-role: |
|
||||||
|
{
|
||||||
|
{{- with secret "database/creds/sql-role" -}}
|
||||||
|
"db_connection": "host=postgres.postgress port=5432 user={{ .Data.username }} password={{ .Data.password }} dbname=postgresdb sslmode=disable"
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
vault.hashicorp.com/role: "sql-role"
|
||||||
|
labels:
|
||||||
|
app: dynamic-postgres
|
||||||
|
spec:
|
||||||
|
serviceAccountName: dynamic-postgres
|
||||||
|
containers:
|
||||||
|
- name: app
|
||||||
|
image: jweissig/app:0.0.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: dynamic-postgres
|
||||||
|
labels:
|
||||||
|
app: dynamic-postgres
|
33
hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml
Normal file
33
hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: pgadmin-config
|
||||||
|
labels:
|
||||||
|
app: pgadmin
|
||||||
|
data:
|
||||||
|
PGADMIN_DEFAULT_EMAIL: admin@admin.com
|
||||||
|
PGADMIN_DEFAULT_PASSWORD: admin123
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: pgadmin
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: pgadmin
|
||||||
|
replicas: 1
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: pgadmin
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: pgadmin
|
||||||
|
image: dpage/pgadmin4
|
||||||
|
imagePullPolicy: "IfNotPresent"
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: pgadmin-config
|
@ -0,0 +1,49 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: postgres-config
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
data:
|
||||||
|
POSTGRES_DB: postgresdb
|
||||||
|
POSTGRES_USER: postgresadmin
|
||||||
|
POSTGRES_PASSWORD: admin123
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres
|
||||||
|
replicas: 1
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: postgres:10.4
|
||||||
|
imagePullPolicy: "IfNotPresent"
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: postgres-config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
name: http
|
||||||
|
port: 5432
|
||||||
|
targetPort: 5432
|
80
hashicorp/vault/example-apps/dynamic-postgresql/readme.md
Normal file
80
hashicorp/vault/example-apps/dynamic-postgresql/readme.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Dynamic Secret Creation [PostgreSQL]
|
||||||
|
|
||||||
|
Deploy our test database
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl create ns postgres
|
||||||
|
kubectl -n postgres apply -f ./hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml
|
||||||
|
kubectl -n postgres apply -f ./hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml
|
||||||
|
kubectl -n postgres get pods
|
||||||
|
|
||||||
|
kubectl -n postgres exec -it <podname> bash
|
||||||
|
psql --username=postgresadmin postgresdb
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Enable the database engine
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 vault login
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 vault secrets enable database
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configure DB Credential creation
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 sh
|
||||||
|
|
||||||
|
vault write database/config/postgresdb \
|
||||||
|
plugin_name=postgresql-database-plugin \
|
||||||
|
allowed_roles="sql-role" \
|
||||||
|
connection_url="postgresql://{{username}}:{{password}}@postgres.postgres:5432/postgresdb?sslmode=disable" \
|
||||||
|
username="postgresadmin" \
|
||||||
|
password="admin123"
|
||||||
|
|
||||||
|
vault write database/roles/sql-role \
|
||||||
|
db_name=postgresdb \
|
||||||
|
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
|
||||||
|
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
|
||||||
|
default_ttl="1h" \
|
||||||
|
max_ttl="24h"
|
||||||
|
|
||||||
|
#test
|
||||||
|
vault read database/creds/sql-role
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example Application
|
||||||
|
|
||||||
|
Create a policy to control access to secrets
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 sh
|
||||||
|
|
||||||
|
cat <<EOF > /home/vault/postgres-app-policy.hcl
|
||||||
|
path "database/creds/sql-role" {
|
||||||
|
capabilities = ["read"]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
vault policy write postgres-app-policy /home/vault/postgres-app-policy.hcl
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Bind our role to a service account for our application
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 sh
|
||||||
|
|
||||||
|
vault write auth/kubernetes/role/sql-role \
|
||||||
|
bound_service_account_names=dynamic-postgres \
|
||||||
|
bound_service_account_namespaces=vault-example \
|
||||||
|
policies=postgres-app-policy \
|
||||||
|
ttl=1h
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
kubectl -n vault-example apply -f .\hashicorp\vault\example-apps\dynamic-postgresql\deployment.yaml
|
14
hashicorp/vault/injector/injector-clusterrole.yaml
Normal file
14
hashicorp/vault/injector/injector-clusterrole.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: vault-example-agent-injector-clusterrole
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
rules:
|
||||||
|
- apiGroups: ["admissionregistration.k8s.io"]
|
||||||
|
resources: ["mutatingwebhookconfigurations"]
|
||||||
|
verbs:
|
||||||
|
- "get"
|
||||||
|
- "list"
|
||||||
|
- "watch"
|
||||||
|
- "patch"
|
14
hashicorp/vault/injector/injector-clusterrolebinding.yaml
Normal file
14
hashicorp/vault/injector/injector-clusterrolebinding.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: vault-example-agent-injector-binding
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: vault-example-agent-injector-clusterrole
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: vault-example-agent-injector
|
||||||
|
namespace: vault-example
|
64
hashicorp/vault/injector/injector-deployment.yaml
Normal file
64
hashicorp/vault/injector/injector-deployment.yaml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: vault-example-agent-injector
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
component: webhook
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
component: webhook
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
component: webhook
|
||||||
|
spec:
|
||||||
|
serviceAccountName: vault-example-agent-injector
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsGroup: 1000
|
||||||
|
runAsUser: 100
|
||||||
|
containers:
|
||||||
|
- name: sidecar-injector
|
||||||
|
image: "hashicorp/vault-k8s:0.1.2"
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
env:
|
||||||
|
- name: AGENT_INJECT_LISTEN
|
||||||
|
value: ":8080"
|
||||||
|
- name: AGENT_INJECT_LOG_LEVEL
|
||||||
|
value: "info"
|
||||||
|
- name: AGENT_INJECT_VAULT_ADDR
|
||||||
|
value: https://vault-example.vault-example.svc:8200
|
||||||
|
- name: AGENT_INJECT_VAULT_IMAGE
|
||||||
|
value: "vault:1.3.1"
|
||||||
|
- name: AGENT_INJECT_TLS_AUTO
|
||||||
|
value: vault-example-agent-injector-cfg
|
||||||
|
- name: AGENT_INJECT_TLS_AUTO_HOSTS
|
||||||
|
value: vault-example-agent-injector-svc,vault-example-agent-injector-svc.vault-example,vault-example-agent-injector-svc.vault-example.svc
|
||||||
|
args:
|
||||||
|
- agent-inject
|
||||||
|
- 2>&1
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health/ready
|
||||||
|
port: 8080
|
||||||
|
scheme: HTTPS
|
||||||
|
failureThreshold: 2
|
||||||
|
initialDelaySeconds: 1
|
||||||
|
periodSeconds: 2
|
||||||
|
successThreshold: 1
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health/ready
|
||||||
|
port: 8080
|
||||||
|
scheme: HTTPS
|
||||||
|
failureThreshold: 2
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 2
|
||||||
|
successThreshold: 1
|
||||||
|
timeoutSeconds: 5
|
20
hashicorp/vault/injector/injector-mutating-webhook.yaml
Normal file
20
hashicorp/vault/injector/injector-mutating-webhook.yaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: admissionregistration.k8s.io/v1beta1
|
||||||
|
kind: MutatingWebhookConfiguration
|
||||||
|
metadata:
|
||||||
|
name: vault-example-agent-injector-cfg
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
webhooks:
|
||||||
|
- name: vault.hashicorp.com
|
||||||
|
clientConfig:
|
||||||
|
service:
|
||||||
|
name: vault-example-agent-injector-svc
|
||||||
|
namespace: vault-example
|
||||||
|
path: "/mutate"
|
||||||
|
caBundle: ""
|
||||||
|
rules:
|
||||||
|
- operations: ["CREATE", "UPDATE"]
|
||||||
|
apiGroups: [""]
|
||||||
|
apiVersions: ["v1"]
|
||||||
|
resources: ["pods"]
|
||||||
|
namespaceSelector:
|
13
hashicorp/vault/injector/injector-service.yaml
Normal file
13
hashicorp/vault/injector/injector-service.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: vault-example-agent-injector-svc
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 443
|
||||||
|
targetPort: 8080
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
||||||
|
component: webhook
|
6
hashicorp/vault/injector/injector-serviceaccount.yaml
Normal file
6
hashicorp/vault/injector/injector-serviceaccount.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: vault-example-agent-injector
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-agent-injector
|
115
hashicorp/vault/readme.md
Normal file
115
hashicorp/vault/readme.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# Hashicorp Vault Guide
|
||||||
|
|
||||||
|
# Vault
|
||||||
|
|
||||||
|
For this tutorial, I use Kuberentes 1.17
|
||||||
|
It's critical because we'll need certain [admission controllers](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) enabled.
|
||||||
|
|
||||||
|
To get 1.17 for Linux\Windows, just use `kind` since you can create a 1.17 with admissions all setup.
|
||||||
|
|
||||||
|
```
|
||||||
|
#Windows
|
||||||
|
kind create cluster --name vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62
|
||||||
|
|
||||||
|
#Linux
|
||||||
|
kind create cluster --name vault --kubeconfig ~/.kube/kind-vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62
|
||||||
|
```
|
||||||
|
|
||||||
|
## TLS End to End Encryption
|
||||||
|
|
||||||
|
VIDEO: <Coming-Soon>
|
||||||
|
See steps in `hashicorp/vault/tls/ssl_generate_self_signed.txt`
|
||||||
|
You'll need to generate TLS certs (or bring your own)
|
||||||
|
Create base64 strings from the files, place it in the `server-tls-secret.yaml` and apply it.
|
||||||
|
Remember not to check-in your TLS to GIT :)
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl create ns vault-example
|
||||||
|
kubectl -n vault-example apply -f ./hashicorp/vault/server/
|
||||||
|
kubectl -n vault-example get pods
|
||||||
|
```
|
||||||
|
|
||||||
|
## Storage
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example get pvc
|
||||||
|
```
|
||||||
|
ensure vault-claim is bound, if not, `kubectl -n vault-example describe pvc vault-claim`
|
||||||
|
ensure correct storage class is used for your cluster.
|
||||||
|
if you need to change the storage class, deleve the pvc , edit YAML and re-apply
|
||||||
|
|
||||||
|
## Initialising Vault
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 vault operator init
|
||||||
|
#unseal 3 times
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 vault operator unseal
|
||||||
|
kubectl -n vault-example get pods
|
||||||
|
```
|
||||||
|
|
||||||
|
## Depploy the Injector
|
||||||
|
|
||||||
|
VIDEO: <Coming-Soon>
|
||||||
|
|
||||||
|
Injector allows pods to automatically get secrets from the vault.
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example apply -f ./hashicorp/vault/injector/
|
||||||
|
kubectl -n vault-example get pods
|
||||||
|
```
|
||||||
|
|
||||||
|
## Injector Kubernetes Auth Policy
|
||||||
|
|
||||||
|
For the injector to be authorised to access vault, we need to enable K8s auth
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 vault login
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 vault auth enable kubernetes
|
||||||
|
|
||||||
|
|
||||||
|
kubectl -n vault-example exec -it vault-example-0 sh
|
||||||
|
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
|
||||||
|
exit
|
||||||
|
|
||||||
|
kubectl -n vault-example get pods
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
|
||||||
|
So we have a vault, an injector, TLS end to end, stateful storage.
|
||||||
|
The injector can now inject secrets for pods from the vault.
|
||||||
|
|
||||||
|
Now we are ready to use the platform for different types of secrets:
|
||||||
|
|
||||||
|
## Secret Injection Guides
|
||||||
|
|
||||||
|
I've broken this down into basic guides to avoid this document from becoming too large.
|
||||||
|
|
||||||
|
### Basic Secrets
|
||||||
|
|
||||||
|
Objective:
|
||||||
|
----------
|
||||||
|
* Let's create a basic secret in vault manually
|
||||||
|
* Application consumes the secret automatically
|
||||||
|
|
||||||
|
[Try it](./example-apps/basic-secret/readme.md)
|
||||||
|
|
||||||
|
### Dynamic Secrets: Postgres
|
||||||
|
|
||||||
|
Objective:
|
||||||
|
----------
|
||||||
|
* We have a Postgres Database
|
||||||
|
* Let's delegate Vault to manage life cycles of our database credentials
|
||||||
|
* Deploy an app, that automatically gets it's credentials from vault
|
||||||
|
|
||||||
|
[Try it](./example-apps/basic-secret/readme.md)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
14
hashicorp/vault/server/server-clusterrolebinding.yaml
Normal file
14
hashicorp/vault/server/server-clusterrolebinding.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: vault-example-server-binding
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: system:auth-delegator
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: vault-example
|
||||||
|
namespace: vault-example
|
20
hashicorp/vault/server/server-config-configmap.yaml
Normal file
20
hashicorp/vault/server/server-config-configmap.yaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: vault-example-config
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
data:
|
||||||
|
extraconfig-from-values.hcl: |-
|
||||||
|
disable_mlock = true
|
||||||
|
ui = true
|
||||||
|
listener "tcp" {
|
||||||
|
address = "0.0.0.0:8200"
|
||||||
|
tls_cert_file = "/vault/ssl/vault-example.pem"
|
||||||
|
tls_key_file = "/vault/ssl/vault-example-key.pem"
|
||||||
|
tls_min_version = "tls12"
|
||||||
|
cluster_address = "[::]:8201"
|
||||||
|
}
|
||||||
|
storage "file" {
|
||||||
|
path = "/vault/data"
|
||||||
|
}
|
22
hashicorp/vault/server/server-disruptionbudget.yaml
Normal file
22
hashicorp/vault/server/server-disruptionbudget.yaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# {{ template "vault.mode" . }}
|
||||||
|
# {{- if and (and (eq (.Values.global.enabled | toString) "true") (eq .mode "ha")) (eq (.Values.server.ha.disruptionBudget.enabled | toString) "true") -}}
|
||||||
|
# # PodDisruptionBudget to prevent degrading the server cluster through
|
||||||
|
# # voluntary cluster changes.
|
||||||
|
# apiVersion: policy/v1beta1
|
||||||
|
# kind: PodDisruptionBudget
|
||||||
|
# metadata:
|
||||||
|
# name: {{ template "vault.fullname" . }}
|
||||||
|
# namespace: {{ .Release.Namespace }}
|
||||||
|
# labels:
|
||||||
|
# helm.sh/chart: {{ include "vault.chart" . }}
|
||||||
|
# app.kubernetes.io/name: {{ include "vault.name" . }}
|
||||||
|
# app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
# app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
# spec:
|
||||||
|
# maxUnavailable: {{ template "vault.pdb.maxUnavailable" . }}
|
||||||
|
# selector:
|
||||||
|
# matchLabels:
|
||||||
|
# app.kubernetes.io/name: {{ include "vault.name" . }}
|
||||||
|
# app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
# component: server
|
||||||
|
# {{- end -}}
|
44
hashicorp/vault/server/server-ingress.yaml
Normal file
44
hashicorp/vault/server/server-ingress.yaml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# {{- if .Values.server.ingress.enabled -}}
|
||||||
|
# {{- $serviceName := include "vault.fullname" . -}}
|
||||||
|
# {{- $servicePort := .Values.server.service.port -}}
|
||||||
|
# apiVersion: extensions/v1beta1
|
||||||
|
# kind: Ingress
|
||||||
|
# metadata:
|
||||||
|
# name: {{ template "vault.fullname" . }}
|
||||||
|
# namespace: {{ .Release.Namespace }}
|
||||||
|
# labels:
|
||||||
|
# helm.sh/chart: {{ include "vault.chart" . }}
|
||||||
|
# app.kubernetes.io/name: {{ include "vault.name" . }}
|
||||||
|
# app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
# app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
# {{- with .Values.server.ingress.labels }}
|
||||||
|
# {{- toYaml . | nindent 4 }}
|
||||||
|
# {{- end }}
|
||||||
|
# {{- with .Values.server.ingress.annotations }}
|
||||||
|
# annotations:
|
||||||
|
# {{- toYaml . | nindent 4 }}
|
||||||
|
# {{- end }}
|
||||||
|
# spec:
|
||||||
|
# {{- if .Values.server.ingress.tls }}
|
||||||
|
# tls:
|
||||||
|
# {{- range .Values.server.ingress.tls }}
|
||||||
|
# - hosts:
|
||||||
|
# {{- range .hosts }}
|
||||||
|
# - {{ . | quote }}
|
||||||
|
# {{- end }}
|
||||||
|
# secretName: {{ .secretName }}
|
||||||
|
# {{- end }}
|
||||||
|
# {{- end }}
|
||||||
|
# rules:
|
||||||
|
# {{- range .Values.server.ingress.hosts }}
|
||||||
|
# - host: {{ .host | quote }}
|
||||||
|
# http:
|
||||||
|
# paths:
|
||||||
|
# {{- range .paths }}
|
||||||
|
# - path: {{ . }}
|
||||||
|
# backend:
|
||||||
|
# serviceName: {{ $serviceName }}
|
||||||
|
# servicePort: {{ $servicePort }}
|
||||||
|
# {{- end }}
|
||||||
|
# {{- end }}
|
||||||
|
# {{- end }}
|
14
hashicorp/vault/server/server-pv.yaml
Normal file
14
hashicorp/vault/server/server-pv.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: vault
|
||||||
|
labels:
|
||||||
|
type: local
|
||||||
|
spec:
|
||||||
|
storageClassName: manual
|
||||||
|
capacity:
|
||||||
|
storage: 1Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
hostPath:
|
||||||
|
path: "/mnt/data"
|
12
hashicorp/vault/server/server-pvc.yaml
Normal file
12
hashicorp/vault/server/server-pvc.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: vault-claim
|
||||||
|
spec:
|
||||||
|
storageClassName: standard
|
||||||
|
#storageClassName: hostpath
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
25
hashicorp/vault/server/server-service.yaml
Normal file
25
hashicorp/vault/server/server-service.yaml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: vault-example
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
annotations:
|
||||||
|
# This must be set in addition to publishNotReadyAddresses due
|
||||||
|
# to an open issue where it may not work:
|
||||||
|
# https://github.com/kubernetes/kubernetes/issues/58662
|
||||||
|
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
||||||
|
spec:
|
||||||
|
# We want the servers to become available even if they're not ready
|
||||||
|
# since this DNS is also used for join operations.
|
||||||
|
publishNotReadyAddresses: true
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8200
|
||||||
|
targetPort: 8200
|
||||||
|
- name: internal
|
||||||
|
port: 8201
|
||||||
|
targetPort: 8201
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
component: server
|
6
hashicorp/vault/server/server-serviceaccount.yaml
Normal file
6
hashicorp/vault/server/server-serviceaccount.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: vault-example
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
132
hashicorp/vault/server/server-statefulset.yaml
Normal file
132
hashicorp/vault/server/server-statefulset.yaml
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: vault-example
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
spec:
|
||||||
|
serviceName: vault-example
|
||||||
|
podManagementPolicy: Parallel
|
||||||
|
replicas: 1
|
||||||
|
updateStrategy:
|
||||||
|
type: "OnDelete"
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
component: server
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
component: server
|
||||||
|
spec:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
component: server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
terminationGracePeriodSeconds: 10
|
||||||
|
serviceAccountName: vault-example
|
||||||
|
shareProcessNamespace: true
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: vault-example-config
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: vault-claim
|
||||||
|
- name: tls-secret
|
||||||
|
secret:
|
||||||
|
secretName: vault-example-tls-secret
|
||||||
|
initContainers:
|
||||||
|
- name: setupperms
|
||||||
|
image: alpine:latest
|
||||||
|
command: ['sh', '-c', 'echo The app is running! && chown 100 /vault/data && ls -l /vault/']
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /vault/data
|
||||||
|
containers:
|
||||||
|
- name: vault
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsGroup: 1000
|
||||||
|
runAsUser: 100
|
||||||
|
capabilities:
|
||||||
|
add: ["IPC_LOCK"]
|
||||||
|
image: vault:1.3.1
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command:
|
||||||
|
- "/bin/sh"
|
||||||
|
- "-ec"
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
sed -E "s/HOST_IP/${HOST_IP?}/g" /vault/config/extraconfig-from-values.hcl > /tmp/storageconfig.hcl;
|
||||||
|
sed -Ei "s/POD_IP/${POD_IP?}/g" /tmp/storageconfig.hcl;
|
||||||
|
/usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/storageconfig.hcl
|
||||||
|
env:
|
||||||
|
- name: HOST_IP
|
||||||
|
valueFrom:
|
||||||
|
fieldRef:
|
||||||
|
fieldPath: status.hostIP
|
||||||
|
- name: POD_IP
|
||||||
|
valueFrom:
|
||||||
|
fieldRef:
|
||||||
|
fieldPath: status.podIP
|
||||||
|
- name: VAULT_ADDR
|
||||||
|
value: "https://127.0.0.1:8200"
|
||||||
|
- name: VAULT_API_ADDR
|
||||||
|
value: "https://$(POD_IP):8200"
|
||||||
|
- name: SKIP_CHOWN
|
||||||
|
value: "true"
|
||||||
|
- name: SKIP_SETCAP
|
||||||
|
value: "true"
|
||||||
|
- name: VAULT_CACERT
|
||||||
|
value: "/vault/ssl/ca.pem"
|
||||||
|
volumeMounts:
|
||||||
|
- name: tls-secret
|
||||||
|
mountPath: /vault/ssl
|
||||||
|
- name: config
|
||||||
|
mountPath: /vault/config
|
||||||
|
- name: data
|
||||||
|
mountPath: /vault/data
|
||||||
|
ports:
|
||||||
|
- containerPort: 8200
|
||||||
|
name: http
|
||||||
|
- containerPort: 8201
|
||||||
|
name: internal
|
||||||
|
- containerPort: 8202
|
||||||
|
name: replication
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: "/v1/sys/health?standbyok=true"
|
||||||
|
port: 8200
|
||||||
|
scheme: HTTPS
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: "/v1/sys/health?standbyok=true"
|
||||||
|
port: 8200
|
||||||
|
scheme: HTTPS
|
||||||
|
initialDelaySeconds: 60
|
||||||
|
periodSeconds: 3
|
||||||
|
successThreshold: 1
|
||||||
|
timeoutSeconds: 5
|
||||||
|
lifecycle:
|
||||||
|
# Vault container doesn't receive SIGTERM from Kubernetes
|
||||||
|
# and after the grace period ends, Kube sends SIGKILL. This
|
||||||
|
# causes issues with graceful shutdowns such as deregistering itself
|
||||||
|
# from Consul (zombie services).
|
||||||
|
preStop:
|
||||||
|
exec:
|
||||||
|
command: [
|
||||||
|
"/bin/sh", "-c",
|
||||||
|
# Adding a sleep here to give the pod eviction a
|
||||||
|
# chance to propagate, so requests will not be made
|
||||||
|
# to this pod while it's terminating
|
||||||
|
"sleep 5 && kill -SIGTERM $(pidof vault)",
|
||||||
|
]
|
||||||
|
|
9
hashicorp/vault/server/server-tls-secret.yaml
Normal file
9
hashicorp/vault/server/server-tls-secret.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: vault-example-tls-secret
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
vault-example.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVUVENDQXpXZ0F3SUJBZ0lVUkJaRmlSVXZnMTRJMFF6NkU0N3RJKzQ0R21Nd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF5Ck1qSTBOakF3V2hjTk1qRXdNekF5TWpJME5qQXdXakJ4TVFzd0NRWURWUVFHRXdKQlZURVJNQThHQTFVRUNCTUkKVm1samRHOXlhV0V4RWpBUUJnTlZCQWNUQ1UxbGJHSnZkWEp1WlRFVE1CRUdBMVVFQ2hNS1MzVmlaWEp1WlhSbApjekVPTUF3R0ExVUVDeE1GVm1GMWJIUXhGakFVQmdOVkJBTVREWFpoZFd4MExXVjRZVzF3YkdVd2dnRWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDa2JHVHNzSEQ1N3FKVXVIRElsZGpsZHM5QytOWEoKZXpFekNkbEQwdFlsZkVtQU56eURFdnZqbTJielI1MnlCd1VxRGZkeElMdE0xYlQzVFZjYWdSWkVNWkJOVnBtWgpxMUh6aXV1ZkhJMnNVN1pBcmxFbnNyV25oZEdrb0lPd0FyUGl6NXZFVDVJYXh1bXQzUlc3b2hEaE9QdnF0M3ZsCmtBTW9LZXJvMm9QdWp0K0hoQ3ppVDNkMGdjNUlGZWZVbkNiTDBQUmpselBXeFdzQ1ByWDJpYmJaZzkzb2IvNFgKOHlTRVVmZlk4eC9aaytWZDRqZXc3TnhzYllZdGFhUkwzU0M2My9FNERpMkgxSWVtQkRFOGNBNGZiVGpEZGVqKwp5WGcwR1BvYTlWUkVsUlJjMEU1RUQ0eG9IRFFoTFFCeFJqWHJoT1Z1Mmp2cXlvR25OSHQ4MDViQkFnTUJBQUdqCmdmc3dnZmd3RGdZRFZSMFBBUUgvQkFRREFnV2dNQjBHQTFVZEpRUVdNQlFHQ0NzR0FRVUZCd01CQmdnckJnRUYKQlFjREFqQU1CZ05WSFJNQkFmOEVBakFBTUIwR0ExVWREZ1FXQkJSeGg5U3JXTzhESlBkMjFqR091OW04d0Q1RQpSVEFmQmdOVkhTTUVHREFXZ0JUdDhnaDErS3pRZTc2N3I0cldaazhUU0FEc0REQjVCZ05WSFJFRWNqQndnZzEyCllYVnNkQzFsZUdGdGNHeGxnaTEyWVhWc2RDMWxlR0Z0Y0d4bExuWmhkV3gwTFdWNFlXMXdiR1V1YzNaakxtTnMKZFhOMFpYSXViRzlqWVd5Q0gzWmhkV3gwTFdWNFlXMXdiR1V1ZG1GMWJIUXRaWGhoYlhCc1pTNXpkbU9DQ1d4dgpZMkZzYUc5emRJY0Vmd0FBQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWJ1V3VIbkJORnVKbCttSDlwVndhCnhDcGd4NHNPVDdZeFhJS2RXZ1QrREpPanlKYjFFMkt2ZTJLdVoxZ0tiazZua3pMRzlGZXlDbUFzNmdPTW95cmkKZm1uQ0QzR2FDaFV1OTNlVEtudlgxNVl5UDdoYldNaHVqT3c3Tmo2U0VpQkxTL08yanhHRkwzb0p6cWFRQTFtSwp3bjNsWGY0QVkyUTFFSWxuQ0JvU3lRTFRZS0lISUlNbk5GaWJjRG5jY0lUbG1IdktKd2hVTFk2REJ0WGR0QXFYCmgvam1OSVF4THZNSzFwL0JnRzZrai9XNlBkdXNoZjdLaWgvWU9La3N2WlJWZlhnRjdNeUZQR2NESXNLVk05bHUKRUdRQnBYcDJFa0NjNElXMmM5MGlPaU9wRlZqb0ZvSDFOVHE0TGM5RFk0WDNNa0FSck5RVitoa016M2M5bitWbwpDdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
|
||||||
|
vault-example-key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBcEd4azdMQncrZTZpVkxod3lKWFk1WGJQUXZqVnlYc3hNd25aUTlMV0pYeEpnRGM4Cmd4TDc0NXRtODBlZHNnY0ZLZzMzY1NDN1ROVzA5MDFYR29FV1JER1FUVmFabWF0Ujg0cnJueHlOckZPMlFLNVIKSjdLMXA0WFJwS0NEc0FLejRzK2J4RStTR3NicHJkMFZ1NklRNFRqNzZyZDc1WkFES0NucTZOcUQ3bzdmaDRRcwo0azkzZElIT1NCWG4xSndteTlEMFk1Y3oxc1ZyQWo2MTlvbTIyWVBkNkcvK0YvTWtoRkgzMlBNZjJaUGxYZUkzCnNPemNiRzJHTFdta1M5MGd1dC94T0E0dGg5U0hwZ1F4UEhBT0gyMDR3M1hvL3NsNE5CajZHdlZVUkpVVVhOQk8KUkErTWFCdzBJUzBBY1VZMTY0VGxidG83NnNxQnB6UjdmTk9Xd1FJREFRQUJBb0lCQUJtY1NKd1ZYNE9PaC9wcQpRQ2IrTUNxTnR2clhoM1U2bXc4NEdYOVc5OFFlOTlQZ3hxd2o2TmdxL0g0b1NZZlJVQnljMEUzdXF6M3NpNk41CmlIZTRZNTk3bU41eS9yblExWkw1c0htNEdOa2VzT1NpUWtITXREN0R1VVBMUExmTnMvZEFIeU1Vd2MwcDdud0cKVTd4R0locnlwVXFLQ2VKWDdDWDFZWUdqaDZsQWwrYWR0YmFCaG1MSkRaek53WmZTcnlneVVPSnVjQXpOZCtxRwpxUXBmU1Y0c0Z6WGdQL3F3REtHcGg0anFYRnBFWkNCQzgyNE9rdUVQL0k2TVBrK3M5N2xjQXlmaWVGamRwT2E3CnVHUm1sV3BUNG9QZXNFTmF0YkNid1dsR25jamJtL1VxSldVRndJdjRFYlhlQ1JOVlRBM1VOSjlWMlRQVHFIRVUKb2FScFo0RUNnWUVBemhvWUR6R0c0S2xDdjAvclE4MDN5dHJwVzNqWEpOWlBNa1ZpcFNEUVV3MFp5SWpDeVdQWAo1WEhtaG1uc0I5YkpYbFpjK1pRTTBtalBYUGFOZXgzek1NSkp0L1VIM0Roc0FZL3dUOW0zQk1VbjhNeU4rWCt3CjFvUUhOMmZTSFhQNUx6bSs5YWQwUGpIRkVLOGlFQ2J1a1FmQkUwOGc0QjkyU3liN3F6VVM3RGNDZ1lFQXpEc2YKK0VTcUsvUEpleWs4Vmd1eTFISVNUY054d0htejVYcEpoTVYzRnRKTDJyM0l2dHloNGxiaExsenNlcHB5U3JsLwo3d3BlQW1aQklUblpia3dnVW9WVlR0VHdwT05TSEF1aEpNc1RFbzhBdnZGQ0hUQXMzbVQvcDBuT3hoTmgvbVdGCjJLSHgxakcxNUlBWHppWkZNNmhmY2lLcjV6QWZWMGpzR3hhRnlNY0NnWUJoWmUxMnlLWC81NTFXZ2JNaHdJcWMKUCtYRng0Nk1wd2FZTURnVTV6UHIrNlh5b2NiRG0zNTh2TjMvS1hGVXB3bFVucVdqZ0hhcXZNTTZJSDN0NzlKcwplWFNURGFYZ1NYMnBJMWVpdExXTCtJd09mT3lmT3R2Y0ZGckFzVHlYbEtYdXpuQlM4UWE3R1pRU2RXRTRsdDFwCkJtd1U3dkVQV1c3eXh3SnAvMVBvOHdLQmdGTVMwY1JKR2ZkYTZOL2lQQnE4RTNmN0ZwcnZIend0eFJGWkZzS2QKRi8zK2VNQjNaa3JNc0VUREZrR25wc0dRUldGRDUxZ3luVjdZZlRHb3VGcjNPRWFZMmNTQk5ZbTh0YytXbzJ1MQo5d0lialRBZUxzaDBxaXVrWmFHRWtrbGI1UVo0QVdQSEsvbjJxb2hSMmwwT2tDT2RINFhydUlVSHZCZmpIN2M5CkNCcE5Bb0dBYzdBUHh2UGRMemJlQkhmYTEvcFhkYm1VQ3hFd25YMEwwYWdSOUxpQk8wWmJmUHhwWFpKV2wrVDMKOXFMQWFwMFFQMFhpQU9RS3g2M1ZWcks1dDZRdzJUTlhSOWcrRnZDS1lwVkt0aHVvbU9yeUpTQ2pOTFFlVTBpTApKa1hVd3lPK0lhampVNVdCSk1lWSt1cTlFaW9jaUdNRU1ONDBWQUZhdzhTUnhaVlA4SDA9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
|
||||||
|
ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtRENDQW9DZ0F3SUJBZ0lVY0c2TVdaVDJka3Rla24vRk5XZUxQdG16SWp3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF5Ck1qSTBOakF3V2hjTk1qVXdNekF4TWpJME5qQXdXakJTTVFzd0NRWURWUVFHRXdKQlZURVFNQTRHQTFVRUNCTUgKUlhoaGJYQnNaVEVTTUJBR0ExVUVCeE1KVFdWc1ltOTFjbTVsTVJBd0RnWURWUVFLRXdkRmVHRnRjR3hsTVFzdwpDUVlEVlFRTEV3SkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLMm94UkFhCmF6MUs5VGVQdmxiL24rQUxOUCtET2h2eHorSHdxUXo0b0llSEV5NkEwUGZVcnVSRCtMcktrbTA4VVJyeXBKcjYKZXI3QWJKVmFqcXNNYXUxazQ3NTJkdFhzek9pcnlPUlpZeVFSTWF1M2MrK1VycnZHWi9nd2dSWGNleEhZRHlIYgptUDFTQjdiUXAzK2cvQ053OUVmL0N0dXFkMi8ydVc1clY4VFZYZldzMVNILyszT1VVY1ZzZ1E1RWYvbnVpOWN0CjhCT3JRUW5kQndjYWxYenlSV1A3MEswTXhleDU2M3UwU1pBTndYbWRLN21RcXVNREV6VEtwU0ZveC9RRTdIMDQKd3V3SHp1MFRiLzIwYlk2eWlzMVVRajJMSU02SDNHMU55TThNK2V2ZUJzaGxGckVQMzRRSWtzZldpVFl5RUdudwppT3N0MzBvekM1TkhkdDBDQXdFQUFhTm1NR1F3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFJd0hRWURWUjBPQkJZRUZPM3lDSFg0ck5CN3ZydXZpdFptVHhOSUFPd01NQjhHQTFVZEl3UVkKTUJhQUZPM3lDSFg0ck5CN3ZydXZpdFptVHhOSUFPd01NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFjalE2YgpNRWZkWUQzd3FUUVhXY1ovYjFHTEFXWHNsTFU5VDYyNVJUUDV1MjFyc1FnaGJHWi9XcUgwT0JLa2FzVjc3c1JTCm9rRUJuVzd1UmpJbFBlS1pXS0tibHZ2ZGhyU2RDRmpraUVVYTBLdHkwNWtQTWt6bnhTdENQMzg3S2dQWWhYa0wKZGVlVkpwWFFURzZkNGx5blBUNDZmbmFvSjRoU052Y1RZdHUweXFBT3NqdEhuM2NMeW1GbS96L1U4cEZONWtTVApocUdSanhWbldQN09scW5hQ0txSjJuZDFwUUlMcWp5bFNScURrYzI0WXhHcVRPM3cyRndPS2VPbmhPelRpWk0yCk83WFVGMmE0cnNHQUdEejNQMEVENlJJZFpaWWRwQWwyN2VrZTJsSXFHTHBBcGJGMHJjUVg0aEdIUkZqaUt3WTgKU2F6YWM2cm8zRThIN3h3SwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
20
hashicorp/vault/server/ui-service.yaml
Normal file
20
hashicorp/vault/server/ui-service.yaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Headless service for Vault server DNS entries. This service should only
|
||||||
|
# point to Vault servers. For access to an agent, one should assume that
|
||||||
|
# the agent is installed locally on the node and the NODE_IP should be used.
|
||||||
|
# If the node can't run a Vault agent, then this service can be used to
|
||||||
|
# communicate directly to a server agent.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: vault-example-ui
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vault-example-ui
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: vault-example
|
||||||
|
component: server
|
||||||
|
publishNotReadyAddresses: true
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8080
|
||||||
|
targetPort: 8200
|
13
hashicorp/vault/tls/ca-config.json
Normal file
13
hashicorp/vault/tls/ca-config.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"signing": {
|
||||||
|
"default": {
|
||||||
|
"expiry": "8760h"
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"default": {
|
||||||
|
"usages": ["signing", "key encipherment", "server auth", "client auth"],
|
||||||
|
"expiry": "8760h"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
hashicorp/vault/tls/ca-csr.json
Normal file
18
hashicorp/vault/tls/ca-csr.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"hosts": [
|
||||||
|
"cluster.local"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"algo": "rsa",
|
||||||
|
"size": 2048
|
||||||
|
},
|
||||||
|
"names": [
|
||||||
|
{
|
||||||
|
"C": "AU",
|
||||||
|
"L": "Melbourne",
|
||||||
|
"O": "Example",
|
||||||
|
"OU": "CA",
|
||||||
|
"ST": "Example"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
46
hashicorp/vault/tls/ssl_generate_self_signed.txt
Normal file
46
hashicorp/vault/tls/ssl_generate_self_signed.txt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
|
||||||
|
cd ./hashicorp/vault/tls/
|
||||||
|
|
||||||
|
docker run -it --rm -v ${PWD}:/work -w /work debian:buster bash
|
||||||
|
apt-get update && apt-get install -y curl &&
|
||||||
|
curl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl && \
|
||||||
|
curl https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson && \
|
||||||
|
chmod +x /usr/local/bin/cfssl && \
|
||||||
|
chmod +x /usr/local/bin/cfssljson
|
||||||
|
|
||||||
|
#generate certificate
|
||||||
|
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
|
||||||
|
cfssl gencert \
|
||||||
|
-ca=ca.pem \
|
||||||
|
-ca-key=ca-key.pem \
|
||||||
|
-config=ca-config.json \
|
||||||
|
-hostname="vault-example,vault-example.vault-example.svc.cluster.local,vault-example.vault-example.svc,localhost,127.0.0.1" \
|
||||||
|
-profile=default \
|
||||||
|
vault-csr.json | cfssljson -bare vault-example
|
||||||
|
|
||||||
|
#get values to make a secret
|
||||||
|
cat ca.pem | base64 | tr -d '\n'
|
||||||
|
cat vault-example.pem | base64 | tr -d '\n'
|
||||||
|
cat vault-example-key.pem | base64 | tr -d '\n'
|
||||||
|
|
||||||
|
#linux - make the secret automatically
|
||||||
|
cat <<EOF > ./server-tls-secret.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: vault-example-tls-secret
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
vault-example.pem: $(cat vault-example.pem | base64 | tr -d '\n')
|
||||||
|
vault-example-key.pem: $(cat vault-example-key.pem | base64 | tr -d '\n')
|
||||||
|
ca.pem: $(cat ca.pem | base64 | tr -d '\n')
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
#TEST
|
||||||
|
vault operator init #grab keys
|
||||||
|
vault operator unseal #unseal 3 times
|
||||||
|
|
||||||
|
vault login
|
||||||
|
vault kv put cubbyhole/hello foo=world
|
16
hashicorp/vault/tls/vault-csr.json
Normal file
16
hashicorp/vault/tls/vault-csr.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"CN": "vault-example",
|
||||||
|
"key": {
|
||||||
|
"algo": "rsa",
|
||||||
|
"size": 2048
|
||||||
|
},
|
||||||
|
"names": [
|
||||||
|
{
|
||||||
|
"C": "AU",
|
||||||
|
"L": "Melbourne",
|
||||||
|
"O": "Kubernetes",
|
||||||
|
"OU": "Vault",
|
||||||
|
"ST": "Victoria"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user