これまでもこのブログでJuju + MAASを使ったOpenStackの構築方法について定期的に取り上げていましたが、最近の構成でOpenvSwitchからOVNが使われるようになったり、キーマネージメント関連でVaultが使われるようになったりとだいぶ変更があったため、試してみることにしました。
ソフトウェア/ハードウェア構成
以下の構成で構築できたことを確認している。
ソフトウェア
- Juju 2.7.8-bionic-amd64
- MAAS 2.7.3 (8291-g.384e521e6-0ubuntu1~18.04.2)
- OpenStack Victoria
ハードウェア
- 物理サーバー3台(NIC2つ、ストレージ2つ、サーバーにMAAS Tagを設定しておく)
- bootstrap用サーバー1台(物理でも仮想でも良い。vCPU 2、メモリー8GB、ストレージ60GB程度)
Jujuはアプリケーションをデプロイするためのソフトウェアで、MAASはサーバーを管理するソフトウェアである。 OSをサーバーにデプロイしたり、Linux KVMホストを自動で構築できたりする。 JujuはMAASで管理しているノードを使うことができる。今回はJujuとMAASの組み合わせでOpenStackを構築する。
JujuはAnsible Playbookに相当するCharmとBundleというものがある。Charmはアプリケーションをデプロイするもの、Bundleは複数のアプリケーションを一括でデプロイ、設定を行って使用可能な状態にするものである(例えばWordPressを構築する場合、Webサーバーとデータベースサーバーをセットアップして、WordPressアプリケーションをセットアップする。Bundleはこの一連の作業を全て行う)。
OpenStackをJuju Bundleを使ってデプロイ
ここから先はドキュメントを見ながらデプロイする。
まず、Charm CLIをインストールする。
$ sudo snap install charm --channel=stable --classic
Charm CLIをインストールすると、Bundleのダウンロードが簡単になる。 次のようなコマンドでダウンロードが可能。バージョン指定しない場合は最新版が落ちてくる。
$ charm pull openstack-base-73 ~/openstack-base-73
(必要に合わせて)Bundleを修正する。
$ cd ~/openstack-base && cp bundle.yaml bundle-edit.yaml && vi bundle-edit.yaml
Bundleは以下の箇所を修正した。machinesにMAAS Tagを指定した。
variables: openstack-origin: &openstack-origin cloud:focal-victoria data-port: &data-port br-ex:eno50 ※変更したところ(二つ目のNIC external network用) worker-multiplier: &worker-multiplier 0.25 osd-devices: &osd-devices /dev/sdb /dev/vdb ※変更したところ expected-osd-count: &expected-osd-count 3 expected-mon-count: &expected-mon-count 3 machines: '0': series: focal constraints: "tags=bay5" ※変更したところ(MAAS tagを追加) '1': series: focal constraints: "tags=bay10" ※変更したところ(MAAS tagを追加) '2': series: focal constraints: "tags=bay13" ※変更したところ(MAAS tagを追加)
Bundleを使ってJujuでOpenStackをデプロイする。 openstack-base-spaces-overlay.yaml
はMAASのスペースに合わせて適切に編集する。
$ juju deploy ./bundle-edit.yaml --overlay ./openstack-base-spaces-overlay.yaml
Jujuによるデプロイ処理はおおよそ30分から1時間程度の時間を要する。 以前はこれだけだったが、最近のOpenStack Base Bundleは、Vaultを使って安全なストレージと証明書管理サービスを提供するために利用している。 従って、デプロイ後にVault周りの追加対応が必要になる。
Vaultクライアントのインストールと設定
ここから先は以下を参考に実施。
まず、Vaultクライアントを入れる。snapパッケージで入れる場合は以下のコマンドを実行する。
$ sudo snap install vault
シェル変数VAULT_ADDRを定義する。
$ export VAULT_ADDR="http://172.17.28.164:8200"
「172.17.28.164」の部分は juju status vault/0
とか実行して、VaultサーバーのIPアドレスを確認して指定する。
Vaultクライアントでコマンドを実行し、Vaultのデプロイメントを初期化する。 次のような応答が返されるはず。
Vaultを初期化するとVaultデプロイメントのシールを解除するためのキーと初期ルートトークンが発行される。
$ vault operator init -key-shares=5 -key-threshold=3 Unseal Key 1: XqeOza3SY6f4L6xfuk6f8JumrEF7cak9mUXCCPRXzs4B Unseal Key 2: djvVAAste0F5iSe43nmBs2ZX5r+wUqHe4UfUrcprWkyM Unseal Key 3: iSXHBdTNIKrbd3JIEI+n+q7j04Q4HPsQOHgk7apupttT Unseal Key 4: J8jzdUi0HOWgx8Ig75Mu8uVQTXkw6yNv2kMhjeNz2/5B Unseal Key 5: xTJkk3guA9Mq3CYfDhIBevSWrD1CIer6q70HVACMbduc Initial Root Token: ebded15e-c908-5d3a-1df0-1e7e7218c162 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.
発行された時点ではキーは密封されているため、unseal(開封)する必要がある。 各Vaultユニットは個別に開封する必要があるため、複数のボールトユニットがある場合はユニットごとに、以下の開封プロセスを繰り返して個々のユニットを指すようにVAULT_ADDR環境変数を毎回変更する。
「vault operator unseal」コマンドを3回行ったのは、「vault operator init -key-shares=5 -key-threshold=3」と実行したため。このコマンドは重要なマスターキーを5つに分割して、3つのキーを使ってマスターキーを再構築するためである。当然ながら、これらのキーは流出しないように厳重管理しなければならない。
$ vault operator unseal XqeOza3SY6f4L6xfuk6f8JumrEF7cak9mUXCCPRXzs4B Key Value --- ----- Seal Type shamir Initialized true Sealed true Total Shares 5 Threshold 3 Unseal Progress 1/3 Unseal Nonce 393517e8-2eb0-1433-57b3-ae67ef2bedfd Version 1.5.4 HA Enabled false $ vault operator unseal djvVAAste0F5iSe43nmBs2ZX5r+wUqHe4UfUrcprWkyM Key Value --- ----- Seal Type shamir Initialized true Sealed true Total Shares 5 Threshold 3 Unseal Progress 2/3 Unseal Nonce 393517e8-2eb0-1433-57b3-ae67ef2bedfd Version 1.5.4 HA Enabled false $ vault operator unseal iSXHBdTNIKrbd3JIEI+n+q7j04Q4HPsQOHgk7apupttT Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 5 Threshold 3 Version 1.5.4 Cluster Name vault-cluster-0b495fa0 Cluster ID 81f0295d-4ae5-24f5-4092-5da6d26d7d14 HA Enabled false
以上で、Vaultを使用する準備が整った。他のアプリケーションが暗号化キーストレージのVaultにアクセスできるように、シークレットストレージのバックエンドとロールを作成できるようにするには、ルートトークンを使用してチャームを承認する必要がある。
最初に、この目的で初期ルートトークンを使用して、TTLが制限されたワンショットルートトークンを生成する。
$ export VAULT_TOKEN=ebded15e-c908-5d3a-1df0-1e7e7218c162 $ vault token create -ttl=10m Key Value --- ----- token s.lD9Kpuk4nSKrLQSpAkUaSAlD token_accessor AweRecDwyqqZkKHxAb8hmdEs token_duration 10m token_renewable true token_policies ["root"] identity_policies [] policies ["root"]
このワンショットルートトークンを使用して、Vaultへのチャームへのアクセスを設定する。アクションの実行が完了すると、Vaultユニットがアクティブになり、各 アプリケーションのシークレットストレージに対する保留中の要求が処理されます。
$ juju run-action --wait vault/leader authorize-charm token=s.lD9Kpuk4nSKrLQSpAkUaSAlD
次にこちらを確認。
最後に、SSL証明書を提供する。これは、Vaultに自己署名証明書を使用させるか、証明書チェーンを使用する方法が取れる。ここでは自己署名証明書を利用してみる。次のコマンドを使ってSSL証明書を作成する。
$ juju run-action --wait vault/leader generate-root-ca
Vault周りのコンフィグレーションが完了してしばらくすると、OpenStackの構築は完成する。
あとは、いつも通りネットワーク作成、イメージアップロード、セキュリティグループ構成などを行っていく。
最後に
セキュリティを考慮してVaultを使うようにしているのは特に問題はないものの、構築から完成までに手動の対応が必要になってしまっているのはなんと言いますか、自動化の魅力が半減しちゃっているなあという印象を受けました。本来のJujuってそこがメリットだったんですけどね。
参考情報源
構築にあたっては次のページの情報を参考にした。