HashiCorp Vault HA Clusterの運用

# 概要

HashiCorp Vault にて、Raftを利用したHA Cluster構成を組んでいる場合の、バックアップ／リストア、アップデート、障害対応などの運用について検証した記録です。

# 前提条件

- 本記事は、下記内容に沿ってVault Cluster構成を組んだ環境での説明となります。
  [HashiCorp Vault HA Cluster構築](https://qiita.com/saitamanokusa/items/35a9e0676a5f0ea41c37)
- 本記事は、VaultのRaft、Clusterの動作を理解していることを前提とします。
  [HashiCorp Vault HA Cluster 基本動作](https://qiita.com/saitamanokusa/items/99f6db467d52d798460c)
- HashiCorp Vault 1.13.2 を使って確認した内容です。
- Vaultは、Auto-Unseal を利用できるものとします。（未設定の場合は利用できる状態まで済ませてください）

# はじめに

Vaultを自前で運用するにあたり、一番気になるのは、運用のメンテナンスコストかと思います。
本記事では、通常発生しうる、バックアップ／リストア、アップデート等のメンテナンス操作、および万が一障害となった場合のリカバリー手段について解説します。

# snapshotでのバックアップ／リストア

Raft構成の場合、snapshot コマンドで、バックアップ、リストアの操作が容易に行なえます。

```shell
# Leader node を確認
vault operator raft list-peers

# Leader node にて、バックアップを取得
vault operator raft snapshot save vault_snapshot_2023-05-18.bak

# ファイルに出力されてことを確認
ls -l vault_snapshot_*

# 適当に編集操作をおこなう（省略）

# 事前に取得したバックアップから、リストア
vault operator raft snapshot restore vault_snapshot_2023-05-18.bak

# 編集操作が戻っていることを確認（省略）

```

:::note warn
vault operator raft snapshot コマンドは、Leader node で行う必要があります。
定期処理を行う場合、AWSならばALBに向けたコマンドにすることで、ヘルスチェックにより Leader node に向けられます。
:::

[Vault Data Backup Standard Procedure](https://developer.hashicorp.com/vault/tutorials/standard-procedures/sop-backup)

# アップデート（メンテナンス）方法

vault cluster をアップデートする際の対応方法です。
※vault に限らず、OSメンテを行う場合も同じ要領です。

## snapshot でバックアップ

vault のデータストアは、下位互換性がありません。
万が一もとのバージョンに戻したい場合、vaultとあわせて、データも元のバージョン時点のものに戻す必要があります。

そのため、事前に必ずSnapshotで、ファイルベースのバックアップを取得します。

```shell
# Leader node にて、バックアップを取得
vault operator raft snapshot save vault_before_update.bak
# 確認
ls -l
```

## Standby Node のアップデート

先に、Standby Node のアップデートを済ませます。

```shell
# Standby Node を確認 (Active Node = false)
vault operator members

# Standby Node でアップデートを実施
sudo dnf update vault

# 状況確認 ※表示されるバージョン変わらず
vault operator members

# サービス再起動で、バージョン更新を確認
sudo systemctl restart vault
vault operator members

# 該当ノードが voter となっていること、 autopilot の状態に問題がないことを確認
vault operator raft list-peers
vault operator raft autopilot state
```

:::note warn
アップデート時は、Raft の耐障害性が確実に確保されるように注意してください。
3台構成の場合、確実に1台ずつ進める必要があります。
:::

## Active Nodeのアップデート

Standby Node のアップデートが完了したら、Active Node のアップデートを対応します。

Active Node は、上位ALBからの通信が流れてくるため、突然メンテナンスを行うと、ヘルスチェック検出で切り替わるまでの間、障害となってしまいます。
そのため、事前に強制的にStandby Node に切り替え、ALBからの通信が別nodeに切り替わったことを確認の上、メンテナンスを行います。

```shell
# LeaderNodeを、手動で Standby へ切り替え
vault operator step-down
# standby に切り替わったことを確認
vault operator members

# ALB からの通信が、別nodeに切り替わったことを確認
# AWS管理画面または外部からALB向けのコマンドでチェック
# ※下記に確認方法ページへのリンクあり

# standby および通信が切りわり（メンテOK状態）が確認できたら、アップデートを実施
sudo dnf update vault
sudo systemctl restart vault
vault operator raft list-peers
vault operator raft autopilot state
```

:::note
ヘルスチェック検出による宛先ノード変更確認については、こちらで解説しています
[Active Node変更時のALB経由の通信チェック](https://qiita.com/saitamanokusa/items/99f6db467d52d798460c#active-node%E5%A4%89%E6%9B%B4%E6%99%82%E3%81%AEalb%E7%B5%8C%E7%94%B1%E3%81%AE%E9%80%9A%E4%BF%A1%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF)
:::

[Vault Upgrade Standard Procedure](https://developer.hashicorp.com/vault/tutorials/standard-procedures/sop-upgrade#rolling-upgrade-procedure-for-upgrading-a-single-ha-cluster)

# 障害時のリカバリー手段

Raftは、必要ノード数を確保できないと、一切アクセスできなくなります。
その場合のリカバリー手段について、確認がとれた方法を紹介します。

## single node でのリカバリー

1つ目は、強制的に、シングルノード構成で起動する手段です。

Raft のデータが保存場所に、シングルノード構成で強制起動させるためのファイルを配置し、vaultを再起動します。

id, address は、`/etc/vault.d/vault.hcl` の設定で使用している、node_id, cluster_addr で指定しているIPアドレスで指定します。

```shell
# Raft データPathの指定位置に、シングルノード起動用のファイルを配置
cat > /opt/vault/raft/raft/peers.json << EOF
[
  {
    "id": "vault-01",
    "address": "192.168.11.101:8201"
  }
]
EOF

chown vault: /opt/vault/raft/raft/peers.json

# vault を再起動起
systemctl restart vault

# status 上は、HA Mode active となったことを確認
vault status
Key                      Value
---                      -----
(省略)
Storage Type             raft
(省略)
HA Enabled               true
HA Cluster               https://192.168.11.101:8201
HA Mode                  active
(省略)

# 単一ノードで起動したことを確認
vault login ****
vault operator raft list-peers
Node        Address                     State     Voter
----        -------                     -----     -----
vault-01    192.168.11.101:8201    leader    true

# あとは、他のメンバーノードでも、データ削除したうえで起動すれば、Raftに追加され、Clusterが復旧します。
```

:::note
もしauto-joinを利用するなど、構成ファイルで、cluster_addr、node_id が分からない場合

- address は、自ノードのプライベートIPで指定
- id は、`/var/log/messages` より、LocalID で検索すると見つかります。

```shell
grep LocalID /var/log/messages
```

:::

[Vault Cluster Lost Quorum Recovery](https://developer.hashicorp.com/vault/tutorials/day-one-raft/raft-lost-quorum)

## snapshot バックアップからのリカバリー

2つ目の方法は、Snapshotで取得したバックアップファイルからのリカバリーです。

```shell
# 既存のデータを削除し、単一ノードで起動
systemctl stop vault
rm -rf /opt/vault/raft/*
systemctl start vault

# vault を初期化
# 生成される recovery key や root token は、一時的に使用するのみです
vault operator init

# 生成したroot token でloginし、単一ノードで正常起動したことを確認
vault login ****
vault status
vault operator raft list-peers

# あらかじめ取得済みのバックアップファイルより、リストア
vault operator raft snapshot restore -force vault_snapshot.bak

# 【重要】 vault を一度再起動する
# これにより、バックアップ元のUnseal key (recovery key) でのunseal操作がなされます
systemctl restart vault

# バックアップ元のデータが戻ったことを確認　（省略）

# あとは、他のメンバーノードでも、データ削除したうえで起動すれば、Raftに追加され、Clusterが復旧します。
```

[Standard Procedure for Restoring a Vault Cluster](https://developer.hashicorp.com/vault/tutorials/standard-procedures/sop-restore)

## RaftからFileへの移行

こちらは、Clusterのリカバリーとは異なりますが、、、
Raft から、File への変換を行い、デフォルトのFileストレージとして、1台構成で起動させる方法です。

※パーミッションがややこしいため、root ユーザーでの操作をお勧めします。

現在のディレクトリに、データ変換用の定義ファイル`migrate.hcl`を作成します。

```shell:migrate.hcl
storage_source "raft" {
  path    = "/opt/vault/raft"
}

storage_destination "file" {
  path = "/opt/vault/data"
}
```

```shell
systemctl stop vault 

# あらかじめ変換先を空にしておく
rm -rf /opt/vault/data/*

# 上記で用意したファイルを使って、データ変換を実行
vault operator migrate -config migrate.hcl

# 変換されたデータを確認
ls -l /opt/vault/data
# owner ユーザー/グループを vault に修正
chown -R vault: /opt/vault/data

# (構成ファイル /etc/vault.d/vault.hcl を Fileストレージ用に構成したうえで)
# vault 起動
systemctl start vault

# Fileストレージで起動したことを確認
vault status

# データ移行ができたことを確認
vault login ****
vault auth list
vault secrets list

```

[operator migrate](https://developer.hashicorp.com/vault/docs/commands/operator/migrate)

# 最後に

本記事で取り扱ったようなメンテナンス操作は、使う機会がないため、なかなか慣れないかもしれませんが、検証環境で実際に操作してみれば、すぐに要領をつかめるかと思います。
本記事の内容が、Cluster構成を進める足がかりとなれば幸いです。