新人が DevStack 上で Tacker を動かそうとする話

# 目次

[1. はじめに](#はじめに)
[2. 環境](#環境)
[3. インストール手順](#インストール手順)
[4. 発生したエラー](#発生したエラー)
[5. まとめ](#まとめ)

# 参考 URL

- [Install via Devstack](https://docs.openstack.org/tacker/latest/install/devstack.html)
- [DevStack](https://docs.openstack.org/devstack/latest/)
- [OpenStack Configuration](https://docs.openstack.org/devstack/latest/configuration.html#local-conf)
- [Welcome to kuryr-kubernetes’s documentation!](https://docs.openstack.org/kuryr-kubernetes/latest/)

# はじめに

初めまして。新入社員として約 3 か月目の新人です。

この記事では NFV という言葉すら知らなかった新人が [Install via Devstack]( https://docs.openstack.org/tacker/latest/install/devstack.html) を参考にして DevStack 環境をインストールし、VIM として OpenStack と Kubernetes を登録するまでの手順と発生したエラーを複数の章に分けて記載していきます。

- 第 1 章: この記事です。

[Install via Devstack]( https://docs.openstack.org/tacker/latest/install/devstack.html) を実際に試します。

- 第 2 章: 続く。。。

今回のインストールで自分が調べた用語は以下にまとめました。

## NFV (Network Function Virtualization)

ネットワーク機能を汎用サーバの仮想化基盤上でソフトウェアとして実装する方式のことです。
ETSI (欧州電気通信標準化機構) が提唱している NFV のアーキテクチャである ETSI-NFV アーキテクチャでは VNF, NFVI, MANO という 3 領域に分割されています。

### VNF (Virtual Network Function) 

仮想マシンとして動作するネットワーク機器です。
ここが既存のネットワーク機器と置き換わるイメージです。

### NFVI (NFV Infrastructure)

VNF を実行するための物理リソースと仮想化機能です。
サーバやストレージなどのハードウェアリソースと、仮想化のためのハイパーバイザが含まれます。

### NFV MANO (Management and Orchestration)

ハードウェアリソース、ソフトウェアリソース、VNFの管理機能とオーケストレーション機能を提供します。
下記の 3 つの機能から成り立っています。

- NFVO (NFV Orchestrator)
自動化の中心的な役割を担い、複数の VNF から構成されるネットワークサービスのライフサイクルを管理し、システム全体を統合的に運用します。

- VNFM (VNF Manager)
VNF が必要なリソースや VNF のライフサイクルを管理します。

- VIM (Virtualized Infrastructure Manager)
NFVI を制御します。
OpenStack や Kubernetes といったものが該当し、必要な VM やリソースの割り当てを行います。

## VNFD (VNF Descriptor)

VNF カタログに相当します。
TOSCA をベースにした YAML 形式で記載されているテンプレートです。

- TOSCA (Topology and Orchestration Specification for Cloud Applications)
クラウドアプリケーション向けトポロジ・オーケストレーションに関する仕様です。

## Tacker

NFVO (NFV Orchestrator), VNFM (VNF Manager) を担います。

カタログ化されたネットワークサービス (NSD) やカタログ化された VNF (VNFD) を基に、インフラドライバを経由し、VNF やそれに関連するネットワークが VIM に展開されます。

tacker-conductor と tacker-server のプロセスと MySQL から構成されています。
MySQL はデータベースであり、登録されている VIM の情報などが記録されています。
DevStack 環境インストール後は実際に MySQL の中身を確認もできます。

### tacker-conductor

conductor が案内人やガイド、(音楽用語で) 指揮者、導体 (= 伝えるもの) といった意味なので、Tacker の伝えるという処理を担当する部分ということです。
tacker-server から受け取った処理を実行し、VIM に対する API クライアントを担当します。

### tacker-server

NFVO や VNF からのリクエストを受け付けます。
受け取ったリクエスト次第で処理を tacker-conductor に渡したり MySQL に渡したりします。

# 環境

ESXi 上に下記のような構成の仮想マシンを準備しました。
使用 OS は Ubuntu 20.04 LTS です。

|         | 自環境  | 推奨環境   |
|---------|--------|------------|
| CPU     | 4 core | 4core 以上 |
| RAM     | 16GB   | 16GB 以上  |
| Storage | 160GB  | 80GB 以上  |

仮想マシンの準備後は下記のコマンドで最新の状態にし、再起動しておきます。

```
sudo apt-get update
sudo apt-get upgrade
```

ESXi など、スナップショットの機能が利用できる場合はこの時点を初期状態として一度記録しておくことをお勧めします。

# インストール手順

この手順は本環境でインストール完了までうまくいったものです。
手順完成までに発生したエラーは [4. 発生したエラー](#発生したエラー) にまとめます。

## Tacker Install

Tacker をインストールする最初のステップは、Devstack のクローンを作成し、local.conf を準備することです。

- Devstack
OpenStack を簡単にデプロイするためのツールです。

- local.conf
このファイルには、インストールに必要なさまざまな構成オプションが含まれています。

### DevStack インストールユーザーの作成

DevStack をインストールするためのユーザーを作成します。

```
sudo useradd -s /bin/bash -d /opt/stack -m stack
sudo chmod +x /opt/stack
echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack
sudo -u stack -i
```

### DevStack のダウンロード

必要に応じて特定のブランチを使用して、Git 経由で Devstack を取得します。
今回は 2022/4/30 にリリースされた Yoga 版を利用します。

```
git clone https://opendev.org/openstack/devstack.git
cd devstack
git checkout stable/yoga
```

### local.conf ファイルの準備

local.conf ファイルで Tacker 関連の Devstack プラグインを有効にします。
今回は Openstack and Kubernetes as VIM 用のものを使用します。

取得後、HOST_IP の値を自分の環境の IP へ変更します。
localhost から外に接続可能な IP に変更することによって Horizon で外からアクセスできるようにできます。

本環境で最終的に利用した local.conf は下記のとおりです。
enable_plugin で有効化したプラグインはすべて stable/yoga のものを利用しました。
master 版では後述するエラーが発生してしまいました。

```
[[local|localrc]]
############################################################
# Customize the following HOST_IP based on your installation
############################################################
HOST_IP=10.100.2.220

ADMIN_PASSWORD=devstack
MYSQL_PASSWORD=devstack
RABBIT_PASSWORD=devstack
SERVICE_PASSWORD=$ADMIN_PASSWORD
SERVICE_TOKEN=devstack

############################################################
# Customize the following section based on your installation
############################################################

# Pip
PIP_USE_MIRRORS=False
USE_GET_PIP=1

#OFFLINE=False
#RECLONE=True

# Logging
LOGFILE=$DEST/logs/stack.sh.log
VERBOSE=True
ENABLE_DEBUG_LOG_LEVEL=True
ENABLE_VERBOSE_LOG_LEVEL=True

# Neutron ML2 with OpenVSwitch
Q_PLUGIN=ml2
Q_AGENT=ovn
PHYSICAL_NETWORK=mgmtphysnet0

# Disable security groups
LIBVIRT_FIREWALL_DRIVER=nova.virt.firewall.NoopFirewallDriver

# Enable neutron, heat, networking-sfc, barbican and mistral
enable_plugin neutron https://opendev.org/openstack/neutron stable/yoga
enable_plugin heat https://opendev.org/openstack/heat stable/yoga
enable_plugin networking-sfc https://opendev.org/openstack/networking-sfc stable/yoga
enable_plugin barbican https://opendev.org/openstack/barbican stable/yoga
enable_plugin mistral https://opendev.org/openstack/mistral stable/yoga

# Ceilometer
#CEILOMETER_PIPELINE_INTERVAL=300
enable_plugin ceilometer https://opendev.org/openstack/ceilometer stable/yoga
enable_plugin aodh https://opendev.org/openstack/aodh stable/yoga

# Blazar
enable_plugin blazar https://github.com/openstack/blazar.git stable/yoga

# Tacker
enable_plugin tacker https://opendev.org/openstack/tacker stable/yoga

enable_service n-novnc
enable_service n-cauth

disable_service tempest

# Enable kuryr-kubernetes, docker, octavia
KUBERNETES_VIM=True
enable_plugin kuryr-kubernetes https://opendev.org/openstack/kuryr-kubernetes stable/yoga
enable_plugin octavia https://opendev.org/openstack/octavia stable/yoga
enable_plugin devstack-plugin-container https://opendev.org/openstack/devstack-plugin-container stable/yoga
#KURYR_K8S_CLUSTER_IP_RANGE="10.0.0.0/24"

enable_service kubernetes-master
enable_service kuryr-kubernetes
enable_service kuryr-daemon

[[post-config|/etc/neutron/dhcp_agent.ini]]
[DEFAULT]
enable_isolated_metadata = True

[[post-config|$OCTAVIA_CONF]]
[controller_worker]
amp_active_retries=9999
[[post-config|/etc/cinder/cinder.conf]]
[lvmdriver-1]
image_volume_cache_enabled = False
```

#### local.conf について

local.conf ファイルは [Tacker リポジトリ](https://opendev.org/openstack/tacker/src/branch/master) からコピーでき、構成タイプごとに例が存在します。

基本的な構成は 2 種類あります。

##### 1. All-in-one mode

Tacker を含む完全な Devstack 環境がインストールされます。
このモードには下記の 2 つの例があります

1. OpenStack as VIM
2. Openstack and Kubernetes as VIM

このモードの違いは、Openstack and Kubernetes as VIM では octavia と kuryr-kubernetes をデプロイすることです。

- octavia

OpenStack Load-balancing サービスです。
コントローラーノード上で実行されています。

- kuryr-kubernetes

OpenStack のネットワークと Kubernetes の統合に関するプロジェクトです。
OpenStack 上の VM と Kubernetes の Pod を同じ Neutron ネットワークで接続できるようすることを目的としています。

[Tacker リポジトリ](https://opendev.org/openstack/tacker/src/branch/master) からコピーできるサンプルファイルから下記のような差を確認できます。

```
$ diff local.conf.example local.conf.kubernetes
37c37,38
< # Enable heat, networking-sfc, barbican and mistral
---
> # Enable neutron, heat, networking-sfc, barbican and mistral
> enable_plugin neutron https://opendev.org/openstack/neutron master
45d45
< CEILOMETER_EVENT_ALARM=True
62a63,73
> # Enable kuryr-kubernetes, docker, octavia
> KUBERNETES_VIM=True
> enable_plugin kuryr-kubernetes https://opendev.org/openstack/kuryr-kubernetes master
> enable_plugin octavia https://opendev.org/openstack/octavia master
> enable_plugin devstack-plugin-container https://opendev.org/openstack/devstack-plugin-container master
> #KURYR_K8S_CLUSTER_IP_RANGE="10.0.0.0/24"
>
> enable_service kubernetes-master
> enable_service kuryr-kubernetes
> enable_service kuryr-daemon
>
65a77,80
>
> [[post-config|$OCTAVIA_CONF]]
> [controller_worker]
> amp_active_retries=9999
```

##### 2. Standalone mode

いくつかの必須の OpenStack サービスを備えた Tacker 環境のみがインストールされます。 
Nova、Neutron、またはその他の重要なコンポーネントは、このモードには含まれません。

### Devstack インストール

インストールスクリプトを実行します。
このスクリプトは環境にもよりますが、60 ~ 120 分程度はかかります。
その間、接続切れ (ssh 接続時の無通信切断) などを発生させないように注意してください。

```
./stack.sh
```

# 発生したエラー

DevStack インストール完了までに発生したエラーについてまとめました。

## Neutron Error

stack.sh スクリプト実行時に発生したエラーです。

```
[Call Trace]
./stack.sh:1291:start_neutron_service_and_check
/home/yoshi/devstack/lib/neutron-legacy:562:test_with_retry
/home/yoshi/devstack/functions-common:2382:die
[ERROR] /home/yoshi/devstack/functions-common:2382 Neutron did not start
Error on exit
```

### 試したこと

#### 漏れていた設定の追加

- /etc/hosts に外向け IP のローカル名前解決設定追加
- local.conf の HOST_IP を外向けの IP に変更
- インストールスクリプトを実行するユーザーがパスワードなしで sudo できるように設定
- 再度、stack.sh スクリプト実行

結果、エラーに変化はありませんでした。

#### stack ユーザの利用

- DevStack 環境を初めからインストールし直し
- stack ユーザ作成して実施する (参考: [DevStack](https://docs.openstack.org/devstack/latest/))
- 再度、stack.sh スクリプト実行

結果、下記のようなエラーが発生しました。

```
+inc/python:pip_install:190                sudo -H LC_ALL=en_US.UTF-8 SETUPTOOLS_USE_DISTUTILS=stdlib http_proxy= https_proxy= no_proxy= PIP_FIND_LINKS= python3.8 -m pip install -c /opt/stack/requirements/upper-constraints.txt -e /opt/stack/cinder
/usr/lib/python3/dist-packages/secretstorage/dhcrypto.py:15: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
  from cryptography.utils import int_from_bytes
/usr/lib/python3/dist-packages/secretstorage/util.py:19: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
  from cryptography.utils import int_from_bytes
Obtaining file:///opt/stack/cinder
ERROR: Exception:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/_internal/req/req_install.py", line 443, in check_if_exists
    self.satisfied_by = pkg_resources.get_distribution(str(no_marker))
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 481, in get_distribution
    dist = get_provider(dist)
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 357, in get_provider
    return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 900, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 791, in resolve
    raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (jmespath 1.0.1 (/usr/local/lib/python3.8/dist-packages), Requirement.parse('jmespath<1.0.0,>=0.7.1'), {'botocore', 'boto3'})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/base_command.py", line 186, in _main
    status = self.run(options, args)
  File "/usr/lib/python3/dist-packages/pip/_internal/commands/install.py", line 357, in run
    resolver.resolve(requirement_set)
  File "/usr/lib/python3/dist-packages/pip/_internal/legacy_resolve.py", line 177, in resolve
    discovered_reqs.extend(self._resolve_one(requirement_set, req))
  File "/usr/lib/python3/dist-packages/pip/_internal/legacy_resolve.py", line 333, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/usr/lib/python3/dist-packages/pip/_internal/legacy_resolve.py", line 265, in _get_abstract_dist_for
    return self.preparer.prepare_editable_requirement(req)
  File "/usr/lib/python3/dist-packages/pip/_internal/operations/prepare.py", line 560, in prepare_editable_requirement
    req.check_if_exists(self.use_user_site)
  File "/usr/lib/python3/dist-packages/pip/_internal/req/req_install.py", line 447, in check_if_exists
    existing_dist = pkg_resources.get_distribution(
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 481, in get_distribution
    dist = get_provider(dist)
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 357, in get_provider
    return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 900, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 791, in resolve
    raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (jmespath 1.0.1 (/usr/local/lib/python3.8/dist-packages), Requirement.parse('jmespath<1.0.0,>=0.7.1'), {'botocore', 'boto3'})
+inc/python:pip_install:1                  exit_trap
+./stack.sh:exit_trap:516                  local r=2
++./stack.sh:exit_trap:517                  jobs -p
+./stack.sh:exit_trap:517                  jobs=
+./stack.sh:exit_trap:520                  [[ -n '' ]]
+./stack.sh:exit_trap:526                  '[' -f '' ']'
+./stack.sh:exit_trap:531                  kill_spinner
+./stack.sh:kill_spinner:426               '[' '!' -z '' ']'
+./stack.sh:exit_trap:533                  [[ 2 -ne 0 ]]
+./stack.sh:exit_trap:534                  echo 'Error on exit'
Error on exit
+./stack.sh:exit_trap:536                  type -p generate-subunit
+./stack.sh:exit_trap:537                  generate-subunit 1657008105 608 fail
+./stack.sh:exit_trap:539                  [[ -z /opt/stack/logs ]]
+./stack.sh:exit_trap:542                  /usr/bin/python3.8 /opt/stack/devstack/tools/worlddump.py -d /opt/stack/logs
ovs-vsctl: unix:/var/run/openvswitch/db.sock: database connection failed (No such file or directory)
ovs-vsctl: unix:/var/run/openvswitch/db.sock: database connection failed (No such file or directory)
+./stack.sh:exit_trap:551                  exit 2
```

#### ovn サービス等起動

```
ovs-vsctl: unix:/var/run/openvswitch/db.sock: database connection failed (No such file or directory)
ovs-vsctl: unix:/var/run/openvswitch/db.sock: database connection failed (No such file or directory)
```

上記のエラーから下記を実行します。

- ovn サービス等起動
- 再度、stack.sh スクリプト実行

```
sudo systemctl start ovn-northd.service
sudo systemctl start ovn-controller.service
sudo systemctl start ovs-vswitchd.service
sudo systemctl start ovsdb-server.service
```

結果、`database connection failed` のエラーは消えましたが、他のエラーはそのままでした。

#### apt-get update

journal をを確認すると、下記のような表記がありました。

```
ERROR: neutron 20.1.0.dev412 has requirement neutron-lib>=2.21.0, but you'll have neutron-lib 2.20.0 which is incompatible.
ERROR: neutron 20.1.0.dev412 has requirement oslo.policy>=3.12.0, but you'll have oslo-policy 3.11.0 which is incompatible.
ERROR: neutron 20.1.0.dev412 has requirement ovsdbapp>=1.16.0, but you'll have ovsdbapp 1.15.2 which is incompatible.
Installing collected packages: neutron
```

最初に apt update していないために、`neutron-lib` (2.20.0) のバージョンが古いのではということで、下記を実行します。

- apt-get update を実行
- 再度、stack.sh スクリプト実行

結果、エラーに変化はありませんでした。
自動的に neutron-lib のバージョンも上がりませんでした。

#### nuetron を stable/yoga に変更

journalctl で確認すると下記のように import エラーが出ていました。

```
$ journalctl -xe -u devstack@q-svc.service --no-pager

...

ERROR neutron   File "/opt/stack/neutron/neutron/plugins/ml2/plugin.py", line 45, in <module>
ERROR neutron     from neutron_lib.api.definitions import port_mac_address_override
ERROR neutron ImportError: cannot import name 'port_mac_address_override' from 'neutron_lib.api.definitions' (/usr/local/lib/python3.8/dist-packages/neutron_lib/api/definitions/__init__.py)
```

この port_mac_address_override が最近実装されたものであり、import できないために発生したエラーではということで、下記を実行しました。

- neutron のファイル (/opt/stack/neutron) を stable/yoga に checkout を実施
- 再度、stack.sh スクリプト実行

結果、下記の 2 つのエラー発生しました。

```
AttributeError: module 'neutron.common.config' has no attribute 'register_common_config_options'

ovs-vsctl: unix:/var/run/openvswitch/db.sock: database connection failed (No such file or directory)
```

#### stack.sh 実行前の環境に戻して実行

- 一度きれいな環境にし、今までの対策をすべて実施
- neutron が stable/yoga を利用するように指定するために下記のように local.conf 変更
- 再度、stack.sh スクリプト実行

```
$ vim local.conf 

・・・

# Enable neutron, heat, networking-sfc, barbican and mistral
enable_plugin neutron https://opendev.org/openstack/neutron master
--
enable_plugin neutron https://opendev.org/openstack/neutron stable/yoga　←に変更
```

結果、下記のようなエラーが発生しました。

```
/usr/lib/python3/dist-packages/secretstorage/util.py:19: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
  from cryptography.utils import int_from_bytes
Traceback (most recent call last):
  File "/usr/local/bin/neutron-db-manage", line 10, in <module>
    sys.exit(main())
  File "/opt/stack/neutron/neutron/db/migration/cli.py", line 661, in main
    return_val |= bool(CONF.command.func(config, CONF.command.name))
  File "/opt/stack/neutron/neutron/db/migration/cli.py", line 183, in do_upgrade
    run_sanity_checks(config, revision)
  File "/opt/stack/neutron/neutron/db/migration/cli.py", line 645, in run_sanity_checks
    script_dir.run_env()
  File "/usr/local/lib/python3.8/dist-packages/alembic/script/base.py", line 563, in run_env
    util.load_python_file(self.dir, "env.py")
  File "/usr/local/lib/python3.8/dist-packages/alembic/util/pyfiles.py", line 92, in load_python_file
    module = load_module_py(module_id, path)
  File "/usr/local/lib/python3.8/dist-packages/alembic/util/pyfiles.py", line 108, in load_module_py
    spec.loader.exec_module(module)  # type: ignore
  File "<frozen importlib._bootstrap_external>", line 848, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/opt/stack/networking-sfc/networking_sfc/db/migration/alembic_migrations/env.py", line 25, in <module>
    from networking_sfc.db.migration.models import head  # noqa
  File "/opt/stack/networking-sfc/networking_sfc/db/migration/models/head.py", line 17, in <module>
    from networking_sfc.db import flowclassifier_db  # noqa
  File "/opt/stack/networking-sfc/networking_sfc/db/flowclassifier_db.py", line 34, in <module>
    from networking_sfc.extensions import flowclassifier as fc_ext
  File "/opt/stack/networking-sfc/networking_sfc/extensions/flowclassifier.py", line 34, in <module>
    common_config.register_common_config_options()
AttributeError: module 'neutron.common.config' has no attribute 'register_common_config_options'
```

先輩より次のような指摘をいただきました。

networking-sfc が neutron のライブラリを呼び出すところで、attribute エラーになっているみたいですね。
たぶん networking-sfc が master で、neutron が yoga/stable なので不整合が起きている気がします。
local.conf の他部分も master ではなくて stable/yoga を取ってくるようにした方がいいかもしれないですね。

#### local.conf で使用ブランチをすべて stable/yoga に変更

- 前回の stack.sh を実行する前の状態に戻す
- 下記の local.conf に変更
- 再度 stack.sh 実行

```
$ cat local.conf
[[local|localrc]]
############################################################
# Customize the following HOST_IP based on your installation
############################################################
HOST_IP=10.100.2.220

ADMIN_PASSWORD=devstack
MYSQL_PASSWORD=devstack
RABBIT_PASSWORD=devstack
SERVICE_PASSWORD=$ADMIN_PASSWORD
SERVICE_TOKEN=devstack

############################################################
# Customize the following section based on your installation
############################################################

# Pip
PIP_USE_MIRRORS=False
USE_GET_PIP=1

#OFFLINE=False
#RECLONE=True

# Logging
LOGFILE=$DEST/logs/stack.sh.log
VERBOSE=True
ENABLE_DEBUG_LOG_LEVEL=True
ENABLE_VERBOSE_LOG_LEVEL=True

# Neutron ML2 with OpenVSwitch
Q_PLUGIN=ml2
Q_AGENT=ovn
PHYSICAL_NETWORK=mgmtphysnet0

# Disable security groups
LIBVIRT_FIREWALL_DRIVER=nova.virt.firewall.NoopFirewallDriver

# Enable neutron, heat, networking-sfc, barbican and mistral
enable_plugin neutron https://opendev.org/openstack/neutron stable/yoga
enable_plugin heat https://opendev.org/openstack/heat stable/yoga
enable_plugin networking-sfc https://opendev.org/openstack/networking-sfc stable/yoga
enable_plugin barbican https://opendev.org/openstack/barbican stable/yoga
enable_plugin mistral https://opendev.org/openstack/mistral stable/yoga

# Ceilometer
#CEILOMETER_PIPELINE_INTERVAL=300
enable_plugin ceilometer https://opendev.org/openstack/ceilometer stable/yoga
enable_plugin aodh https://opendev.org/openstack/aodh stable/yoga

# Blazar
enable_plugin blazar https://github.com/openstack/blazar.git stable/yoga

# Tacker
enable_plugin tacker https://opendev.org/openstack/tacker stable/yoga

enable_service n-novnc
enable_service n-cauth

disable_service tempest

# Enable kuryr-kubernetes, docker, octavia
KUBERNETES_VIM=True
enable_plugin kuryr-kubernetes https://opendev.org/openstack/kuryr-kubernetes stable/yoga
enable_plugin octavia https://opendev.org/openstack/octavia stable/yoga
enable_plugin devstack-plugin-container https://opendev.org/openstack/devstack-plugin-container stable/yoga
#KURYR_K8S_CLUSTER_IP_RANGE="10.0.0.0/24"

enable_service kubernetes-master
enable_service kuryr-kubernetes
enable_service kuryr-daemon

[[post-config|/etc/neutron/dhcp_agent.ini]]
[DEFAULT]
enable_isolated_metadata = True

[[post-config|$OCTAVIA_CONF]]
[controller_worker]
amp_active_retries=9999
[[post-config|/etc/cinder/cinder.conf]]
[lvmdriver-1]
image_volume_cache_enabled = False
```

結果、インストール完了しました。
http://10.100.2.220/dashboard で Horizon のダッシュボードも見ることができました。

```
$ ./stack.sh

・・・

=========================
DevStack Component Timing
(times are in seconds)
=========================
wait_for_service      22
pip_install          569
apt-get              908
run_process           71
dbsync                32
git_timed            1112
apt-get-update       10
test_with_retry        8
async_wait           356
osc 1011
-------------------------
Unaccounted time   2453
=========================
Total runtime        6552

=================
Async summary
=================
Time spent in the background minus waits: 690 sec
Elapsed time: 6552 sec 
Time if we did everything serially: 7242 sec
Speedup:  1.10531


This is your host IP address: 10.100.2.220
This is your host IPv6 address: ::1
Horizon is now available at http://10.100.2.220/dashboard  
Keystone is serving at http://10.100.2.220/identity/  
The default users are: admin and demo
The password: devstack

Services are running under systemd unit files.
For more information see:
https://docs.openstack.org/devstack/latest/systemd.html

DevStack Version: yoga
Change: 6f545e2567166ed9790601ccb589307df688d40d Allow to skip stop of ovn services 2022-05-31 07:31:08 +0000                     
OS Version: Ubuntu 20.04 focal
```

## ceilometer の clone で git call failed

```
Cloning into '/opt/stack/ceilometer'...
error: RPC failed; curl 56 GnuTLS recv error (-9): Error decoding the received TLS packet.
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
+ESC[38;5;242mfunctions-common:git_timed:725           ESC[m^O [[ 128 -ne 124 ]]
+ESC[38;5;242mfunctions-common:git_timed:726           ESC[m^O die 726 'git call failed: [git clone' https://opendev.org/openstack/ceilometer /opt/stack/ceilometer --branch 'master]'
+ESC[38;5;242mfunctions-common:die:264                 ESC[m^O local exitcode=0
[Call Trace]
./stack.sh:590:fetch_plugins
/opt/stack/devstack/functions-common:1793:git_clone_by_name
/opt/stack/devstack/functions-common:702:git_clone
/opt/stack/devstack/functions-common:650:git_timed
/opt/stack/devstack/functions-common:726:die
[ERROR] /opt/stack/devstack/functions-common:726 git call failed: [git clone https://opendev.org/openstack/ceilometer /opt/stack/ceilometer --branch master]
Error on exit
```

git clone が一時的に失敗しただけのため、もう一度流すことによって解決しました。
  
## Kubernetes が起動しない

このエラーは [Install via Devstack]( https://docs.openstack.org/tacker/latest/install/devstack.html) での手順とは直接関係はしておらず、自身が実験として行ったことにて発生したものです。
  
下記のように local.conf を設定したところ Kubernetes が一切動きませんでした。
stack.sh スクリプト実行後、kubelet コマンド等もなかったです。

この local.conf では kuryr-kubernetes をインストールせず、Calico を CNI としてインストールし、OpenStack 上の VM と Kubernetes の Pod を同じ Neutron ネットワークで接続させないようにできるかを試しています。

```
$ cat local.conf
[[local|localrc]]
############################################################
# Customize the following HOST_IP based on your installation
############################################################
HOST_IP=10.100.2.211

・・・

# Enable kuryr-kubernetes, docker, octavia
KUBERNETES_VIM=True
#enable_plugin kuryr-kubernetes https://opendev.org/openstack/kuryr-kubernetes stable/yoga
enable_plugin calico https://git.openstack.org/openstack/networking-calico
enable_plugin octavia https://opendev.org/openstack/octavia stable/yoga
enable_plugin devstack-plugin-container https://opendev.org/openstack/devstack-plugin-container stable/yoga
#KURYR_K8S_CLUSTER_IP_RANGE="10.0.0.0/24"

enable_service kubernetes-master
#enable_service kuryr-kubernetes
#enable_service kuryr-daemon

・・・
```

この手順を試すまで、Kubernetes 関係は kubernetes-master で入り、kuryr-kubernetes は kubernetes-master で起動した Kubernetest のネットワークを OpenStack とつなげるようにしているのかと思っていました。

DevStack は基本的に DevStack 用のルートディレクトリ以下に DevStack 関連のものが入るため、DevStack のルートディレクトリを確認すると　neutron や kuryr-kubernetes などがあることが確認できます。
しかし、kubernetes-master などは存在せず、Kubernetes 関連のものは kuryr-kubernetes しかないことがわかります。

grep コマンドで kuryr-kubernetes 内部を下記のように調べると kubeadm や kubernetes-master という文字がヒットするため、kuryr-kubernetes が存在しない場合、Kubernetes は動作しなさそうです。

```
grep -e "kubernetes-master" -rn ./kuryr-kubernetes/
grep -e "kubeadm" -rn ./kuryr-kubernetes/
```

結論として、kuryr-kubernetes が有効化になっていなければ Devstack 上で Kubernetes が動作しないことがわかりました。

# まとめ

たくさんエラーが発生しましたが、無事に Tacker が動作している DevStack 環境が動作するようになりました。
次回は TOSCA を使用して VM で NFV をデプロイしていきます。