Starling X 概要の整理と構築手順まとめ

# 目的

Starling Xの情報整理と構築手順の確認を行うことを目的としています。

# Starling X 概要

## Starling X プロジェクト
OpenInfra Foundationのプロジェクトの一つ。

一文での説明は下記の通り。
> ハイパフォーマンスで超低遅延なアプリケーションのためのエッジクラウドコンピューティングインフラ。

もう少し詳しい説明は以下の通り。
> StarlingXは、産業用IoT、通信、その他のユースケースで最も要求の厳しいアプリケーションで使用されるエッジ用の完全なクラウド・インフラストラクチャ・ソフトウェア・スタックです。新たにオープンソース化されたStarlingXのコードは、ミッションクリティカルなアプリケーションに導入されている成熟したプロダクション・ソフトウェアをベースにしており、今すぐ製品化できるスケーラブルなソリューションのエッジ実装の基盤となります。

2021/04時点のリリースはR4.0が最新版である。

参考URL：
https://openinfra.dev/projects/
https://www.starlingx.io/

## ユースケース

参考URL： 
https://www.starlingx.io/learn/

### 超低遅延5Gおよび産業用IoT（IIoT）

* 自動運転車（ドローン、車、トラック）
* 産業オートメーション（ロボット工学および仮想プログラマブルロジックコントローラー（vPLC）
* クラウド/仮想無線アクセスネットワーク（cRAN / vRAN）
* スマートシティ/建物（計測と監視）

### 高帯域幅、大容量アプリケーション

* モバイルHDビデオ
* コンテンツ配信
* ヘルスケア（画像および診断）
* キャッシングと監視

### マルチアクセスエッジコンピューティング（ME!

* 拡張現実と仮想現実（AR / VR）
* スタジアムや高密度の場所向けのエンタープライズ向けスモールセルサービス
* 統合顧客宅内機器（uCPE）アプリケーション
* 小売り

## アーキテクチャ

### ソフトウェアアーキテクチャ

![StarlingX_Diagram_DistributedEdgeCloudNative_v2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157364/17020bae-739c-662c-57f1-41c9093453fe.jpeg)

## 余談：類似プロジェクト

LF EDGE プロジェクト内でもEdge領域で類似部分を確認した。

IoT領域において EdgeX Foundaryが存在する。こちらはx86だけでなくARM向けの提供も行っており
Raspberry Pi 4B上で動作が可能となるように対応を行っています。

参考URL：
https://www.lfedge.org/projects/edgexfoundry/
https://docs.edgexfoundry.org/1.3/examples/Ch-ExamplesRP4/


vRAN領域においてAkraino Radio Edg
e Cloud(REC)が存在する。RECはO-RAN規格で定義されるRadio Access Network Intelligent Controller (RIC) 
のサポートも含めた提供を目的としている。

参考URL：
https://www.lfedge.org/projects/akraino/release-4-2/radio-edge-cloud/

このほかにもAkrainoプロジェクトではMEC検討等も進んでいる。

# 構築

## Starling X アーキテクチャ

今回はAll-in-one（AIO）Duplex構成を構築する。

![starlingx-deployment-options-duplex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157364/9bb380eb-c568-077a-1071-21b90ff49416.png)


AIOはコントローラ機能、ワーカー機能、ストレージ機能を提供する単一の物理ノードを指す。
AIOを冗長化した構成がAIO Duplex構成となる。

## VM アーキテクチャ

![VirtualBox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157364/5340074c-155d-1146-6de2-cd4460964f56.png)


Router：
iptablesを利用してNATと内部ネットワークの接続を行う。
また、ControllerのGUIに対しての操作もこちらから行う。

Controller-0：
Starling X Controller Nodeその1

Controller-1：
Starling X Controller Nodeその2


## 構築環境

OS: Windows 10 64bit
仮想化環境: Virtual Box 6.1.18

CPU: 16 vCPU以上
RAM: 50 GB以上
DISK： 700GB以上
※CPU以外は実際に使用するリソースが少ないため調整可能

## 構築手順

1. 事前準備
2. Router用VM構築
3. Controller-0構築
4. Controller-1構築
5. Kubernetes Dashboard構築

### 1. 事前準備

#### Ubuntu Desktop 20.04 の入手

Router用のイメージを入手する。

https://www.ubuntulinux.jp/products/JA-Localized/download

#### Starling X Boot Imageの入手

ミラーサイトよりbootimage.isoを入手する。

http://mirror.starlingx.cengn.ca/mirror/starlingx/release/4.0.1/centos/flock/outputs/iso/

### 2. Router用VM構築

参考URL：
https://docs.starlingx.io/deploy_install_guides/r4_release/virtual/config_virtualbox_netwk.html

