Openshift on Nutanix AHVを完全手動UPIインストール 

# はじめに
この記事は[Nutanix Advent Calendar 2021](https://adventar.org/calendars/6154)の12/12分のエントリその1です。

Nutanix AOS/AHV上にRedhat Openshiftを導入する手順について、まずは完全手動UPIインストール手順を日本語化しました。

# 前提情報
## バージョン情報
Nutanix AOS: 5.20
Openshift: 4.9
Nutanix CSI: 2.4.3

Openshift 4.9の[Installing a user-provisioned cluster on bare metal
](https://docs.openshift.com/container-platform/4.9/installing/installing_bare_metal/installing-bare-metal.html
)と、[Nutanix公式GithubにおけるOpenshiftインストール手順](https://github.com/nutanix/openshift/tree/main/docs/install/manual)を参考に記載しました。

## 構成

![スクリーンショット 2021-12-13 11.12.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/a3fa6a56-3f3b-33c8-2a54-988a22c9a0c2.png)

## リソース情報
### ヘルパーノード(作業用踏み台/DNSサーバ/APIサーバ向けとアプリトラフィック向け兼用のロードバランサ/Webサーバ)

| マシン      | FQDN         | CPU数        | コア数/CPU   | RAM(GB)         | ストレージ(Gib)     | IPアドレス    |        
|:-----------|:------------|:------------|:------------|:------------|:------------|:------------|
|Helper      |bastion/ns/lb/web.(ドメイン名)           |2            |2            |8            |100          |10.42.9.135 |

### Openshiftクラスタ
| マシン      | FQDN         | CPU数        | コア数/CPU   | RAM(GB)         | ストレージ(GiB)     |IPアドレス     |
|:-----------|:------------|:------------|:------------|:------------|:------------|:------------|
| Bootstrap     |bootstrap.(クラスタ名).(ドメイン名)     |2            |2            |8            |100          |10.42.9.141 |
| ControlPlane-0|master0.(クラスタ名).(ドメイン名)       |2            |2            |16           |100          |10.42.9.151 |
| ControlPlane-1|master1.(クラスタ名).(ドメイン名)       |2            |2            |16           |100          |10.42.9.152 |
| ControlPlane-2|master2.(クラスタ名).(ドメイン名)       |2            |2            |16           |100          |10.42.9.153 |
| Compute-0     |worker0.(クラスタ名).(ドメイン名)       |1            |2            |8            |100          |10.42.9.161 |
| Compute-1     |worker1.(クラスタ名).(ドメイン名)       |1            |2            |8            |100          |10.42.9.162 |

# 手順
## ヘルパーノードの準備
CentOS7ベースのヘルパーノードに対して各サーバーソフトウェアをインストール、設定していきます。

### BINDによるDNSサーバ設定
各コンポーネントの名前解決に用います。以下の正引き、逆引きのレコードを準備し、namedサービスを有効化します。

```text:正引き.zone
$ORIGIN (ドメイン名).
$TTL 3600
@       IN      SOA     ns.(ドメイン名). root (
                                2021120801      ; Serial
                                3600            ; Refresh
                                900             ; Retry
                                3600000         ; Expire
                                3600 )          ; Minimum
             IN   NS      ns.(ドメイン名).

bastion                     IN      A        10.42.9.135
lb                          IN      A        10.42.9.135
ns                          IN      A        10.42.9.135
web                         IN      A        10.42.9.135

api-int.(クラスタ名)           IN      A       10.42.9.135 ;クラスタ内部のAPI通信
api.(クラスタ名)               IN      A       10.42.9.135 ;クラスタ外部からのAPI通信
*.apps.(クラスタ名)            IN      A       10.42.9.135 ;アプリケーション通信
bootstrap.(クラスタ名)         IN      A       10.42.9.141
master0.(クラスタ名)           IN      A       10.42.9.151
master1.(クラスタ名)           IN      A       10.42.9.152
master2.(クラスタ名)           IN      A       10.42.9.153
worker0.(クラスタ名)           IN      A       10.42.9.161
worker1.(クラスタ名)           IN      A       10.42.9.162
```

```text:逆引き.zone
$TTL 3600
@       IN      SOA     ns.(ドメイン名). root (
                                2021120801     ; Serial
                                3600            ; Refresh
                                900             ; Retry
                                3600000         ; Expire
                                3600 )          ; Minimum
      IN          NS      ns.(ドメイン名).
;


135    IN  PTR api-int.(クラスタ名).(ドメイン名).
135    IN  PTR api.(クラスタ名).(ドメイン名).
141    IN  PTR bootstrap.(クラスタ名).(ドメイン名).
151    IN  PTR master0.(クラスタ名).(ドメイン名).
152    IN  PTR master1.(クラスタ名).(ドメイン名).
153    IN  PTR master2.(クラスタ名).(ドメイン名).
161    IN  PTR worker0.(クラスタ名).(ドメイン名).
162    IN  PTR worker1.(クラスタ名).(ドメイン名).
```

正引き、逆引きが正しく出来るか、確認します、

```
dig +noall +answer @10.42.9.135 api.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 api-int.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 random.apps.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 bootstrap.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 master0.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 master1.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 master2.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 worker0.(クラスタ名).(ドメイン名)
dig +noall +answer @10.42.9.135 worker1.(クラスタ名).(ドメイン名)

dig +noall +answer @10.42.9.135 -x 10.42.9.141
dig +noall +answer @10.42.9.135 -x 10.42.9.151
dig +noall +answer @10.42.9.135 -x 10.42.9.152
dig +noall +answer @10.42.9.135 -x 10.42.9.153
dig +noall +answer @10.42.9.135 -x 10.42.9.161
dig +noall +answer @10.42.9.135 -x 10.42.9.162
dig +noall +answer @10.42.9.135 -x 10.42.9.135
```

### ha proxy設定
kubeapiやアプリトラフィックのロードバランサとして用います。以下の設定を準備し、haproxyサービスを有効化します。

```text:haproxy.cfg
global
  log         127.0.0.1 local2
  pidfile     /var/run/haproxy.pid
  maxconn     4000
  daemon
defaults
  mode                    http
  log                     global
  option                  dontlognull
  option http-server-close
  option                  redispatch
  retries                 3
  timeout http-request    10s
  timeout queue           1m
  timeout connect         10s
  timeout client          1m
  timeout server          1m
  timeout http-keep-alive 10s
  timeout check           10s
  maxconn                 3000
frontend stats
  bind *:1936
  mode            http
  log             global
  maxconn 10
  stats enable
  stats hide-version
  stats refresh 30s
  stats show-node
  stats show-desc Stats for ocp4 cluster 
  stats auth admin:ocp4
  stats uri /stats
listen api-server-6443 
  bind *:6443
  mode tcp
  server bootstrap bootstrap.(クラスタ名).(ドメイン名):6443 check inter 1s backup 
  server master0 master0.(クラスタ名).(ドメイン名):6443 check inter 1s
  server master1 master1.(クラスタ名).(ドメイン名):6443 check inter 1s
  server master2 master2.(クラスタ名).(ドメイン名):6443 check inter 1s
listen machine-config-server-22623 
  bind *:22623
  mode tcp
  server bootstrap bootstrap.(クラスタ名).(ドメイン名):22623 check inter 1s backup 
  server master0 master0.(クラスタ名).(ドメイン名):22623 check inter 1s
  server master1 master1.(クラスタ名).(ドメイン名):22623 check inter 1s
  server master2 master2.(クラスタ名).(ドメイン名):22623 check inter 1s
listen ingress-router-443 
  bind *:443
  mode tcp
  balance source
  server worker0 worker0.(クラスタ名).(ドメイン名):443 check inter 1s
  server worker1 worker1.(クラスタ名).(ドメイン名):443 check inter 1s
listen ingress-router-80 
  bind *:80
  mode tcp
  balance source
  server worker0 worker0.(クラスタ名).(ドメイン名):80 check inter 1s
  server worker1 worker1.(クラスタ名).(ドメイン名):80 check inter 1s
```

### nginx設定
Openshiftをインストールする際のignitionファイルを格納します。以下設定を準備し、nginxサービスを有効化します。

```text:nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       5000;
        listen       [::]:5000;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}
```

### SSHキーペア作成
Openshiftクラスタの各ノードにsshログインする際に用いるSSHキーペアを作成します。

```
ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub
ssh-add ~/.ssh/id_rsa
```

### インストールプログラムを取得
Openshiftクラスタのインストールプログラムを取得、展開します。

```
wget https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/openshift-install-linux.tar.gz
tar -zxvf openshift-install-linux.tar.gz 
mv openshift-install /usr/local/bin/
openshift-install version
```

### シークレット情報を取得
Redhatサイトからシークレット情報を取得し、保存します。

```
https://console.redhat.com/openshift/install/metal/user-provisionedから"Copy pull secret"する
echo 'Copy pull secretでコピーした値' > PullSecret.txt
cat PullSecret.txt
```

### Openshift CLI, Kubernetes CLIを取得
Openshiftクラスタを操作するためのCLI(oc, kubectl)プログラムを取得、展開します。

```
wget https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/openshift-client-linux.tar.gz
mv kubectl /usr/local/bin/
mv oc /usr/local/bin/
kubectl version
oc version
```

### install-config.yamlを作成
Openshiftクラスタの初期化コンフィグを作成します。

```
mkdir ~/openshift
cd ~/openshift
```

```yaml:install-config.yaml
apiVersion: v1
baseDomain: (ドメイン名) 
compute: 
- hyperthreading: Enabled 
  name: worker
  replicas: 0 
controlPlane: 
  hyperthreading: Enabled 
  name: master
  replicas: 3 
metadata:
  name: (クラスタ名)
networking:
  clusterNetwork:
  - cidr: 10.128.0.0/14 
    hostPrefix: 23 
  networkType: OpenShiftSDN
  serviceNetwork: 
  - 172.30.0.0/16
platform:
  none: {} 
fips: false 
pullSecret: 'PullSecret.txtの内容' 
sshKey: '~/.ssh/id_rsa.pubの内容' 
```

install-config.yamlのバックアップを取得します。

```
cp install-config.yaml install-config.yaml.bkup
```

### KubernetesマニフェストとIgnitionコンフィグファイルの作成
マニフェストを作成します。

```
cd ~/openshift
openshift-install create manifests --dir .
```

次のパラメータを更新し、MasterノードへのPodスケジュールを無効化します。

```
grep "mastersSchedulable" manifests/cluster-scheduler-02-config.yml
sed -ie 's/mastersSchedulable: true/mastersSchedulable: false/' manifests/cluster-scheduler-02-config.yml
grep "mastersSchedulable" manifests/cluster-scheduler-02-config.yml
```

ignitionコンフィグを作成します。

```
openshift-install create ignition-configs --dir .
```

次のディレクトリ構成が出来ているはずです。

```
~/openshift
├── auth
│   ├── kubeadmin-password
│   └── kubeconfig
├── bootstrap.ign
├── master.ign
├── metadata.json
└── worker.ign
└── install-config.yaml.bkup
```

作成したignitionコンフィグファイルをnginxによるWebサーバ上に格納します。

```
mkdir /usr/share/nginx/html/ocp
cp bootstrap.ign master.ign worker.ign /usr/share/nginx/html/ocp
chmod +r /usr/share/nginx/html/ocp/*
wget http://web:5000/ocp/bootstrap.ign -O /tmp/bootstrap.ign
```

## Nutanixの準備
### イメージサービスへのISO登録
Prism Centralにログインし、"仮想インフラ" --> "イメージ" --> "イメージを追加"と進みます。イメージソースをURLとし、URLとして **https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/latest/latest/rhcos-live.x86_64.iso** を指定します。

![スクリーンショット 2021-12-10 11.36.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/cf054cf1-c1be-e77a-39fe-17182b667ef6.png)

"次へ"を押し、所望のクラスタ上にCoreOSイメージをアップロードします。

### IPAM機能付きサブネット作成
"Network & Security"　--> "サブネット"　--> "Create Subnet"と進みます。ここではAHVのIPAM機能を用いるため、"IP Address Management"にチェックを入れ、DNSサーバ、ドメイン、IPプールを正しく入力します。

![スクリーンショット 2021-12-10 11.39.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/ea97b32d-7ec9-375c-ad39-f90d89561db3.png)

![スクリーンショット 2021-12-10 11.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/a04e263e-a0e0-22ed-f193-9a1ce7ba37d4.png)

"Save"を押し、サブネットを作成します。

### Bootstrap/ControlPlane/Computeの仮想マシンを作成する
リソース情報を基にBootstrap/ControlPlane/Computeの仮想マシンを必要分作成します。

![スクリーンショット 2021-12-10 11.40.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/f173f738-eddb-ee65-701a-31e37d8cc9a9.png)

![スクリーンショット 2021-12-10 11.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/cadf674b-1925-4f40-f5f7-345e3288face.png)

![スクリーンショット 2021-12-10 11.42.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/9ef8b268-0fa6-452d-b6f1-ec535c2e1891.png)

作成出来たら、パワーオンします。

### コンソールにログインし、CoreOSをディスクにインストール
電源オンになったら各仮想マシンのコンソールに入ります。CoreOSが上がっているので、仮想マシンの役割に応じて以下入力し、ディスクへとCoreOSをインストールします。

```
[Bootstrap]
sudo coreos-installer install /dev/sda --ignition-url=http://web:5000/ocp/bootstrap.ign --insecure-ignition
[Control Plane]
sudo coreos-installer install /dev/sda --ignition-url=http://web:5000/ocp/master.ign --insecure-ignition
[Compute]
sudo coreos-installer install /dev/sda --ignition-url=http://web:5000/ocp/worker.ign --insecure-ignition
```

インストール出来たらシャットダウンします。

```
shutdown -h now
```

[Bootstrap]
![スクリーンショット 2021-12-10 11.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/28a3d30a-8b20-a098-528e-971f20f21634.png)

[Control Plane]
![スクリーンショット 2021-12-10 11.54.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/49c8dcfb-b97c-6796-1fb2-ae0b861b1ad0.png)

[Compute]
![スクリーンショット 2021-12-10 12.03.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/f59301fb-c4fe-4eb1-a4cc-0ca140b786ce.png)

###　ISOディスクをアンマウントし、パワーオン
Prism Centralの"仮想インフラ"　--> "仮想マシン"の各仮想マシンにおいて"Update"メニューに入り、CDROMをアンマウントします。

![スクリーンショット 2021-12-10 11.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/d4d481c3-39e7-0e2b-1117-cb5163f2939b.png)

アンマウントが出来たら、再度パワーオンします。

## Openshiftインストール
### Openshiftインストール状況確認
パワーオンしてCoreOSが起動すると、自動的にOpenshiftクラスタのインストールが始まります。
ヘルパーノードで以下コマンドを入力し、インストール完了を待ちます。

```
openshift-install --dir . wait-for bootstrap-complete --log-level=info
INFO Waiting up to 30m0s for the Kubernetes API at https://api.test.example.com:6443...
INFO API v1.22.1 up
INFO Waiting up to 30m0s for bootstrapping to complete...
INFO It is now safe to remove the bootstrap resources
```

### Bootstrapノードの除去
インストール完了後はBootstrapノードは不要のため、ロードバランサのエントリから削除します。

```
sed -ie 's/server bootstrap/#server bootstrap/g' /etc/haproxy/haproxy.cfg
systemctl reload haproxy
```

また、Prism Centralでbootstrapマシンを電源オフします。

### Openshiftクラスタ状態の確認
クラスタの接続先情報を設定し、クラスタ状態を確認します。

```
mkdir ~/.kube
cp ~/openshift/auth/kubeconfig ~/.kube/config
oc cluster-info
```

### Certificate Signing Requestを承認
Workerノードがまだクラスタに参加出来ていないため、クラスタでCertificate Signing Requestを承認し、Workerノードを参加させます。

```
oc get nodes
oc get csr
oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs --no-run-if-empty oc adm certificate approve
oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs --no-run-if-empty oc adm certificate approve　
oc get csr
oc get nodes
```

### クラスタOperatorの状態確認
クラスタOperatorが正常状態となっていることを確認します。AVAILABLE列が全てTrueであれば正常です。

```
watch -n5 oc get clusteroperators
```

##　Nutanix CSIインストール
OpenshiftクラスタからNutanixの提供するブロックストレージを使用可能とするためのCSIをインストール・設定します。

### ローカルマシンからの名前解決設定
まずはOpenshiftコンソールにログインするため、ローカルマシンからOpenshiftクラスタにアクセスするための名前解決設定を行います。以下はMacでの例です。

```
sudo vi /etc/hosts

10.42.9.135 console-openshift-console.apps.(クラスタ名).(ドメイン名) oauth-openshift.apps.(クラスタ名).(ドメイン名) downloads-openshift-console.apps.(クラスタ名).(ドメイン名) alertmanager-main-openshift-monitoring.apps.(クラスタ名).(ドメイン名) grafana-openshift-monitoring.apps.(クラスタ名).(ドメイン名) prometheus-k8s-openshift-monitoring.apps.(クラスタ名).(ドメイン名) thanos-querier-openshift-monitoring.apps.(クラスタ名).(ドメイン名)
```

その他、dnsmasq等を使用して(クラスタ名).(ドメイン名)向けの名前解決をヘルパーノードに送る設定を行うと/etc/hostsが汚れなく便利です。

### Openshiftコンソールへのアクセス
ヘルパーノードで以下実行し、コンソールアクセスのためのパスワードを確認します。

```
cat ~/openshift/auth/kubeadmin-password
```

以下URLにブラウザでアクセスし、Username、Passwordを入力します。

```
https://console-openshift-console.apps.(クラスタ名).(ドメイン名)
Username: kubeadmin
Password: 上で確認したパスワード
```

![スクリーンショット 2021-12-10 15.28.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/5a4f4deb-e49a-f225-00c6-55706de7e824.png)

### Nutanix CSI Operatorのインストール
"Operators" --> "OperatorHub"と進み、"Nutanix"を検索すると、 **Nutanix CSI Operator** が出てきます。

![スクリーンショット 2021-12-10 15.32.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/97ea3fb4-86b5-de4b-ff0c-03e2493f75c8.png)

"Install"をクリックします。

![スクリーンショット 2021-12-10 15.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/37af9fb6-c42f-3efc-d049-87f104c0b7e3.png)

選択肢は全てデフォルトで問題ありません。"Install"をクリックします。

![スクリーンショット 2021-12-10 15.35.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/b049bc03-fa7d-1d0f-9bd0-292abce3b527.png)

しばらく待つと、"Nutanix CSI Operator"のインストールが完了します。

![スクリーンショット 2021-12-10 15.36.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/985978e6-ef20-4ba3-7986-e5f7aec6b985.png)

"Installed Operators"から"Provided APIs"内の"NutanixCsiStorage"内の"+ Create instance"をクリックします。

![スクリーンショット 2021-12-10 16.51.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/443320b6-de44-ccbb-4e34-809cf5fa1a29.png)

"Create"をクリックし、CSIプラグインの実体となるインスタンスを起動します。

![スクリーンショット 2021-12-10 16.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/53cd7191-3d2d-bc88-3651-27c0dfad8378.png)

"Workloads" --> "Pods"から"Project: ntnx-system"　に以下のPodが起動していれば完了です。

![スクリーンショット 2021-12-10 16.53.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134931/655dc29f-201d-16a4-5e17-db7eedef908b.png)

### Nutanix CSI Operatorの設定
CoreOSではデフォルトでNutanix CSIが必要とするiscsidサービスが起動していないため、[こちら](https://portal.nutanix.com/page/documents/kbs/details?targetId=kA07V000000LWXJSA4)のワークアラウンドを実行します。以下のファイルをヘルパーノード上に作成します。

```yaml:99-master-custom-enable-iscsid.yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  labels:
    machineconfiguration.openshift.io/role: master
  name: 99-master-custom-enable-iscsid
spec:
  config:
    ignition:
      version: 3.1.0
    systemd:
      units:
      - enabled: true
        name: iscsid.service
```
```yaml:99-worker-custom-enable-iscsid.yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  labels:
    machineconfiguration.openshift.io/role: worker
  name: 99-worker-custom-enable-iscsid
spec:
  config:
    ignition:
      version: 3.1.0
    systemd:
      units:
      - enabled: true
        name: iscsid.service
```

クラスタに適用します。

```
oc apply -f 99-master-custom-enable-iscsid.yaml
oc apply -f 99-worker-custom-enable-iscsid.yaml
```

CSIからPrismにアクセスするための設定をヘルパーノード上に作成します。

```yaml:storage-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: ntnx-secret
  namespace: ntnx-system
stringData:
  key: (Prism Element IPアドレス):(Prism Elementポート番号):(ユーザ名):(パスワード)
```

NutanixのVolumes向けストレージクラスを作成します。

```yaml:storage-class.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: nutanix-volume
provisioner: csi.nutanix.com
parameters:
  csi.storage.k8s.io/provisioner-secret-name: ntnx-secret
  csi.storage.k8s.io/provisioner-secret-namespace: ntnx-system
  csi.storage.k8s.io/node-publish-secret-name: ntnx-secret
  csi.storage.k8s.io/node-publish-secret-namespace: ntnx-system
  csi.storage.k8s.io/controller-expand-secret-name: ntnx-secret
  csi.storage.k8s.io/controller-expand-secret-namespace: ntnx-system
  csi.storage.k8s.io/fstype: ext4
  dataServiceEndPoint: (Prism データサービス IPアドレス):3260
  storageContainer: (ストレージコンテナ名)
  storageType: NutanixVolumes
  #whitelistIPMode: ENABLED
  #chapAuth: ENABLED
allowVolumeExpansion: true
reclaimPolicy: Delete
```

クラスタに適用します。

```
oc apply -f storage-secret.yaml
oc apply -f storage-class.yaml
```

試しにPVCを作ってみます。

```yaml:test-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nutanix-volume
```

上のファイルを適用して、default namespace上にPV,PVCが作成されていることに確認します。

```
oc apply -f test-pvc.yaml 
oc get pv,pvc
```

### イメージレジストリ向けストレージの設定
Openshiftに搭載されているコンテナイメージレジストリのバックエンドストレージとしてNutanix Volumesから切り出したPVCを設定します。

```yaml:image-registry-claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: image-registry-claim
  namespace: openshift-image-registry
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
  storageClassName: nutanix-volume
```

クラスタに適用します。

```
oc apply -f image-registry-claim.yaml 
```

イメージレジストリの設定を以下により変更します。

```
oc edit configs.imageregistry.operator.openshift.io

managementState: Removed
--> managementState: Managed

rolloutStrategy: RollingUpdate
--> rolloutStrategy: Recreate

storage: {}
--> storage:
      pvc:
       claim: image-registry-claim
```

イメージレジストリ向けのPodが起動していれば完了です。

```
oc get po -n openshift-image-registry | grep image-registry | grep -v operator
```

# おわりに
マルチノードでの最小構成OpenshiftクラスタをNutanix上に手動UPI手順で立ち上げる方法をご紹介しました。今回ご紹介した手順は完全手動手順のため、なかなか大変ですが、次回以降、Redhatの提供するAssisted Installerを利用したUPI手順やNutanix Calmを利用した自動化手順をご紹介します。