🔑

Vault Enteprise の DR/PR レプリケーション

2024/06/03に公開

Vault Enterpriseではリージョン障害などに対応するため、Vaultクラスタ間でレプリケーション構成を組む事が可能です。レプリケーションにもDisaster Recovery(以下DR)レプリケーションとPerformance(以下PR)レプリケーションの2種類のレプリケーションを組む事が可能です。

詳細は以下のドキュメントをご確認頂ければと思いますが、DRレプリケーションはプライマリに昇格するまではクライアントからのリクエストは受付らません。一方、PRレプリケーションはクライアントからのリクエストを受ける事ができ、Read処理はPRクラスタ自身で、Write処理はPrimaryクラスタにリダイレクトされる形でクライアントからのリクエストにレスポンスします。
https://developer.hashicorp.com/vault/docs/enterprise/replication

以下の様な構成で、Vault EnterpriseのDR/PRレプリケーションを構成し、Primaryクラスタを停止し、DR secondaryのPrimary昇格を行い、その中でクライアントからのリクエストに対するVaultクラスタの挙動を確認しました。


Vault Enterprise DR/PRレプリケーション構成

ここで行なっている内容はReferencesに記載してあるチュートリアルやドキュメントを参照しておりますので、実際にVault Enterpriseでレプリケーション構成を組まれる際はご参照ください。

Set up Vault Enterprise clusters

上記の通りの構成で、Ubuntuの仮想マシン上にVault Enterpriseクラスタをデプロイし、レプリケーション構成を組んでいます。ネットワーク構成として、Vault: Solution Design Guide - Detailed designに記載がある様に、クラスタ間での8200ポート、8201ポートでの通信を許可する様にしています。
検証用途のため、各クラスタは1台の仮想マシンで構成していますが、本番環境で利用される場合は、リファレンスアーキテクチャに則った形で構成して頂く事をオススメ致します。

Cluster type IP address
Primary 10.0.101.59
PR secondary 10.0.102.40
DR secondary 10.0.103.231

各クラスタの設定ファイル(/etc/vault.d/config.hcl)は以下の様な形で設定しています。api_addrcluster_addrはクラスタ毎に変更しています。

Primary の /etc/vault.d/config.hcl
api_addr     = "http://10.0.101.59:8200"
cluster_addr = "http://10.0.101.59:8201"

ui = true

license_path = "/etc/vault.d/vault.hclic"

listener "tcp" {
  address         = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"
  tls_disable     = true
}

storage "raft" {
  path    = "/var/lib/vault"
  node_id = "vault1"
}

telemetry {
  disable_hostname          = true
  prometheus_retention_time = "12h"
}

reporting {
  license {
    enabled = false
  }
}

Primaryクラスタに関しては、初期化した後に認証メソッドやシークレットエンジンなどの設定をした上で、PRレプリケーション、DRレプリケーションの構成をしています。

認証メソッド
$ vault auth list
Path         Type        Accessor                  Description                                Version
----         ----        --------                  -----------                                -------
token/       token       auth_token_9241eb14       token based credentials                    n/a
userpass/    userpass    auth_userpass_3f65d3ab    for human access on handson environment    n/a
ポリシー
$ vault policy list
all-vegetables
default
read-fruits
vault-admin
write-fruits
root
シークレットエンジン
$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_f84483ac    per-token private secret storage
identity/     identity     identity_6b93d7f2     identity store
sys/          system       system_6f62b677       system endpoints used for control, policy and debugging
test/         kv           kv_5d2f0bc6           kv-v2 secrets engine for test
登録してあるシークレット
$ vault kv list test
Keys
----
fruits
vegetables
クラスタステータス
$ vault status
Key                     Value
---                     -----
Seal Type               shamir
Initialized             true
Sealed                  false
Total Shares            1
Threshold               1
Version                 1.16.3+ent
Build Date              2024-05-29T00:40:37Z
Storage Type            raft
Cluster Name            vault-cluster-6aec9704
Cluster ID              e60592ae-afe7-1d67-a459-d6612b7b4eb1
HA Enabled              true
HA Cluster              https://10.0.101.59:8201
HA Mode                 active
Active Since            2024-05-31T00:17:54.384160098Z
Raft Committed Index    466
Raft Applied Index      466
Last WAL                85

Enable PR replication

まずは、PrimaryクラスタでPRレプリケーションを有効化していきます。利用しているAPIエンドポイントは、Enable performance primary replicationになります。

$ vault write -f sys/replication/performance/primary/enable
WARNING! The following warnings were returned from Vault:

  * This cluster is being enabled as a primary for replication. Vault will be
  unavailable for a brief period and will resume service shortly.

次に、PR secondaryクラスタ用のトークンをPrimaryクラスタで作成します。利用しているAPIエンドポイントは、Generate performance secondary tokenになります。生成されるトークンのデフォルトTTLは30分ですが、ここではTTLを長くして作成しています。

