仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

kolla-ansibleを使ったAll-in-one OpenStackの構築

概要

OpenStack kollaとは、OpenStackの各コンポーネントをDockerコンテナとしてイメージ化・デプロイするプロジェクトです。 そして、今回使うkolla-ansibleは、kollaイメージを使ってDocker上でOpenStackを動かすためのインストーラーです。処理は名前の通りAnsibleを内部的に使ってデプロイを行います。

手順は基本はここに書かれているとおりです。ただ実際動かしてみると、色々注意しなければいけない点があったので今回記事にまとめることにしました。

サーバーに必要な設定

OS

OSはUbuntu Server 20.04.2を使いました。事前にアップデートを適用して、最新の状態にしました。

NICの設定

NICは管理用とExternal用の2つを用意しました。

管理用インターフェイス

管理用インターフェイスはホストへのSSHアクセス、デプロイ時のパッケージダウンロードのためのインターネットアクセスが必要です。

External用インターフェイス

OpenStackのインスタンスのルーティングのために必要なインターフェイスです。管理用インターフェイスと別のVLANが推奨されます。

初期セットアップの流れ

  • 依存パッケージをまずインストールする
sudo apt update
sudo apt install python3-dev libffi-dev gcc libssl-dev
  • Python 3で仮想環境をセットアップする

今回はUbuntu Server 20.04.2を利用しました。Ubuntu 20.04はPython3.8がデフォルトでインストールされていますが、仮想環境を作るためのモジュールはデフォルトではインストールされていません。まずこれをインストールする必要があります。

sudo apt install python3-venv

Python3の仮想環境については詳しくは公式サイトのvenv --- 仮想環境の作成をご覧ください。以降はPython3の仮想環境のことをvenvと記述します。

最近のLinuxはデフォルトでPython 3が使われることが多いので、うかつにpipコマンドなどでパッケージをインストールしてしまうとシステムにインストール済みのモジュールが置き換わって問題が起きるなんてことになりかねません。問題を回避するためにはvenvなどの仮想環境を利用する方法が極めて有効です。

mkdir -p ~/setup-kolla/virtual/environment
cd ~/kolla
python3.8 -m venv ./virtual/environment
source ./virtual/environment/bin/activate
  • Ansibleをインストールする

今回はvenvを使っているので、pipでAnsibleをインストールします(最初はaptでいれたのですが、venv内でシステムにインストールしたAnsibleが認識されなかったため。"そんなansible moduleなんてないよ"と言われました)。

pip install 'ansible<3.0'
  • kolla-ansibleをインストールする
pip install kolla-ansible

通常、pipでモジュールをインストールすると最新のパッケージがインストールされます。 最初はUbuntu 20.04でOpenStack Ussuriリリースを動かそうとしました。

kolla-ansibleでデプロイ中に次のようなエラーが表示されて失敗しました。

nova-cell : Waiting for nova-compute services to register themselves
FAILED - RETRYING: Waiting for nova-compute services to register themselves

エラーログなどから次のIssueを見つけました。要約すると、「インストールしているkolla-ansibleのバージョンと想定しているデプロイバージョンの不一致が原因」とのことでした。

どのバージョンのkolla-ansibleがどのバージョンのOpenStackのデプロイをサポートしているのかの情報を見つけることはできませんでしたが、次のプロジェクトページのSeries and milestonesにヒントがあるように見えました。

このセットアップを試したときにインストールされたkolla-ansibleは12.0.0でした。従って、Wallabyリリースをインストールするのが適切であると判断しました。

(environment) ~$ pip list |grep kolla-ansible
kolla-ansible      12.0.0
  • Quickstartにならって、/etc/kollaディレクトリを作成します。
sudo mkdir -p /etc/kolla
sudo chown $USER:$USER /etc/kolla
  • globals.ymlpasswords.yml/etc/kollaディレクトリにコピーします。

前の手順でvenv環境は「~/setup-kolla/virtual/environment」に作りましたので、このディレクトリー配下にあるファイルを/etc/kollaディレクトリーにコピーします。