#### Router用VMの作成

下記を設定する。

| 項目 | 設定値 |
| ------------------ | -------------- |
| タイプ | Linux|
| バージョン | Ubuntu(64-bit) |
| メモリーサイズ | 2048 MB|
| 仮想ハードディスク | 25 GB|

#### Router用VMの設定

設定対象のVMを右クリックし、設定画面を開き設定を行う。

1. 一般>高度を選択し、クリップボードの共有、ドラッグ&ドロップを双方向に設定する。
1. システム>プロセッサーを選択し、プロセッサー数を2に設定する。
1. ディスプレイ>スクリーンを選択し、ビデオメモリーを最大値に設置し、3Dアクセラレーションを有効化する。
2. ネットワーク>アダプター1を選択し、割り当てをNATに設定する。（NAT Networkの設定）
3. ネットワーク>アダプター2を選択し、下記を設定する。（OAM Networkの設定）
 * 「ネットワークアダプターを有効化」にチェックを入れる。
 * 割り当てをホストオンリーアダプタとする。
 * 名前から「VirtualBox Host-Only Ethernet Adapter」を選択する。
4. ストレージ>ストレージデバイスより空の光学ディスクへ、ダウンロードしたUbuntu DesktopのISOを選択して追加する。


#### Router用VM 起動後の設定

1. Router用VMを起動し、ガイダンスに従いUbuntuをインストールする。インストール完了後、光学ディスクを除去し再起動する。
2. デバイス> Guest Additions CDを挿入を選択し、VirtualBox Guest Additions Installationを実行する。完了後CDは除去する。
3. Ubuntuのソフトウェア更新を実施し、再起動する
4. sysctlの変更を実施する

```
$ sudo nano /etc/sysctl.conf

...
# 下記行のコメントアウトを削除する。
net.ipv4.ip_forward=1


$ sudo sysctl -p
net.ipv4.ip_forward = 1
```

5. OAM NetworkのGateway IPアドレスを設定する。

```
$ sudo su -
$ cat > /etc/netplan/99_config.yaml << EOF
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: true
    enp0s8:
      addresses:
        - 10.10.10.1/24
EOF

$ exit

$ sudo netplan apply

# enp0s8へIPが設定されていることを確認する。
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
 valid_lft forever preferred_lft forever
inet6 ::1/128 scope host 
 valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:3f:5e:04 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
 valid_lft 86398sec preferred_lft 86398sec
inet6 fe80::e0ba:c587:40e8:3104/64 scope link noprefixroute 
 valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:77:48:cf brd ff:ff:ff:ff:ff:ff
inet 10.10.10.1/24 brd 10.10.10.255 scope global enp0s8
 valid_lft forever preferred_lft forever
inet6 fe80::90f0:9c13:cf80:fb74/64 scope link noprefixroute 
 valid_lft forever preferred_lft forever
```

6. ホストオンリーネットワークからNATネットワークへのパケット転送設定を行う。

```
$ sudo apt-get install -y iptables-persistent

$ sudo iptables -t nat -A POSTROUTING --out-interface enp0s3 -j MASQUERADE
$ sudo iptables -A FORWARD --in-interface enp0s8 -j ACCEPT
$ sudo /etc/init.d/netfilter-persistent save

```

7. VirtualBoxへNAT Networkを追加する
VirtualBox本体のウインドウよりファイル>環境設定>ネットワークを選択し、新しいNATネットワークを追加する。
追加後、下記の通り設定を変更する。
 * ネットワークを有効化にチェックを入れる
 * ネットワーク名を設定する(NAT Network)
 * ネットワークCIDRへ10.10.10.0/24を入力する
 * DHCPのサポートのチェックを外す
 * IPv6サポートのチェックを入れる
 * IPv6デフォルトルートのアドバタイズのチェックを外す

以上で作業完了です。

### 3. Controller-0構築

参考URL：
https://docs.starlingx.io/deploy_install_guides/r4_release/virtual/install_virtualbox.html

#### Controller Node用VMの作成

下記を設定する。Controller-0,1で差分はないため、2台のVMを作成する。

| 項目 | 設定値|
| ------------------ | ------------------- |
| タイプ | Linux |
| バージョン | Other Linux(64-bit) |
| メモリーサイズ | 20480 MB|
| 仮想ハードディスク | 240 GB|

#### Controller Node用VMの設定

1. システム>マザーボードを選択し、起動順序の設定を下記の通りとする
 3. 光学
 1. ハードディスク
 2. ネットワーク
 4. フロッピー