$ vault write sys/replication/performance/primary/secondary-token id=perf-secondary ttl=180m
Key                              Value
---                              -----
wrapping_token:                  eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NvciI6IiIsImFkZHIiOiJodHRwOi8vMTAuMC4xMDEuMzA6ODIwMCIsImV4cCI6MTcxNzA4MjExNywiaWF0IjoxNzE3MDcxMzE3LCJqdGkiOiJodnMuZ1ZrZ0R5SjZPazVQNHFpS01lR0duMU1EIiwibmJmIjoxNzE3MDcxMzEyLCJ0eXBlIjoid3JhcHBpbmcifQ.AAWbRNj8EYBFmHmV-Oyg3eszx0NZdw1z5U_LNCF5ZmYZMJo_RKIN0-eUrhCrRVJJLX8ngNzGBAjJ2ZAJhZry2TpOAEyK0TKDFcu2gqkrkUHPfMcHW7ADTW63YxZsd2H65HW84RCr2EYuYe9094qTUO2GascheXwMxhKiJ593NjtdpM4v
wrapping_accessor:               urliVSwnMUPsdtqa6Mto98Fr
wrapping_token_ttl:              3h
wrapping_token_creation_time:    2024-05-30 12:15:17.569953165 +0000 UTC
wrapping_token_creation_path:    sys/replication/performance/primary/secondary-token

PR secondaryクラスタで、PRレプリケーションを有効化する前に、クラスタのステータスを確認しておきます。以下の通り、シークレットエンジン、認証メソッド、ポリシーはクラスタを初期化した直後のデフォルト設定のみである事が確認出来ます。

$ vault status
Key                     Value
---                     -----
Seal Type               shamir
Initialized             true
Sealed                  false
Total Shares            1
Threshold               1
Version                 1.16.3+ent
Build Date              2024-05-29T00:40:37Z
Storage Type            raft
Cluster Name            vault-cluster-73fb0288
Cluster ID              87db43c2-076c-e17d-5605-7e611665f394
HA Enabled              true
HA Cluster              https://10.0.102.40:8201
HA Mode                 active
Active Since            2024-05-31T00:27:01.090454156Z
Raft Committed Index    237
Raft Applied Index      237
Last WAL                27
$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_759c465f    per-token private secret storage
identity/     identity     identity_c9b5f205     identity store
sys/          system       system_deb2072f       system endpoints used for control, policy and debugging
$ vault auth list
Path      Type     Accessor               Description                Version
----      ----     --------               -----------                -------
token/    token    auth_token_90df44f1    token based credentials    n/a
$ vault policy list
default
root

Primaryクラスタで生成したPR secondaryクラスタ用のトークンを環境変数PR_SECONDARY_TOKENに設定します。

export PR_SECONDARY_TOKEN="eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NvciI6IiIsImFkZHIiOiJodHRwOi8vMTAuMC4xMDEuNTk6ODIwMCIsImV4cCI6MTcxNzEzMzU4OSwiaWF0IjoxNzE3MTE1NTg5LCJqdGkiOiJodnMuTFFGSkJrSE93WUx2NGJ1dTJVZzdleTNiIiwibmJmIjoxNzE3MTE1NTg0LCJ0eXBlIjoid3JhcHBpbmcifQ.ALGmvqjRXPLNCb_gG2c635DCtYe9dcPRhquQytilWnCUd_jZcOegrw6L6bZISVWFQHSf8co_7QIyar_TmLe44uahADzDNauKJBLR3pXZ9hwezKMs5khagelr-gSEAdvsTtOMLNPPHZ809eZ-BcgACADyGAVZcKxfKkCYsR7DRh_24yIw"

PR secondaryクラスタでPRレプリケーションを有効化します。利用するAPIエンドポイントは、Enable performance secondaryになります。

$ vault write sys/replication/performance/secondary/enable token=$PR_SECONDARY_TOKEN
WARNING! The following warnings were returned from Vault:

  * Vault has successfully found secondary information; it may take a while to
  perform setup tasks. Vault will be unavailable until these tasks and initial
  sync complete.

PRレプリケーションのステータスを確認してみます。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
connection_state               ready
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717115786
last_remote_wal                0
last_start                     2024-05-31T00:36:26Z
merkle_root                    db3c05cc55b4fe5551d5ee272e7a2ee2564dace2
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-2 cluster_address:https://10.0.101.59:8201 connection_status:connected last_heartbeat:2024-05-31T00:36:31Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   perf-secondary
ssct_generation_counter        0
state                          stream-wals

-format=jsonオプションをつけると出力をJSON形式にする事もできます。

vault read -format=json sys/replication/performance/status
Output
{
  "request_id": "97f75d84-d07b-241c-7482-29acde5eada4",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "cluster_id": "f71523a9-41a8-3a84-7feb-6b8cc64d7c57",
    "connection_state": "ready",
    "corrupted_merkle_tree": false,
    "known_primary_cluster_addrs": [
      "https://10.0.101.59:8201"
    ],
    "last_corruption_check_epoch": "-62135596800",
    "last_reindex_epoch": "1717115786",
    "last_remote_wal": 0,
    "last_start": "2024-05-31T00:36:26Z",
    "merkle_root": "db3c05cc55b4fe5551d5ee272e7a2ee2564dace2",
    "mode": "secondary",
    "primaries": [
      {
        "api_address": "http://10.0.101.59:8200",
        "clock_skew_ms": "-1",
        "cluster_address": "https://10.0.101.59:8201",
        "connection_status": "connected",
        "last_heartbeat": "2024-05-31T00:37:06Z",
        "last_heartbeat_duration_ms": "2"
      }
    ],
    "primary_cluster_addr": "https://10.0.101.59:8201",
    "secondary_id": "perf-secondary",
    "ssct_generation_counter": 0,
    "state": "stream-wals"
  },
  "warnings": null
}

Replicate date from Primary to PR secondary

Primaryクラスタで行った更新処理がPR secondaryクラスタにも反映されるか確認してみます。

$ vault kv get test/fruits
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T00:29:02.130136663Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

===== Data =====
Key        Value
---        -----
member1    apple
member2    banana

シークレットtest/fruitsmember3を追加してみます。

