Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagebash
# Clone the chart repo
$ git clone https://github.com/hashicorp/vault-helm.git
$ cd vault-helm

# Checkout a tagged version
$ git checkout v0.1.2

# Run Helm
$ helm install --name vault ./
...

NOTE: You can pass the --dry-run flag to helm install  to simply print our the resources that will be created, instead of actually triggering their creation.

Verify that Vault is Running

You should then be able to open a port-forward using kubectl to the Vault podYou should now have a sealed vault running. You should see something like the following in the logs:

Code Block
languagebash
$ kubectl logs port-forwardf vault-0 8200:8200

As long as this port-forward is running, navigating your browser to http://localhost:8200 should allow you to view the Vault UI.

Similarly, pointing your vault  binary at http://localhost:8200 over the port-forward will allow you to run vault status  to view the cluster status.


==> Vault server configuration:

             Api Address: http://10.37.0.7:8200
                     Cgo: disabled
         Cluster Address: https://10.37.0.7:8201
              Listener 1: tcp (addr: "[::]:8200", cluster address: "[::]:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: info
                   Mlock: supported: true, enabled: true
                 Storage: file
                 Version: Vault v1.2.2

==> Vault server started! Log data will stream in below:

2019-11-05T19:42:37.448Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T19:42:40.439Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T19:42:43.369Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T19:42:46.420Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T19:42:49.215Z [INFO]  core: seal configuration missing, not initialized
    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...    ...

Managing the Vault Server

You should then be able to open a port-forward using kubectl to the Vault pod:

Code Block
languagebash
$ kubectl port-forward vault-0 8200:8200

As long as this port-forward is running, navigating your browser to http://localhost:8200 should allow you to view the Vault UI.

Similarly, pointing your vault  binary at http://localhost:8200 over the port-forward will allow you to run vault status to view the cluster status.

If you just need to run the vault command-line tool, you could choose instead to kubectl exec into the vault pod to run the command there:

Code Block
languagebash
$ kubectl exec -it vault-0 -- vault status

NOTE: For larger Vault cluster, configuring Vault to be exposed via a Kubernetes Service may be preferential.

Unsealing the Vault

By default, the Helm chart starts the Vault in a Sealed and uninitialized state. To use the vault you will first need to initialize it, then unseal it.

Initialization will create the keys needed for unsealing. SAVE THESE KEYS SOMEWHERE SAFE!

Code Block
languagebash
$ kubectl exec -it vault-0 -- vault operator init
Unseal Key 1: qGDqGX13Sy/G6E+ZuQZ9DvhoFV7PDYfpPDO7uv1ox1qI
Unseal Key 2: EFfPzYkeowIZRqVoV2Dg9SeQmfj0Hi33CBjAy2Zq1T/9
Unseal Key 3: j13UH+mdrOE+3bwBVOdv/YUKjTyrSNRDUaZykx7aFQRv
Unseal Key 4: mwA47fXNmdv8u2nXL8s2poi1oqjfGNPNMc6aGG5j1S2m
Unseal Key 5: 0TQ42RgTH+xiKguZiIsg5ttrGuZ5gy3xAqY7G6QjRns4

Initial Root Token: s.JyaDk0IiYveqHiXJAmhdJ9Es

Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.

Vault does not store the generated master key. Without at least 3 key to
reconstruct the master key, Vault will remain permanently sealed!

It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See "vault operator rekey" for more information.

Now that you have the keys, you can unseal the vault!

As described in the output above, you will need to enter 3 of the 5 unseal keys to successfully unseal the Vault:

Code Block
languagebash
$ kubectl exec -it vault-0 -- vault operator unseal
Unseal Key (will be hidden): <paste-from-above>
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true    <---- Sealed
Total Shares       5
Threshold          3
Unseal Progress    1/3     <----
Unseal Nonce       0ed7cb42-66ad-63b2-fb42-36410f93b6b1
Version            1.2.2
HA Enabled         false

$ kubectl exec -it vault-0 -- vault operator unseal
Unseal Key (will be hidden): <paste-from-above>
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true    <---- Sealed
Total Shares       5
Threshold          3
Unseal Progress    2/3     <----
Unseal Nonce       0ed7cb42-66ad-63b2-fb42-36410f93b6b1
Version            1.2.2
HA Enabled         false

$ kubectl exec -it vault-0 -- vault operator unseal
Unseal Key (will be hidden): <paste-from-above>
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false      <---- Unsealed
Total Shares    5
Threshold       3
Version         1.2.2
Cluster Name    vault-cluster-0959e8a7
Cluster ID      60657f4c-55fb-0bb5-d511-9dc9e32f5eb6
HA Enabled      false

Check back on the logs to see the Vault initialized and unsealed:

Code Block
languagebash
2019-11-05T20:09:13.461Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T20:09:16.399Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T20:09:19.344Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T20:09:22.511Z [INFO]  core: seal configuration missing, not initialized
2019-11-05T20:09:23.338Z [INFO]  core: security barrier not initialized
2019-11-05T20:09:23.539Z [INFO]  core: security barrier initialized: shares=5 threshold=3
2019-11-05T20:09:23.748Z [INFO]  core: post-unseal setup starting
2019-11-05T20:09:23.849Z [INFO]  core: loaded wrapping token key
2019-11-05T20:09:23.849Z [INFO]  core: successfully setup plugin catalog: plugin-directory=
2019-11-05T20:09:23.850Z [INFO]  core: no mounts; adding default mount table
2019-11-05T20:09:23.988Z [INFO]  core: successfully mounted backend: type=cubbyhole path=cubbyhole/
2019-11-05T20:09:23.989Z [INFO]  core: successfully mounted backend: type=system path=sys/
2019-11-05T20:09:23.990Z [INFO]  core: successfully mounted backend: type=identity path=identity/
2019-11-05T20:09:24.553Z [INFO]  core: successfully enabled credential backend: type=token path=token/
2019-11-05T20:09:24.553Z [INFO]  core: restoring leases
2019-11-05T20:09:24.553Z [INFO]  rollback: starting rollback manager
2019-11-05T20:09:24.556Z [INFO]  expiration: lease restore complete
2019-11-05T20:09:24.661Z [INFO]  identity: entities restored
2019-11-05T20:09:24.662Z [INFO]  identity: groups restored
2019-11-05T20:09:24.662Z [INFO]  core: post-unseal setup complete
2019-11-05T20:09:24.966Z [INFO]  core: root token generated
2019-11-05T20:09:24.966Z [INFO]  core: pre-seal teardown starting
2019-11-05T20:09:24.966Z [INFO]  rollback: stopping rollback manager
2019-11-05T20:09:24.966Z [INFO]  core: pre-seal teardown complete
2019-11-05T20:09:59.450Z [INFO]  core.cluster-listener: starting listener: listener_address=[::]:8201
2019-11-05T20:09:59.450Z [INFO]  core.cluster-listener: serving cluster requests: cluster_listen_address=[::]:8201
2019-11-05T20:09:59.454Z [INFO]  core: post-unseal setup starting
2019-11-05T20:09:59.457Z [INFO]  core: loaded wrapping token key
2019-11-05T20:09:59.457Z [INFO]  core: successfully setup plugin catalog: plugin-directory=
2019-11-05T20:09:59.463Z [INFO]  core: successfully mounted backend: type=system path=sys/
2019-11-05T20:09:59.464Z [INFO]  core: successfully mounted backend: type=identity path=identity/
2019-11-05T20:09:59.464Z [INFO]  core: successfully mounted backend: type=cubbyhole path=cubbyhole/
2019-11-05T20:09:59.480Z [INFO]  core: successfully enabled credential backend: type=token path=token/
2019-11-05T20:09:59.480Z [INFO]  core: restoring leases
2019-11-05T20:09:59.480Z [INFO]  rollback: starting rollback manager
2019-11-05T20:09:59.481Z [INFO]  expiration: lease restore complete
2019-11-05T20:09:59.485Z [INFO]  identity: entities restored
2019-11-05T20:09:59.485Z [INFO]  identity: groups restored
2019-11-05T20:09:59.485Z [INFO]  core: post-unseal setup complete
2019-11-05T20:09:59.485Z [INFO]  core: vault is unsealed

You are now ready to store and retrieve secrets from the Vault! Let's try manually storing some secrets to learn the basicsNOTE: For larger Vault cluster, configuring Vault to be exposed via a Kubernetes Service may be preferential.


Local Install

A local install has quite a few more manual steps to get things running on Kubernetes.

...

Code Block
languagebash
$ vault secrets disable kv/
Success! Disabled the secrets engine (if it existed) at: kv/

For a list of all available secrets engines, please see the Vault documentation regarding Secrets Engines.

Managing Users and Policies

...

Code Block
languagetext
linenumberstrue
exit_after_auth = true
pid_file = "/home/vault/pidfile"

auto_auth {
    method "kubernetes" {
        mount_path = "auth/kubernetes"
        config = {
            role = "example"
        }
    }

    sink "file" {
        config = {
            path = "/home/vault/.vault-token"
        }
    }
}

Notice that the Vault Agent Auto-Auth is configured to use the kubernetes auth method enabled at the auth/kubernetes path on the Vault server. The Vault Agent will use the example role to authenticate.

The sink block specifies the location on disk where to write tokens. Vault Agent Auto-Auth sink can be configured multiple times if you want Vault Agent to place the token into multiple locations. In this example, the sink is set to /home/vault/.vault-token.

Create a Consul Template

Vault uses Consul under the hood to persist its key-value pairs. Consul is a service mesh for Kubernetes that provides convenient ways to plug data into running pods.

...

This template reads secrets at the secret/myapp/config path and set the username and password values.

NOTE: If the secret/ path is enabled with key/value v2 secrets engine, the templatized expressions should be modified as follow (Line 15 through 18):

...

Code Block
languagebash
# Create a ConfigMap called 'example-vault-agent-config'
$ kubectl create configmap example-vault-agent-config --from-file=./configs-k8s/

# View the created ConfigMap
$ kubectl get configmap example-vault-agent-config -o yaml

Now create a pod spec anmed named example-k8s-spec.yml that mounts in the files from the examplevault-agent-config ConfigMap and using the vault-auth ServiceAccount:

...

Execute the following command to create the vault-agent-example Pod:

Code Block
languagebash
$ kubectl apply -f example-k8s-spec.yml --record

...

Code Block
languagebash
$ kubectl port-forward pod/vault-agent-example 8080:80

In a web browser, go to localhost:8080

Kubernetes

Notice that the username and password values were successfully read from secret/myapp/config.

This proves that we are able to capture Vault values and automatically render them at container startup using Consul.

Open a shell to the consul-template container:

Code Block
languagebash
$ kubectl exec -it vault-agent-example --container consul-template sh

Remember that we set the Vault Agent's sink to be /home/vault/.vault-token. To view the token stored in the sink:

...