2. システム>プロセッサーを選択し、プロセッサー数を7に設定する。
3. システム>ストレージを選択し、10Gと100Gのストレージを追加作成、登録する
4. ネットワーク>アダプター1を選択し、割り当てを設定する。（OAM Networkの設定）
 * 「ネットワークアダプターを有効化」にチェックを入れる。
 * 割り当てをホストオンリーアダプタとする。
 * 名前から「VirtualBox Host-Only Ethernet Adapter」を選択する。
 * アダプタータイプから「Intel PRO/1000 MT デスクトップ(82540EM)」を選択する。
 * プロミスキャスモードから 「すべて許可」を選択する。
5. ネットワーク>アダプター2を選択し、下記を設定する。（Management Networkの設定）
 * 「ネットワークアダプターを有効化」にチェックを入れる。
 * 割り当てを内部ネットワークとする。
 * 名前を「intnet-management」と入力する。
 * アダプタータイプから「Intel PRO/1000 MT デスクトップ(82540EM)」を選択する。
 * プロミスキャスモードから 「すべて許可」を選択する。

6. Windows上でPowershellを起動し、Controller Node用VMで起動に利用するネットワークインターフェースの優先度変更を行う

```
> cd "C:\Program Files\Oracle\VirtualBox"

> .\VBoxManage.exe list vms
"Router" {79b6d405-9ddc-41c1-8f74-b35e976c4991}
"Controller-0" {3dc5cdba-9be5-481e-ab76-598ed48165a3}
"Controller-1" {1598bd77-c846-4d3e-a68e-1868777100ff}

> .\VBoxManage modifyvm 3dc5cdba-9be5-481e-ab76-598ed48165a3 --nicbootprio2 1
> .\VBoxManage modifyvm 1598bd77-c846-4d3e-a68e-1868777100ff --nicbootprio2 1

```

> --nicbootprio<1-N> <priority>:
> PXE を使用して、ネットワーク経由でブートするために NIC を試行する順序を指定します。優先順位は、0から4の整数です。優先度1が最も高く、優先度4は低くなります。優先度0は、特に指定がない限りデフォルトで、最も低くなります。

#### Controller-0のインストール

1. Controller-0へStarling XのBoot Imageを挿入し起動する
2. 起動後、All-in-one Controller Configuration > Graphical Consoleを選択し、インストールが完了するまで待機する。インストール完了後Boot Imageを除去する。
※インストール完了まで5~10分程度、起動完了まで3~5分程度必要

3. 初回ログインを行う。初回ログインはパスワード変更を求められるため、任意のパスワードを設定する。設定完了後、自動でログアウトされるため再度ログインする。
※キーボードの認識は英字キーボードとなっているため注意が必要

```
# 初期パスワード
user: sysadmin
password: sysadmin
```

4. NAT Network向けのIP設定を行う

```
$ export CONTROLLER0_OAM_CIDR=10.10.10.3/24
$ export DEFAULT_OAM_GATEWAY=10.10.10.1
$ sudo ip address add $CONTROLLER0_OAM_CIDR dev enp0s3
$ sudo ip link set up dev enp0s3
$ sudo ip route add default via $DEFAULT_OAM_GATEWAY dev enp0s3

#設定完了後、NATを経由してpingが成功することを確認する
$ ping 8.8.8.8
```

※Ansibleによる自動構築時に外部参照が必要となるため、必ず確認すること

5. 自動構築用のymlファイルを作成する
※今回はドキュメント記載のサンプルをそのまま利用した

```localhost.yml

$ cd ~
$ cat <<EOF > localhost.yml
---
system_mode: duplex

dns_servers:
- 8.8.8.8
- 8.8.4.4

external_oam_subnet: 10.10.10.0/24
external_oam_gateway_address: 10.10.10.1
external_oam_floating_address: 10.10.10.2
external_oam_node_0_address: 10.10.10.3
external_oam_node_1_address: 10.10.10.4

admin_username: admin
admin_password: <admin-password>
ansible_become_pass: <sysadmin-password>

# Add these lines to configure Docker to use a proxy server
# docker_http_proxy: http://my.proxy.com:1080
# docker_https_proxy: https://my.proxy.com:1443
# docker_no_proxy:
# - 1.2.3.4

EOF

$ cat localhost.yml
```

6. ansibleを起動し、インストールを行う。
※インストール完了まで15分程度必要

```
$ ansible-playbook /usr/share/ansible/stx-ansible/playbooks/bootstrap.yml

...

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************************************************
localhost: ok=322changed=185unreachable=0failed=0 
```

#### Controller-0 設定

1.OAM及びManagement Network向けのインターフェースを構成する。