$ vault kv patch -mount=test fruits member3=cherry
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:22:53.54075085Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2
$ vault kv get test/fruits
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:22:53.54075085Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2

===== Data =====
Key        Value
---        -----
member1    apple
member2    banana
member3    cherry

同様に、シークレットtest/fruitsmember4を追加してみます。

$ vault kv patch -mount=test fruits member4=lemon
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:24:02.967956548Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3
$ vault kv get test/fruits
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:24:02.967956548Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    apple
member2    banana
member3    cherry
member4    lemon

Primaryクラスタで作成しておいたUserpass認証メソッドのadminユーザーでログインします。問題なくログイン出来た事からも、PrimaryクラスタからPR secondaryクラスタへレプリケーションがなされている事が確認できます。

$ vault login -method=userpass -path=userpass username=admin password=changeme
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                    Value
---                    -----
token                  hvs.CAESIIyKMkTGtGMfPQ1_kZzcaB6S7c9iqsR071yN48fDGKoPGiEKHGh2cy51Q2x1U0xiUFFnY0lsNGFLU1lJT3MyQ2YQ8AQ
token_accessor         9Yx6Euu5IsLiHvs6cZks3PCJ
token_duration         30m
token_renewable        true
token_policies         ["default" "vault-admin"]
identity_policies      []
policies               ["default" "vault-admin"]
token_meta_username    admin

Userpass認証メソッドのadminユーザーに付与されているvault-adminは以下のポリシーで定義しているため、ルートと同じ権限でVaultを操作出来る様にしています。

vault-adminポリシードキュメント
path "*" {
  capabilities = ["sudo","read","create","update","delete","list","patch"]
}

test/fruitsを確認してみると、Primaryクラスタで更新した内容が反映されている事が確認できます。

$ vault kv get test/fruits
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:24:02.967956548Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    apple
member2    banana
member3    cherry
member4    lemon

PRレプリケーションのステータスを確認してみます。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
connection_state               ready
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717115786
last_remote_wal                147
last_start                     2024-05-31T00:57:34Z
merkle_root                    69e37b1b69d6cc60a606bfdc37bd0cb61e1471a8
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-2 cluster_address:https://10.0.101.59:8201 connection_status:connected last_heartbeat:2024-05-31T01:30:39Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   perf-secondary
ssct_generation_counter        0
state                          stream-wals

PR secondaryクラスタ側のPRレプリケーションのステータスから、last_remote_wal147statesteram-walsとなっている事が分かります。

