Prerequisites
These instructions require the following tools on the local machine:
Kubernetes command-line interface (CLI)
Helm CLI
The kubectl context should be set to the Kubernetes cluster where the HiveMQ broker will be installed.
\uD83D\uDCD8 Instructions
Install the Vault
...
git clone https://github.com/hashicorp-education/learn-vault-secrets-operator.git
...
cd learn-vault-secrets-operator
...
Helm Chart
Add the HashiCorp Helm repository.
Code Block language bash $ helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update hashicorp
helm install vault hashicorp/vault -n vault --create-namespace --values vault/vault-values.yaml
- Convert the license and copy to the vault:
"hashicorp" has been added to your repositories
Update all the repositories to ensure
Verify you have “root” token:helm
is aware of the latest versions.Code Block language bash cat hivemq.lic | base64 > hivemq.lic.b64 kubectl cp hivemq.lic.b64 vault-0:/tmp/hivemq.lic.b64
Attach to the Vault:
kubectl exec --stdin=true --tty=true vault-0 -n vault -- /bin/sh
Run in the vault:
$ helm repo update Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "hashicorp" chart repository Update Complete. ⎈Happy Helming!⎈
Install the latest version of the Vault server running in development mode.
Code Block language bash $ helm install vault hashicorp/vault --set "server.dev.enabled=true" NAME: vault ## ...
The Vault pod and Vault Agent Injector pod are deployed in the default namespace.
Display all the pods in the default namespace.
Code Block language bash vault$ tokenkubectl lookupget #Key pods NAME Value #--- ----- #accessor READY STATUS ma6KC5nhNdTmANzeco0Evtdm #creation_timeRESTARTS AGE vault-0 1707226849 #creation_ttl 0s #display_name token #entity_id n1/a1 #expire_time Running 0 <nil> #explicit_max_ttl 0s #id 80s vault-agent-injector-5945fb98b5-tpglz 1/1 Running 0 root #issue_time 2024-02-06T13:40:49.967795042Z #meta <nil> #num_uses 0 #orphan true #path 80s
The
vault-0
pod runs a Vault server in development mode. Thevault-agent-injector
pod performs the injection based on the annotations present or patched on a deployment.
Development mode: Running a Vault server in development is automatically initialized and unsealed. This is ideal in a learning environment but NOT recommended for a production environment.Wait until the
vault-0
pod andvault-agent-injector
pod are running and ready (1/1
).
Set a secret in Vault
Copy the hivemq-license file to the
vault-0
pod.Code Block language bash $ kubectl cp hivemq.lic pod/vault-0:/tmp/
Verify that the file is copied.
Code Block language bash $ kubectl exec -it vault-0 -- ls /tmp
Start an interactive shell session on the
vault-0
pod.Code Block language bash $ kubectl exec -it vault-0 -- /bin/sh / $
Your system prompt is replaced with a new prompt
/ $
. Commands issued at this prompt are executed on thevault-0
container.Enable kv-v2 secrets at the path
hivemq
.Code Block language bash $ vault secrets enable -path=hivemq kv-v2 Success! Enabled the kv-v2 secrets engine at: hivemq/
Create a secret at path
hivemq/myenv/license
with ahivemq_license_b64
key and base64-encoded/tmp/hivemq.lic
file.Code Block language bash $ cd /tmp $ vault kv put hivemq/myenv/license hivemq_license_b64="$(base64 -w 0 hivemq.lic)" ====== Secret Path ====== hivemq/data/myenv/license ======= Metadata ======= Key auth/token/create #policies Value --- [root] #renewable false #ttl----- created_time 2024-02-21T17:34:39.261249639Z custom_metadata <nil> deletion_time 0s #typen/a destroyed service
Enable secrets on the path:
Put the content of the base64 encoded file to the vault secret at the path:Code Block language bash vault secrets enable -path=hivemq-mqtt/obc-poc/opt/hivemq/license kv-v2 #Success! Enabled the kv-v2 secrets engine at: hivemq-mqtt/obc-poc/opt/hivemq/license/
false version 1
Verify that the secret is defined at the path
internal/database/config
.Code Block language bash $ vault kv putget hivemq-mqtt/obc-poc/opt/hivemq/license/hivemq.lic.b64 mydata="$(cat /tmp/hivemq.lic.b64)" #==========myenv/license ============== Secret Path ======================= #hivemq-mqtt/obc-poc/opt/hivemq/license/data/hivemq.lic.b64 # #hivemq/data/myenv/license ======= Metadata ======= #KeyKey Value #--- ----- #createdcreated_time 2024-02-06T1721T14:2257:4401.720536373Z446984026Z #customcustom_metadata <nil> #deletiondeletion_time n/a #destroyeddestroyed false #version version 1 ========= Data ========= Key Value --- ----- hivemq_lic_b64 2 SCFNUSRbM10.......
The secret is ready for the application.
Lastly, exit the
kv list hivemq-mqtt/obc-poc/opt/hivemq/license/ #Keys #---- #hivemq.lic.b64vault
List vault secrets at the path:
-0
pod.Code Block language bash $ exit
Configure Kubernetes authentication
Vault provides a Kubernetes authentication method that enables clients to authenticate with a Kubernetes Service Account Token. This token is provided to each pod when it is created.
Start an interactive shell session on the
vault-0
pod.Code Block language bash $ kubectl exec -it vault-0 -- /bin/sh / $
Your system prompt is replaced with a new prompt
/ $
. Commands issued at this prompt are executed on thevault-0
container.Enable the Kubernetes authentication method.
Code Block language bash $ vault auth enable kubernetes Success! Enabled kubernetes auth method at: kubernetes/
Vault accepts a service token from any client in the Kubernetes cluster. During authentication, Vault verifies that the service account token is valid by querying a token review Kubernetes endpoint.
Configure the Kubernetes authentication method to use the location of the Kubernetes API.
Note: For the best compatibility with recent Kubernetes versions, ensure you are using Vault v1.13.3 or greater.
Code Block language bash $ vault write auth/kubernetes/config \ kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"
Successful output from the command resembles this example:
Code Block language text Success! Data written to: auth/kubernetes/config
The environment variable
KUBERNETES_PORT_443_TCP_ADDR
is defined and references the internal network address of the Kubernetes host.For a client to read the secret data defined at
hivemq/myenv/license
, requires that the read capability be granted for the pathhivemq/data/myenv/license
. This is an example of a policy. A policy defines a set of capabilities.Write out the policy named
hivemq
that enables theread
capability for secrets at pathinternal/data/database/config
.Code Block language bash $ vault kvpolicy listwrite hivemq-mqtt/obc-poc/opt/hivemq/license/ #Keys #---- #hivemq.lic.b64
Exit from the vault container
exit
Consult-template.hcl file:
View file name consul-template.hcl Edit the hivemq-operator/values.yaml and add the sidecar:
Code Block language yaml- <<EOF path "internal/data/database/config" { capabilities = ["read"] } EOF
Create a Kubernetes authentication role named
hivemq
.Code Block language bash $ vault write auth/kubernetes/role/hivemq \ bound_service_account_names=hivemq-hivemq-operator-hivemq \ bound_service_account_namespaces=hivemq \ policies=internal-app \ ttl=24h
Successful output from the command resembles this example:
Code Block language text Success! Data written to: auth/kubernetes/role/hivemq
The role connects the Kubernetes service account,
hivemq-hivemq-operator-hivemq
, and namespace,hivemq
, with the Vault policy,hivemq
. The tokens returned after authentication are valid for 24 hours.Lastly, exit the
vault-0
pod.Code Block language bash $ exit
Deploy a HiveMQ cluster
If you already have a customized values.yaml, use it. If you do not have values.yaml file yet, get the values.yaml
Code Block language bash helm show values hivemq/hivemq-operator > values-hivemq.yaml
Edit the values-hivemq.yaml file. Add annotations to the hivemq pods.
Code Block hivemq: # CustomAnnotations container spec to add to the HiveMQ PodPods sidecarspodAnnotations: vault.hashicorp.com/agent- name: consul-template-container inject: "true" vault.hashicorp.com/role: "hivemq" vault.hashicorp.com/agent-inject-status: 'update' image: hashicorp/consul-template:latest vault.hashicorp.com/agent-inject-secret-hivemq-license: "hivemq/data/myenv/license" vault.hashicorp.com/agent-inject-template-hivemq-license: | command: [ "consul-template", "-config", "/hivemq-data/conf/consul-template.hcl" ] {{- with secret \"hivemq/data/myenv/license\" -}} {{- $hivemq_broker_license #command: [ "consul-template", "-version" ] env: - name: TARGET_ENV value: hivemq-mqtt/obc-poc volumeMounts::= base64Decode .Data.data.hivemq_lic_b64 -}} {{- $hivemq_broker_license -}} {{- end -}}
(Re)install hivemq
Code Block language bash helm upgrade hivemq --install hivemq/hivemq-operator -n hivemq -f values-hivemq.yaml
Get all the pods in the hivemq namespace.
Code Block $ kubectl get pods -n hivemq NAME READY STATUS RESTARTS AGE hivemq-599cb74d9c-s8hhm 0/2 Init:0/1 0 - name:23s consulhivemq-template-files69697d9598-l878s mountPath: /hivemq-data/conf1/1 Running 0 # Custom init container specs to add to the HiveMQ Pod. This is an extension of the initialization field. In comparison, this field does not have any defaults but allows for more granular configuration using the full K8s Container API initContainers: []
Edit the hivemq-operator/values.yaml and add the volume with consul-template.hcl
Create the configMap with consul-template-filesCode Block language yaml hivemq: # Additional volumes to add to the HiveMQ Pod additionalVolumes: - name: consul-template-files configMap:20m vault-0 1/1 Running 0 78m vault-agent-injector-5945fb98b5-tpglz 1/1 Running 0 name: consul-template-files
78m
Wait until the re-deployed
hivemq
pod reports that it isRunning
and ready (2/2
).This new pod now launches two containers. The application container, named
hivemq
, and the Vault Agent container, namedvault-agent
.Display the logs of the
vault-agent
container in the neworgchart
pod.Code Block language bash $ kubectl create configmap consul-template-files -n hivemq --from-file consul-template.hcl
Install hivemq
helm upgrade hivemq --install hivemq/hivemq-operator -n hivemq -f hivemq-operator/values.yam
TODO: continue
...
logs \ $(kubectl get pod -l app=hivemq -o jsonpath="{.items[0].metadata.name}") \ --container vault-agent
Vault Agent manages the token lifecycle and the secret retrieval. The secret is rendered in the
orgchart
container at the path/vault/secrets/hivemq-license
.Display the secret written to the
hivemq
container.Code Block language bash $ kubectl exec \ $(kubectl get pod -l app=hivemq -o jsonpath="{.items[0].metadata.name}") \ --container hivemq -- cat /vault/secrets/hivemq-license
The unformatted secret data is present on the container: TODO
\uD83D\uDCCB Related articles
...