```

$ source /etc/platform/openrc

$ OAM_IF=enp0s3
$ MGMT_IF=enp0s8
$ system host-if-modify controller-0 lo -c none
$ IFNET_UUIDS=$(system interface-network-list controller-0 | awk '{if ($6=="lo") print $4;}')
$ for UUID in $IFNET_UUIDS; do
system interface-network-remove ${UUID}
done

$ system host-if-modify controller-0 $OAM_IF -c platform
$ system interface-network-assign controller-0 $OAM_IF oam
$ system host-if-modify controller-0 $MGMT_IF -c platform
$ system interface-network-assign controller-0 $MGMT_IF mgmt
$ system interface-network-assign controller-0 $MGMT_IF cluster-host

```

2. NTPサーバを構成する

```
$ system ntp-modify ntpservers=0.pool.ntp.org,1.pool.ntp.org
```

3. Controllerのロックを解除する。ロック解除後は構成変更適用・サービス開始のために自動で再起動します。
※完了まで10分程度必要

```
system host-unlock controller-0
```

4. Router用VMよりGUI接続を確認する
下記URLへアクセスする。

http://10.10.10.2:8080

user: admin
pass: sysadmin-password


以上で作業完了です。


### 4. Controller-1構築

#### Controller-1 のインストール
1. Contoroller-1を起動する。
2. Contoroller-0側でContoroller-1側の起動を確認する。

コマンドで確認する場合:

```
$ system host-list
+----+--------------+-------------+----------------+-------------+--------------+
| id | hostname | personality | administrative | operational | availability |
+----+--------------+-------------+----------------+-------------+--------------+
| 1| controller-0 | controller| unlocked | enabled | available|
| 2| None | None| locked | disabled| offline|
+----+--------------+-------------+----------------+-------------+--------------+
```

GUIで確認する場合:
Host Inventoryを更新することでUnProvisioned Hostsに追加表示される。

3. Contoroller-0からContoroller-1の自動構築を行う

下記コマンドを実行し、自動構築を行う

```
# system host-listで表示されているidを指定してセットアップを行う
$ system host-update 2 personality=controller
```

※1 インストール完了まで5-10分必要、インストール完了後自動で再起動する。
※2 進捗はGUIを更新することで表示される。

#### Controller-1 の設定

1. *Controller-0* より、下記コマンドを実行しOAM及びManagement Network向けのインターフェースを構成する。

```
$ OAM_IF=enp0s3
$ system host-if-modify controller-1 $OAM_IF -c platform
$ system interface-network-assign controller-1 $OAM_IF oam
$ system interface-network-assign controller-1 mgmt0 cluster-host
```

3. Controllerのロックを解除する。ロック解除後は構成変更適用・サービス開始のために自動で再起動します。
※完了まで10分程度必要

```
$ system host-unlock controller-1
```

以上で作業完了です。

### 5. Kubernetes Dashboard構築

1. Active側のContorollerより下記コマンドを実行する。

```
$ cat <<EOF > dashboard-values.yaml
service:
type: NodePort
nodePort: 30000

rbac:
create: true
clusterAdminRole: true

serviceAccount:
create: true
name: kubernetes-dashboard
EOF

$ helm repo update

$ helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/

$ helm install dashboard kubernetes-dashboard/kubernetes-dashboard -f dashboard-values.yaml

$ cat <<EOF > admin-login.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
EOF

$ kubectl apply -f admin-login.yaml

$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

...
# 最後に出力されるtoken情報を持ってログインするためコピーする

token:eyJhbGciOiJSUzI1NiIsImtpZCI6IjJwLTJSZWgwOFFrek9BZlJEbnRwWGRLLWpOUVdTVzlSUmwxTU5IRHcxMGMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLThyYmtrIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJlNmFhZmZhYi1hNDUxLTRkNGYtYTQ1MC0wMjVmZTA4MmI3Y2IiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ@9.LeL0cS50yRKcSuTJlr4D7GyimISF7F-FcSsEoeOpO3qZDtaeqo07BGEuukBbkQaMrilwuHFsIWGr98yAfjtH0zOFTfrU82fX1QbS0KjFz93ju82Hn4Md7L_8qYFl99dMmqr14fBfFLQZzsxQ0fKmAEr-zWrNl1nXxGGvS3rWNpLlswSae-gu92Nr63ivaD5JwBsQoK9NvOrSt6n5zUS9IhN_lAXxzE10oArjzDDBTOlpl2mo1WvSNrsIbGx_li1w3j9V-5XKKxjvSRSRetg7dhZeJEmGLK4t3MMi_eHYYCuYOPV-VyoIhNak9VBKcPipuN6Y_G3JtWSv_6Sd_sd6xQ
```

2. kubernetes Dashboardへアクセスする。

https://10.10.10.2:30000

token:先ほど出力された内容

## 所感

環境構築だけでも物理リソース、作業内容ともになかなかにハードルの高さを感じました。次はSWACT切替の方法等、実際の手順確認を試していけるとよいなと思っています。