同様にPrimaryクラスタでもPRレプリケーションのステータスを確認してみます。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
corrupted_merkle_tree          false
known_secondaries              [perf-secondary]
last_corruption_check_epoch    -62135596800
last_performance_wal           147
last_reindex_epoch             0
last_wal                       147
merkle_root                    69e37b1b69d6cc60a606bfdc37bd0cb61e1471a8
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[api_address:http://10.0.102.40:8200 clock_skew_ms:-1 cluster_address:https://10.0.102.40:8201 connection_status:connected last_heartbeat:2024-05-31T01:29:59Z last_heartbeat_duration_ms:2 node_id:perf-secondary]]
ssct_generation_counter        0
state                          running

last_wal147であり、PR secondaryクラスタのlast_remote_walの値と同じである事が分かります。これはPrimaryクラスタとPR secondaryクラスタでデータが同期されている事を意味しています。

また、Primaryクラスタのstaterunning、PR secondaryクラスタ側がstream-walsとなっている事から、レプリケーションが正常に実行されている事を意味しています。

Operation in PR secondary

次に、PR secondaryクラスタの更新処理がPrimaryクラスタにリダイレクトされ、処理が正常に完了するか確認してみます。

$ vault kv get test/vegetables
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T00:29:02.116778421Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

===== Data =====
Key        Value
---        -----
member1    asparagus
member2    broccoli
member3    cabbage

シークレットtest/vegetablesmember4member5を追加してみます。

$ vault kv patch -mount=test vegetables member4=eggplant
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:31:57.149367175Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2
$ vault kv patch -mount=test vegetables member5=tomato
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:32:28.58692667Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

追加された内容を確認します。

$ vault kv get test/vegetables
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:32:28.58692667Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    asparagus
member2    broccoli
member3    cabbage
member4    eggplant
member5    tomato

PR secondaryクラスタでPRレプリケーションのステータスを確認しておきます。

$ vault read sys/replication/performance/status
Fri May 31 01:35:10 UTC 2024
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
connection_state               ready
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717115786
last_remote_wal                151
last_start                     2024-05-31T00:57:34Z
merkle_root                    301132e95a95890d74557c73004ac299f0fb5cab
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-1 cluster_address:https://10.0.101.59:8201 connection_status:connected last_heartbeat:2024-05-31T01:35:09Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   perf-secondary
ssct_generation_counter        0
state                          stream-wals

PrimaryクラスタでPR secondaryクラスタで行った更新処理が反映されているか確認してみます。

$ vault kv get test/vegetables
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:32:28.58692667Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    asparagus
member2    broccoli
member3    cabbage
member4    eggplant
member5    tomato

member4member5が追加されており、PR secondaryクラスタに対して行った更新処理が、Primaryクラスタ側へリダイレクトされている事が確認できました。
続いて、PrimaryクラスタでもPRレプリケーションのステータスを確認してみます。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
corrupted_merkle_tree          false
known_secondaries              [perf-secondary]
last_corruption_check_epoch    -62135596800
last_performance_wal           151
last_reindex_epoch             0
last_wal                       151
merkle_root                    301132e95a95890d74557c73004ac299f0fb5cab
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[api_address:http://10.0.102.40:8200 clock_skew_ms:-1 cluster_address:https://10.0.102.40:8201 connection_status:connected last_heartbeat:2024-05-31T01:35:14Z last_heartbeat_duration_ms:2 node_id:perf-secondary]]
ssct_generation_counter        0
state                          running

last_walが先ほどから更新され、PR secondaryクラスタ側のlast_remote_walと同じ値になっており、データが同期されている事が分かります。

Enable DR replication

次に、DRレプリケーションをPrimaryクラスタとDR secondaryクラスタ間で設定していきます。設定方法は、PRレプリケーションを、PrimaryクラスタとPR secondaryクラスタ間で設定した時と同じ様な形になります。

まずは、PrimaryクラスタでDRレプリケーションを有効化していきます。利用しているAPIエンドポイントは、Enable DR primary replicationになります。

$ vault write -f sys/replication/dr/primary/enable
WARNING! The following warnings were returned from Vault:

  * This cluster is being enabled as a primary for replication. Vault will be
  unavailable for a brief period and will resume service shortly.

次に、DR secondaryクラスタ用のトークンをPrimaryクラスタで作成します。利用しているAPIエンドポイントは、Generate DR secondary tokenになります。

$ vault write sys/replication/dr/primary/secondary-token id="dr-secondary"
Key                              Value
---                              -----
wrapping_token:                  eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NvciI6IiIsImFkZHIiOiJodHRwOi8vMTAuMC4xMDEuNTk6ODIwMCIsImV4cCI6MTcxNzEyOTMwMSwiaWF0IjoxNzE3MTI3NTAxLCJqdGkiOiJodnMuY2V6NWQxVjVKaVBQdmJjSWZUWmp2dUczIiwibmJmIjoxNzE3MTI3NDk2LCJ0eXBlIjoid3JhcHBpbmcifQ.AS8blC557L5wjI9ulufuGaDmVIk-5B93kx05a2J_5UMNYZga2RckfWdzTHTOdi-nKnFI4gkkWHyfjCT8Moq637wVART1q1B078UDRewR2_BMreSFLVUj_OdjrRv8LV_GTDwZ-YPUjKk0c9xlVebfYEdDn_wGY2x5no-OMhcVzTYBBx_P
wrapping_accessor:               s4tnFG6auIh3sdyvUTwdU3m1
wrapping_token_ttl:              30m
wrapping_token_creation_time:    2024-05-31 03:51:41.208501325 +0000 UTC
wrapping_token_creation_path:    sys/replication/dr/primary/secondary-token

PrimaryクラスタでDRレプリケーションのステータスを確認してみます。

$ vault read sys/replication/dr/status
Key                            Value
---                            -----
cluster_id                     102d1b1a-d2bb-7d88-b948-7b7da16637d8
corrupted_merkle_tree          false
known_secondaries              [dr-secondary]
last_corruption_check_epoch    -62135596800
last_dr_wal                    158
last_reindex_epoch             0
last_wal                       158
merkle_root                    7b97088fd816bf6d6a79270e62932d6fae87277a
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[connection_status:disconnected node_id:dr-secondary]]
ssct_generation_counter        0
state                          running

DR secondaryクラスタの設定を行なっていないため、secondariesの値にクラスタが登録されていない状態である事が確認出来ます。

DR secondaryクラスタで、DRレプリケーションを有効化する前に、クラスタのステータスを確認しておきます。

$ vault status
Key                     Value
---                     -----
Seal Type               shamir
Initialized             true
Sealed                  false
Total Shares            1
Threshold               1
Version                 1.16.3+ent
Build Date              2024-05-29T00:40:37Z
Storage Type            raft
Cluster Name            vault-cluster-978c535e
Cluster ID              d13e5931-f7d5-0a2d-0162-729bc16eecce
HA Enabled              true
HA Cluster              https://10.0.103.231:8201
HA Mode                 active
Active Since            2024-05-31T03:50:18.547911905Z
Raft Committed Index    138
Raft Applied Index      138
Last WAL                27

Primaryクラスタで生成したDR secondaryクラスタ用のトークンを環境変数DR_SECONDARY_TOKENに設定します。

export DR_SECONDARY_TOKEN="eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NvciI6IiIsImFkZHIiOiJodHRwOi8vMTAuMC4xMDEuNTk6ODIwMCIsImV4cCI6MTcxNzEyOTMwMSwiaWF0IjoxNzE3MTI3NTAxLCJqdGkiOiJodnMuY2V6NWQxVjVKaVBQdmJjSWZUWmp2dUczIiwibmJmIjoxNzE3MTI3NDk2LCJ0eXBlIjoid3JhcHBpbmcifQ.AS8blC557L5wjI9ulufuGaDmVIk-5B93kx05a2J_5UMNYZga2RckfWdzTHTOdi-nKnFI4gkkWHyfjCT8Moq637wVART1q1B078UDRewR2_BMreSFLVUj_OdjrRv8LV_GTDwZ-YPUjKk0c9xlVebfYEdDn_wGY2x5no-OMhcVzTYBBx_P"

DRレプリケーションを有効化します。利用するAPIエンドポイントはEnable DR secondaryになります。

$ vault write sys/replication/dr/secondary/enable token=$DR_SECONDARY_TOKEN
WARNING! The following warnings were returned from Vault:

  * Vault has successfully found secondary information; it may take a while to
  perform setup tasks. Vault will be unavailable until these tasks and initial
  sync complete.

DRレプリケーションのステータスを確認します。

$ vault read sys/replication/dr/status
Key                            Value
---                            -----
cluster_id                     102d1b1a-d2bb-7d88-b948-7b7da16637d8
connection_state               ready
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717127660
last_remote_wal                167
last_start                     2024-05-31T03:54:20Z
merkle_root                    205874f1b7ec6ad78e6f70c33e85e1f560d6ddec
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-1 cluster_address:https://10.0.101.59:8201 connection_status:connected last_heartbeat:2024-05-31T03:54:55Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   dr-secondary
ssct_generation_counter        0
state                          stream-wals

last_remote_wal167statestream-walsとなっている事が確認できます。

続いて、Primaryクラスタで改めて、DRレプリケーションのステータスを確認してみます。

$ vault read sys/replication/dr/status
Key                            Value
---                            -----
cluster_id                     102d1b1a-d2bb-7d88-b948-7b7da16637d8
corrupted_merkle_tree          false
known_secondaries              [dr-secondary]
last_corruption_check_epoch    -62135596800
last_dr_wal                    167
last_reindex_epoch             0
last_wal                       167
merkle_root                    205874f1b7ec6ad78e6f70c33e85e1f560d6ddec
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[api_address:http://10.0.103.231:8200 clock_skew_ms:-1 cluster_address:https://10.0.103.231:8201 connection_status:connected last_heartbeat:2024-05-31T03:55:00Z last_heartbeat_duration_ms:2 node_id:dr-secondary]]
ssct_generation_counter        0
state                          running

last_walの値がDR secondaryクラスタのlast_remote_walと同じ値であり、データが同期されている事が確認できます。また、staterunningとなっている事から、正常にDRレプリケーションが動作している事が確認できます。

PR/DRレプリケーションのステータスは以下の様にUIからも確認する事が出来ます。

PrimaryクラスタのUIで確認できるレプリケーションステータス


DRレプリケーションのステータス


PRレプリケーションのステータス

Stop Primary cluster

Primaryクラスタから、PR secondaryクラスタへのPRレプリケーション、DR secondaryクラスタへのDRレプリケーション構成を組む事が出来たので、この後はPrimaryクラスタに障害が発生し、DR発動した場合の動きを確認していきたいと思います。

Create Batch DR operation token

Primaryクラスタ障害時に、DR secondaryクラスタを新しいPrimaryに昇格させるには、DR オペレーショントークンが必要になります。DRオペレーショントークンの生成プロセスでは、Seal キーまたは Vault が Auto-Seal を使用している場合リカバリキーが必要になります。一般的に障害発生は予見出来ない事から、キーの利用に際して時間が掛かってしまい、迅速にDRオペレーショントークンを生成するのが困難になる可能性があります。

この様な事態に対処するために、Primaryクラスタで生成したバッチDRオペレーショントークンを利用して、DR secondaryクラスタを昇格させることができます。Primaryクラスタ障害に備えるためには、バッチDRオペレーショントークンを活用する方法がおすすめです。

詳細はDR operation token strategyに記載されているので、こちらもご参照下さい。

それではバッチDRオペレーショントークンを作成していきます。

トークンに付与するポリシーを作成します。

$ vault policy write \
    dr-secondary-promotion - <<EOF
path "sys/replication/dr/secondary/promote" {
  capabilities = [ "update" ]
}

# To update the primary to connect
path "sys/replication/dr/secondary/update-primary" {
    capabilities = [ "update" ]
}

# Only if using integrated storage (raft) as the storage backend
# To read the current autopilot status
path "sys/storage/raft/autopilot/state" {
    capabilities = [ "update" , "read" ]
}
EOF
Success! Uploaded policy: dr-secondary-promotion
$ vault policy list
all-vegetables
default
dr-secondary-promotion
read-fruits
vault-admin
write-fruits
root
$ vault policy read dr-secondary-promotion
path "sys/replication/dr/secondary/promote" {
  capabilities = [ "update" ]
}

# To update the primary to connect
path "sys/replication/dr/secondary/update-primary" {
    capabilities = [ "update" ]
}

# Only if using integrated storage (raft) as the storage backend
# To read the current autopilot status
path "sys/storage/raft/autopilot/state" {
    capabilities = [ "update" , "read" ]
}

作成したdr-secondary-promotionポリシーを付与したfailover-handlerという名前のトークンロールを作成します。そのトークンのタイプをbatchにします。バッチトークンを更新することはできないので、renewableパラメータの値をfalseに設定し、orphanパラメータはtrueに設定します。

$ vault write auth/token/roles/failover-handler \
  allowed_policies=dr-secondary-promotion \
  orphan=true \
  renewable=false \
  token_type=batch
Success! Data written to: auth/token/roles/failover-handler

作成したロールでトークンを生成します。

$ vault token create -role=failover-handler -ttl=24h
Key                  Value
---                  -----
token                hvb.AAAAAQIcUxqLEEQ5-OGDTJdAG-oGn2gfpi6ez7kMTUkBOcFDRaSmknWM6p-Lnrcoj6uxA2Uvao7FcUKA4S4tD5WE4OrpGBTRlmAC6aJfsEsrBUZcWVy0C7cjaIXsC14wpdnipSbyjmZbpFUbvgLTzwbscLb3ZwFBNBeB4BnWLzGC5v96DI0TYLXiNPUKpTgJhFBoJv5AAg
token_accessor       n/a
token_duration       24h
token_renewable      false
token_policies       ["default" "dr-secondary-promotion"]
identity_policies    []
policies             ["default" "dr-secondary-promotion"]
$ vault token lookup hvb.AAAAAQIcUxqLEEQ5-OGDTJdAG-oGn2gfpi6ez7kMTUkBOcFDRaSmknWM6p-Lnrcoj6uxA2Uvao7FcUKA4S4tD5WE4OrpGBTRlmAC6aJfsEsrBUZcWVy0C7cjaIXsC14wpdnipSbyjmZbpFUbvgLTzwbscLb3ZwFBNBeB4BnWLzGC5v96DI0TYLXiNPUKpTgJhFBoJv5AAg
Fri May 31 04:01:48 UTC 2024
Key                 Value
---                 -----
accessor            n/a
creation_time       1717128097
creation_ttl        24h
display_name        token
entity_id           n/a
expire_time         2024-06-01T04:01:37Z
explicit_max_ttl    0s
id                  hvb.AAAAAQIcUxqLEEQ5-OGDTJdAG-oGn2gfpi6ez7kMTUkBOcFDRaSmknWM6p-Lnrcoj6uxA2Uvao7FcUKA4S4tD5WE4OrpGBTRlmAC6aJfsEsrBUZcWVy0C7cjaIXsC14wpdnipSbyjmZbpFUbvgLTzwbscLb3ZwFBNBeB4BnWLzGC5v96DI0TYLXiNPUKpTgJhFBoJv5AAg
issue_time          2024-05-31T04:01:37Z
meta                <nil>
num_uses            0
orphan              true
path                auth/token/create/failover-handler
policies            [default dr-secondary-promotion]
renewable           false
role                failover-handler
ttl                 23h59m49s
type                batch

トークンに関してより詳細な情報を知りたい場合、以下のドキュメントをご参照下さい。
https://developer.hashicorp.com/vault/docs/concepts/tokens

バッチDRオペレーショントークンが作成出来たので、各クラスタでレプリケーションのステータスを確認した上で、Primaryクラスタの仮想マシンを停止させます。

Primaryクラスタ

$ vault read sys/replication/dr/status
Key                            Value
---                            -----
cluster_id                     102d1b1a-d2bb-7d88-b948-7b7da16637d8
corrupted_merkle_tree          false
known_secondaries              [dr-secondary]
last_corruption_check_epoch    -62135596800
last_dr_wal                    169
last_reindex_epoch             0
last_wal                       169
merkle_root                    5b48cc501adf6af26d0bedc1eb9b2bd47e511c8d
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[api_address:http://10.0.103.231:8200 clock_skew_ms:-1 cluster_address:https://10.0.103.231:8201 connection_status:connected last_heartbeat:2024-05-31T04:02:20Z last_heartbeat_duration_ms:2 node_id:dr-secondary]]
ssct_generation_counter        0
state                          running
$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
corrupted_merkle_tree          false
known_secondaries              [perf-secondary]
last_corruption_check_epoch    -62135596800
last_performance_wal           169
last_reindex_epoch             0
last_wal                       169
merkle_root                    00c75384cd1ecc50a431d0aceb5cba71675e7ad1
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[api_address:http://10.0.102.40:8200 clock_skew_ms:-1 cluster_address:https://10.0.102.40:8201 connection_status:connected last_heartbeat:2024-05-31T04:02:24Z last_heartbeat_duration_ms:2 node_id:perf-secondary]]
ssct_generation_counter        0
state                          running

PR secondaryクラスタ

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
connection_state               ready
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717115786
last_remote_wal                169
last_start                     2024-05-31T00:57:34Z
merkle_root                    00c75384cd1ecc50a431d0aceb5cba71675e7ad1
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-2 cluster_address:https://10.0.101.59:8201 connection_status:connected last_heartbeat:2024-05-31T04:02:34Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   perf-secondary
ssct_generation_counter        0
state                          stream-wals

DR secondaryクラスタ

$ vault read sys/replication/dr/status
Key                            Value
---                            -----
cluster_id                     102d1b1a-d2bb-7d88-b948-7b7da16637d8
connection_state               ready
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717127660
last_remote_wal                169
last_start                     2024-05-31T03:54:20Z
merkle_root                    5b48cc501adf6af26d0bedc1eb9b2bd47e511c8d
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-1 cluster_address:https://10.0.101.59:8201 connection_status:connected last_heartbeat:2024-05-31T04:02:45Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   dr-secondary
ssct_generation_counter        0
state                          stream-wals

Operation in PR secondary

Primaryクラスタを停止させた後、PR secondaryクラスタからVaultの操作を行い、Primaryクラスタ障害時の挙動を確認してみます。
Read処理はPR secondaryクラスタで完結するため影響なく操作出来る。一方、PR secondaryクラスタに対して行われたWrite処理は、Primaryクラスタへリダイレクトされるため、Write処理は出来ない。が期待される挙動になります。

まずは、Primaryクラスタ停止後のPR secondaryクラスタのクラスタステータスを確認します。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
connection_state               transient_failure
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717115786
last_remote_wal                169
last_start                     2024-05-31T00:57:34Z
merkle_root                    00c75384cd1ecc50a431d0aceb5cba71675e7ad1
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-2 cluster_address:https://10.0.101.59:8201 connection_status:disconnected last_heartbeat:2024-05-31T06:27:44Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   perf-secondary
ssct_generation_counter        0
state                          stream-wals

再度、Userpass認証メソッドのadminユーザーでログインし、作業を行います。

vault login -method=userpass -path=userpass username=admin password=changeme

まずは、Read処理を行なってみます。こちらは、Primaryクラスタ障害発生前と同じ様に実施出来ます。

$ vault kv get test/fruits
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:24:02.967956548Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    apple
member2    banana
member3    cherry
member4    lemon
$ vault kv get test/vegetables
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:32:28.58692667Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    asparagus
member2    broccoli
member3    cabbage
member4    eggplant
member5    tomato

続いて、Write処理を試してみます。シークレットtest/vegetablesmember6を追加してみます。

$ vault kv patch -mount=test vegetables  member6=pumpkin
Error writing data to test/data/vegetables: Error making API request.

URL: PATCH http://127.0.0.1:8200/v1/test/data/vegetables
Code: 500. Errors:

* 1 error occurred:
	* request error returned from primary: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 10.0.101.59:8201: i/o timeout"

Primaryクラスタが稼働している際は行えた更新処理が、上記の様にエラーになります。DR secondaryクラスタをPrimaryに昇格させた後、再度同様のオペレーションをPR secondaryクラスタで実施してみます。

Promote DR secondary to Primary

DR secondaryクラスタをPrimaryへ昇格させ、クラスタ間のレプリケーション構成の中で、Primaryを設定していきます。

Create Batch DR operation tokenで作成したバッチDRオペレーショントークンを環境変数DR_OPERATION_TOKENに設定します。

export DR_OPERATION_TOKEN="hvb.AAAAAQIcUxqLEEQ5-OGDTJdAG-oGn2gfpi6ez7kMTUkBOcFDRaSmknWM6p-Lnrcoj6uxA2Uvao7FcUKA4S4tD5WE4OrpGBTRlmAC6aJfsEsrBUZcWVy0C7cjaIXsC14wpdnipSbyjmZbpFUbvgLTzwbscLb3ZwFBNBeB4BnWLzGC5v96DI0TYLXiNPUKpTgJhFBoJv5AAg"

DR secondaryクラスタをPrimaryへ昇格させる前にDRレプリケーションのステータスを確認します。

$ vault read sys/replication/dr/status
Key                            Value
---                            -----
cluster_id                     102d1b1a-d2bb-7d88-b948-7b7da16637d8
connection_state               transient_failure
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717127660
last_remote_wal                169
last_start                     2024-05-31T03:54:20Z
merkle_root                    5b48cc501adf6af26d0bedc1eb9b2bd47e511c8d
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-2 cluster_address:https://10.0.101.59:8201 connection_status:disconnected last_heartbeat:2024-05-31T06:27:45Z last_heartbeat_duration_ms:9]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   dr-secondary
ssct_generation_counter        0
state                          stream-wals

APIエンドポイントPromote DR secondaryを利用して、DR secondaryクラスタをPrimaryへ昇格させます。

$ vault write -f sys/replication/dr/secondary/promote dr_operation_token=$DR_OPERATION_TOKEN
WARNING! The following warnings were returned from Vault:

  * This cluster is being promoted to a replication primary. Vault will be
  unavailable for a brief period and will resume service shortly.

Primaryへの昇格を行った後に、DRレプリケーションのステータスを確認してみます。modeprimaryに変更されており、DR secondaryクラスタがPrimaryへ昇格した事が確認出来ます。

$ vault read sys/replication/dr/status
Key                            Value
---                            -----
cluster_id                     102d1b1a-d2bb-7d88-b948-7b7da16637d8
corrupted_merkle_tree          false
known_secondaries              []
last_corruption_check_epoch    -62135596800
last_dr_wal                    22
last_reindex_epoch             0
last_wal                       22
merkle_root                    1e3d3bf691abeed42a5dbcd5aeab17dd80d10fc3
mode                           primary
primary_cluster_addr           n/a
secondaries                    []
ssct_generation_counter        1
state                          running

Primaryへ昇格したDR secondaryクラスタで操作を行います。環境変数VAULT_TOKENに、Primaryクラスタを初期化した際に生成されたルートトークンを設定します。

export VAULT_TOKEN=hvs.FrousNxXs5wBaNqEi4KCLSwa

シークレットエンジン、登録されたシークレットを確認します。Primaryへ昇格したDR secondaryクラスタで、Primaryクラスタと同様の内容が確認する事が出来ます。

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_f84483ac    per-token private secret storage
identity/     identity     identity_6b93d7f2     identity store
sys/          system       system_6f62b677       system endpoints used for control, policy and debugging
test/         kv           kv_5d2f0bc6           kv-v2 secrets engine for test
$ vault kv list test
Keys
----
fruits
vegetables
$ vault kv get test/vegetables
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:32:28.58692667Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    asparagus
member2    broccoli
member3    cabbage
member4    eggplant
member5    tomato
$ vault kv get test/fruits
== Secret Path ==
test/data/fruits

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T01:24:02.967956548Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

===== Data =====
Key        Value
---        -----
member1    apple
member2    banana
member3    cherry
member4    lemon

続いて、Primary昇格したDR secondaryクラスタでPRレプリケーションのステータスを確認します。modeprimaryとなっていますが、secondariesに関してはconnection_status:disconnectedとなっています。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
corrupted_merkle_tree          false
known_secondaries              [perf-secondary]
last_corruption_check_epoch    -62135596800
last_performance_wal           21
last_reindex_epoch             0
last_wal                       22
merkle_root                    c805dcb659a583a5f6bf4714f015ab7f6458a867
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[connection_status:disconnected node_id:perf-secondary]]
ssct_generation_counter        1
state                          running

DR secondaryをPrimaryへ昇格させたので、再度PR secondaryクラスタからVaultへオペレーションを行い、挙動を確認してみます。

Operation in PR secondary

DR secondaryクラスタをPrimaryへ昇格させた後、PR secondaryクラスタでPRレプリケーションのステータスを確認してみます。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
connection_state               transient_failure
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.101.59:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717115786
last_remote_wal                169
last_start                     2024-05-31T00:57:34Z
merkle_root                    00c75384cd1ecc50a431d0aceb5cba71675e7ad1
mode                           secondary
primaries                      [map[api_address:http://10.0.101.59:8200 clock_skew_ms:-2 cluster_address:https://10.0.101.59:8201 connection_status:disconnected last_heartbeat:2024-05-31T06:27:44Z last_heartbeat_duration_ms:2]]
primary_cluster_addr           https://10.0.101.59:8201
secondary_id                   perf-secondary
ssct_generation_counter        0
state                          stream-wals

上記の様に、DR secondaryをPrimaryへ昇格させた後も、PR secondaryクラスタが認識しているPrimaryは元のPrimaryクラスタ(10.0.101.59)です。
ダメ元で再度、Write処理を試してみます。シークレットtest/vegetablesmember6を追加してみます。

$ vault kv patch -mount=test vegetables  member6=pumpkin
Error writing data to test/data/vegetables: Error making API request.

URL: PATCH http://127.0.0.1:8200/v1/test/data/vegetables
Code: 500. Errors:

* 1 error occurred:
	* request error returned from primary: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 10.0.101.59:8201: i/o timeout"

DR secondaryクラスタのPrimary昇格前と同様のエラーであり、PR secondaryクラスタのPrimaryの向き先を手動で変更する必要がありそうです。
PR secondaryクラスタが認識しているPrimaryを変更するためには、APIエンドポイントUpdate performance secondary's primaryを利用します。

update_primary_addrsを設定するためのペイロードを作成します。

$ cat << EOF > update_primary.json
> {
  "update_primary_addrs": ["10.0.103.231:8201"]
}
> EOF

作成したupdate_primary.jsonを指定して、PR secondaryクラスタが認識しているPrimaryをPrimaryへ昇格したDR secondaryクラスタ(10.0.103.231)へ更新します。

$ vault write sys/replication/performance/secondary/update-primary @update_primary.json
WARNING! The following warnings were returned from Vault:

  * Replication is restarting. Vault may be unavailable for a brief period of
  time.

PRレプリケーションのステータスを確認してみます。primariesが更新され、Primaryへ昇格したDR secondaryクラスタになっている事が確認出来ます。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
connection_state               ready
corrupted_merkle_tree          false
known_primary_cluster_addrs    [https://10.0.103.231:8201]
last_corruption_check_epoch    -62135596800
last_reindex_epoch             1717115786
last_remote_wal                0
last_start                     2024-05-31T06:40:23Z
merkle_root                    c805dcb659a583a5f6bf4714f015ab7f6458a867
mode                           secondary
primaries                      [map[api_address:http://10.0.103.231:8200 clock_skew_ms:-1 cluster_address:https://10.0.103.231:8201 connection_status:connected last_heartbeat:2024-05-31T06:40:33Z last_heartbeat_duration_ms:1]]
primary_cluster_addr           https://10.0.103.231:8201
secondary_id                   perf-secondary
ssct_generation_counter        0
state                          stream-wals

再度Write処理を試してみます。シークレットtest/vegetablesmember6を追加してみます。

$ vault kv patch -mount=test vegetables  member6=pumpkin
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T06:40:54.035033652Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            4
$ vault kv get test/vegetables
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T06:40:54.035033652Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            4

===== Data =====
Key        Value
---        -----
member1    asparagus
member2    broccoli
member3    cabbage
member4    eggplant
member5    tomato
member6    pumpkin

DR secondaryクラスタがPrimaryへ昇格したことで、PR secondaryクラスタに対してリクエストされたWrite処理がPrimaryへリダイレクトされ、Write処理も正常に行える事が確認出来ました。

Primaryへ昇格したDR secondaryクラスタでも更新が反映されたか確認してみます。

PRレプリケーションのステータスを確認してみます。
PR secondaryクラスタでPrimaryの宛先変更を行った事で、PRレプリケーションのsecondariesがPR secondaryクラスタに更新されている事が確認出来ます。

$ vault read sys/replication/performance/status
Key                            Value
---                            -----
cluster_id                     f71523a9-41a8-3a84-7feb-6b8cc64d7c57
corrupted_merkle_tree          false
known_secondaries              [perf-secondary]
last_corruption_check_epoch    -62135596800
last_performance_wal           21
last_reindex_epoch             0
last_wal                       22
merkle_root                    c805dcb659a583a5f6bf4714f015ab7f6458a867
mode                           primary
primary_cluster_addr           n/a
secondaries                    [map[api_address:http://10.0.102.40:8200 clock_skew_ms:-1 cluster_address:https://10.0.102.40:8201 connection_status:connected last_heartbeat:2024-05-31T06:40:38Z last_heartbeat_duration_ms:1 node_id:perf-secondary]]
ssct_generation_counter        1
state                          running

PR secondaryで更新したシークレットtest/vegetablesmember6が追加されている事が確認出来ます。

$ vault kv get test/vegetables
==== Secret Path ====
test/data/vegetables

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-31T06:40:54.035033652Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            4

===== Data =====
Key        Value
---        -----
member1    asparagus
member2    broccoli
member3    cabbage
member4    eggplant
member5    tomato
member6    pumpkin

PR/DRレプリケーションの設定、Primary障害時の挙動、DR secondaryクラスタのPrimary昇格、PR secondaryが認識しているPrimaryの更新などを確認してきました。

参考になる部分があれば幸いです!

References

Discussion