cp -r ~/setup-kolla/virtual/environment/share/kolla-ansible/etc_examples/kolla/* /etc/kolla
  • インベントリファイルをコピー

同上です。インベントリーファイルは一台のマシンにセットアップする用のall-in-oneと複数構成を想定したmultinodeです。今回はall-in-oneを使います。

cp -r ~/setup-kolla/virtual/environment/share/kolla-ansible/ansible/inventory/* .
  • ansible.cfgの設定を変更

Quickstartにならって、Ansibleの設定を修正します。デフォルトのforksは5に設定されているため、100に設定変更が必要です。

sudo vi /etc/ansible/ansible.cfg

[defaults]
...
host_key_checking=False
...
pipelining=True
...
forks=100
  • venv内でAnsibleが使えることを確認する

エラーが出ずにpongが返ってくれば成功です。

ansible -i all-in-one all -m ping
..
    "ping": "pong"
}
  • kolla passwordsを作成する

コマンドを実行して、コンポーネントのパスワードを作成します。

kolla-genpwd
  • kollaの設定(globals.yml)を準備

デプロイに必要な設定を書き込みます。注意すべきはkolla_internal_vip_addressの指定です。

kolla_internal_vip_addressnetwork_interfaceで指定したIF側のネットワークで未使用のIPアドレスを指定すると書かれています。しかし、All-in-oneインストールではenable_haproxyをnoに設定するように指示されており、そのように設定した場合はホストOSのnetwork_interface側に設定されたIPアドレスをそのまま記述すれば良いようです(少なくともkolla-ansible 12.0.0では)。

また、kolla_install_typebinary, sourceの2つから選択できますが、sourceの方が良いそうです。

実際設定した例を以下に示します。

vi /etc/kolla/globals.yml

kolla_base_distro: "ubuntu"  #ホストOSのディストリビューション
kolla_install_type: "source" #パッケージの取得方法
openstack_release: "wallaby" #OpenStackのバージョン
kolla_internal_vip_address: "172.17.28.64" #管理IFのアドレス
network_interface: "eno49" #管理ネットワークのIF
neutron_external_interface: "eno50" #OpenStack Neutron ネットワークのIF
enable_haproxy: "no"   #All-in-oneではこれをオフにする

ここまで設定したら次はデプロイです。

デプロイの流れ

  • kolla deployに依存するソフトウェアなどのセットアップをします。

必要なコンポーネント(例えばDockerも含めて)が導入されます。事前にDcokerがインストールされていると問題が発生する場合があります。

kolla-ansible -i ./all-in-one bootstrap-servers
  • チェックしてエラーが出なければデプロイ

prechecks実行後、エラーが特に出なければdeployを実行します。

kolla-ansible -i ./all-in-one prechecks
kolla-ansible -i ./all-in-one deploy

万が一、デプロイが失敗したら次のように実行してデプロイをクリアします。Dockerイメージのクリアは必要に応じて行います。サーバースペックにより30分から1時間程度かかります。

kolla-ansible -i ./all-in-one destroy --yes-i-really-really-mean-it
(デプロイしたコンテナなどを消す)
sudo docker rmi $(sudo docker images -a -q)
(イメージをすべてクリーン)

OpenStackにブラウザーからアクセス

  • デプロイが成功したらOpenStack Dashboardにアクセスしてみます。「http://ホストのIPアドレス」のようにブラウザーでアクセスすると自動的にリダイレクトされます

  • OpenStackのadminユーザーのパスワードは以下で確認できます。

grep keystone_admin_password /etc/kolla/passwords.yml

OpenStackにCLIからアクセス

次のように実行すると、OpenStack CLIを使ってOpenStack環境にアクセスできます。 「/etc/kolla/admin-openrc.sh」はこの方法のセットアップでは無かったので、Dashboardにアクセスして、右上のメニューからRCファイルをダウンロードしたものを使いました。

pip install python-openstackclient
source admin-openrc.sh
openstack hypervisor list
+----+---------------------+-----------------+--------------+-------+
| ID | Hypervisor Hostname | Hypervisor Type | Host IP      | State |
+----+---------------------+-----------------+--------------+-------+
|  1 | bay15-gen9          | QEMU            | 172.17.28.64 | up    |
+----+---------------------+-----------------+--------------+-------+

OpenStackにNeutronネットワークを作成

管理側に次のようなパブリックネットワークとサブネットを作成します。

  • ネットワーク種別: flat
  • 物理ネットワーク: physnet1

プロジェクト側に以下を作成します。

  • プロジェクト用ネットワーク、サブネットを作成
  • ルーターを作成
  • ルーターとパブリックネットワークを接続
  • ルーターとプロジェクト用ネットワークを接続
  • セキュリティグループを編集(SSH,ICMP許可など)
  • キーペアの作成もしくは登録
  • イメージの登録
  • フレーバーの定義(cirros: v1CPU, 128MB, 1GB)
  • インスタンスを起動してみる

特にエラーが表示されることなくインスタンスが起動すればまず成功です。compute周りは正常に動いています。

f:id:virtualtech:20210729171440p:plain

起動したインスタンスにアクセスして、ping -c3 8.8.8.8ping -c3 google.comなどが問題なく通ればneutronも正常に動作しています。

OpenStackサービスにアクセスする

今回のセットアップでは、OpenStackはDockerコンテナーの中で各コンポーネントが実行されているため、Dockerの方法で各コンポーネントにアクセスしたり、ログを確認したりできます。OpenStackサービスにアクセスするには次のように実行します。

コンテナーにアクセス後は通常のLinuxシェルと同様操作できます。インストールされているパッケージは最低限のため、設定を開いて確認するときはcat等を使います。また、コンテナー内で設定変更するのは想定されていません。

sudo docker ps
CONTAINER ID   IMAGE                                                   COMMAND                  CREATED       STATUS                 PORTS     NAMES
079ee06a0d98   kolla/ubuntu-source-horizon:wallaby                     "dumb-init --single-…"   3 hours ago   Up 3 hours (healthy)             horizon
e6e8f1d925e6   kolla/ubuntu-source-heat-engine:wallaby                 "dumb-init --single-…"   3 hours ago   Up 3 hours (healthy)             heat_engine
...
ea26545d3fe0   kolla/ubuntu-source-neutron-server:wallaby              "dumb-init --single-…"   3 hours ago   Up 3 hours (healthy)             neutron_server
...
5e093bbf80e6   kolla/ubuntu-source-nova-compute:wallaby                "dumb-init --single-…"   3 hours ago   Up 3 hours (healthy)             nova_compute
...
594bd33a030b   kolla/ubuntu-source-nova-api:wallaby                    "dumb-init --single-…"   3 hours ago   Up 3 hours (healthy)             nova_api
...
478cfdd572ff   kolla/ubuntu-source-keystone:wallaby                    "dumb-init --single-…"   3 hours ago   Up 3 hours (healthy)             keystone
...
d0e3786a8ebb   kolla/ubuntu-source-rabbitmq:wallaby                    "dumb-init --single-…"   3 hours ago   Up 3 hours                       rabbitmq
4e688c805898   kolla/ubuntu-source-memcached:wallaby                   "dumb-init --single-…"   3 hours ago   Up 3 hours                       memcached
...

sudo docker exec -it nova_api bash
(nova_apiコンテナーにアクセス)

ストレージはどうしているか

OpenStackの各コンポーネントはDockerのコンテナーで動いているkolla-ansibleですが、ストレージはどうしているのでしょうか。Dockerコンテナーのなかでストレージが圧迫して問題が起きたら大変なので、調べてみることにしました。

Dockerボリューム機能を利用しているようです。

$ sudo docker volume ls
DRIVER    VOLUME NAME
local     fluentd_data
local     glance
local     keystone_fernet_tokens
local     kolla_logs
local     libvirtd
local     mariadb
local     neutron_metadata_socket
local     nova_compute
local     nova_libvirt_qemu
local     openvswitch_db
local     rabbitmq

glanceのDocker Volumeを見てみます。パスが/var配下になっていることがわかります。

$ sudo docker volume inspect glance
[
    {
        "CreatedAt": "2021-07-29T08:28:57Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/glance/_data",
        "Name": "glance",
        "Options": null,
        "Scope": "local"
    }
]

$ sudo tree /var/lib/docker/volumes/glance/_data
/var/lib/docker/volumes/glance/_data
├── images
│   ├── 3b607e93-900a-4ff5-93ae-283ee050e493
│   └── 5b5279b7-fb4e-4366-8fd3-28ba01cb569e
├── staging
└── tasks_work_dir

3 directories, 2 files

こんな感じできちんとホスト上のディレクトリーをマウントしており、永続データの取り扱いも問題なさそうです。

コンテナーホストの再起動で気をつけること

今回の構成ではDockerコンテナーでOpenStackを動かしています。Dockerのデフォルト設定では、ホストが再起動されてもコンテナーが自動で起動することはありません。従って、再起動した後コンテナーをdocker startコマンドで起動する必要があります。この回避策として、コンテナーに対して自動起動するようにに設定する方法があります。

docs.docker.com

ページに書かれているこの例が使えました。

$ sudo docker update --restart unless-stopped $(sudo docker ps -q)