Vault does not honor cluster_addr

I am deploying vault - to docker swarm - using the below compose.yml. The service is deployed with 3 replicas and is deployed with integrated raft storage.

The documentation says its important, and I provide, cluster_addr, that uses the hostname of each raft node. However, after deployment, if I check the member list and raft status, I can see that vault is using the api_addr (http://vault1:8200 etc) but has used a generated cluster_addr (https not http, ip not hostname).

Node     Address           State       Voter
----     -------           -----       -----
node1    10.0.45.7:8201    leader      true
node3    10.0.45.9:8201    follower    true
node2    10.0.45.8:8201    follower    true
/ # vault operator members
Host Name    API Address           Cluster Address           ActiveNode    Last Echo
---------    -----------           ---------------           ----------    ---------
vault1       http://vault1:8200    https://10.0.45.7:8201    true          <nil>
vault3       http://vault3:8200    https://10.0.45.9:8201    false         2022-05-19 08:40:57.009616077 +0000 UTC
vault2       http://vault2:8200    https://10.0.45.8:8201    false         2022-05-19 08:40:54.46053215 +0000 UTC

This is the stack.yml file that does the deployment to swarm. {{.Task.Slot}} automatically expands out to the integers 1,2 and 3, ensuring that 3 instances of vault, named “vault1”, “vault2” and “vault3” are created, as can be seen in the API Address from the vault operator members report. Additionally there is config for a transit vault to autounsealing.

vault-stack.yml

services:

  vault:
    image: vault:latest
    hostname: vault{{.Task.Slot}}
    cap_add:
      - IPC_LOCK
    command: server
    volumes:
    - /vault/logs
    - vault:/vault/file
    environment:
      SKIP_SETCAP: "true"
      VAULT_ADDR: http://localhost:8200
      VAULT_CLUSTER_INTERFACE: eth0
      VAULT_LOCAL_CONFIG: >
        {
            "cluster_name": "${STACK}",
            "api_addr": "http://vault{{.Task.Slot}}:8200",
            "ui": true,
            "storage": {
              "raft": { 
                "path": "/vault/file",
                "node_id": "node{{.Task.Slot}}",
                "retry_join": {
                  "leader_api_addr": "http://vault1:8200"
                }
              }
            },
            "cluster_addr": "http://vault{{.Task.Slot}}:8201",
            "seal" : {
              "transit" : {
                "address": "http://transit:8200",
                "token": "${TRANSIT_TOKEN}",
                "key_name": "autounseal",
                "mount_path": "transit/"
              }
            },
            "listener": {
                "tcp": {
                    "address": "0.0.0.0:8200",
                    "cluster_address": "0.0.0.0:8201",
                    "tls_disable": true
                }
            },
            "disable_mlock": true
        }
    networks:
      vault:
        aliases: [ vault.vault ]
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role==worker
      restart_policy:
        max_attempts: 5
volumes:
  vault:
    driver: glusterfs
    name: '{{index .Service.Labels "com.docker.stack.namespace"}}_vault-{{.Task.Slot}}'
1 Like

OMG.
VAULT_CLUSTER_INTERFACE make it ignore cluster_addr. Even tho that effects the listen address not the publish url.

fantastic.