IBM Cloud Virtual Private CloudへのOpenShiftのUPIインストール

# はじめに
OpenShift 4.8がGAしました。現時点では、Red Hat OpenShift on IBM Cloudはバージョン4.6か4.7が利用可能です。最新のOpenShiftをIBM Cloudで利用する方法としては、Power Systems Virtual ServerやVMware Solutionsを利用する方法が考えられますが、ここではIBM Cloud Virtual Private Cloud(VPC)の仮想サーバー・インスタンス(VSI)に導入します。OpenShiftのインストーラーは、IBM CloudでのIPIインストールにもUPIインストールにも対応しないので、UPIインストールできるように一工夫します。最新バージョンの利用が可能である他、サスペンドビリング(Suspend Billing)によりVSI料金を節約することもできます。

https://github.com/openshift/installer

UPIインストールには、RHCOSをiso起動してignitionファイルをロードする方法、下表のようにpxe起動してRHCOSの起動ディスクへのコピーとignitionファイルのロードを行う方法があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/8fb45802-4abe-be5d-1744-9016ca4f2f07.png)
VSIのiso起動やpxe起動はできないため、下記によりUPIインストールを実現します。
・VSI作成元のOSイメージに事前にkernelとintramfsを取り込む。
・VSI作成時にuser-dataを指定してgrub.cfgを上書きする。

> ISO または PXE インストールを使用するかどうかは、状況によって異なります。PXE インストールには、利用可能な DHCP サービスとさらなる準備が必要ですが、インストールプロセスはさらに自動化することが可能です。ISO インストールは主に手動によるプロセスで、複数のマシンを設定する場合には使用しにくい可能性があります。

https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.8/html-single/installing/index#creating-machines-bare-metal

# 1. Virtual Private Cloud(VPC)環境
## 1.1. ネットワーク構成概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/5ad97efc-7a79-d9d3-dd59-f037ec41eda8.png)

(1) IBM Cloudクラシック・インフラストラクチャーに仮想サーバー(classicノード)を作成する。
(2) 作業端末はSSL-VPNでclassicノードのプライベートIPアドレスへログインする。
(3) IBM Cloudクラシック・インフラストラクチャーとVPCをTransit Gatewayで接続する。
(4) UPIインストール前提としてDNS Service、ロード・バランサーを構成する。
(5) COS接続用の仮想プライベート・エンドポイント・ゲートウェイを構成する。
(6) RHCOSのrootfsやignitionファイルはclassicノードに配置する。
(7) master/workerノードは異なるサブネットに構成する。
(8) master/worker/bootstrapノードはclassicノードのsquid経由でインターネットに接続する。
(9) master/workerノードはVPCからアクセス可能なNTPサーバーで時刻合わせをする。

※OpenShiftのコンソールやアプリケーションへのアクセス経路は下記の通りです。IBM Cloudへの接続方法をSSL-VPNのみとしているため若干使い勝手が悪くなっています。classicノードはDNS Serviceを利用できず、また、ロード・バランサーのホスト名「d23c75ae-jp-tok.lb.appdomain.cloud」の名前解決もできません。そのため、dnsmasqで同様の名前解決できるように構成しています。ロード・バランサーの構成変更やインスタンス増減によりIPアドレスが変わるため注意が必要です。

```bash:アクセス経路
作業端末 → classicノード(squidフォワードプロキシ:3128 + dnsmasq)
        → Load Balancer(d23c75ae-jp-tok.lb.appdomain.cloud)
        → OpenShiftルーターPod → OpenshiftコンソールPod
```

## 1.2. Transit Gateway
Transit Gatewayを作成してVPCとClassic infrastructureに接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/33e608c8-49a9-3fdf-fc1e-581d2aae4371.png)

## 1.3. ロード・バランサー
アプリケーションロード・バランサーですが、プロトコルはTCPとしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/a82234d1-1d6d-e6d0-632d-9dca39af9ba3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/f8d2e924-539b-1b38-0719-10276a5b66b6.png)

## 1.4. DNS Service
ゾーン「cloud.vpc」を作成し下表のエントリーを追加します。ワイルドカードを含むホスト名「\*.apps.ocp.cloud.vpc」に対してLoad Balancerのホスト名「d23c75ae-jp-tok.lb.appdomain.cloud」をCNAME設定できないので、OpenShiftコンソール等、インストール時に作成されるルートのホスト名を複数追加しています。上述の通り、classicノードから利用できないので「*.apps.ocp.cloud.vpc」は不要かもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/df10e429-5a0e-c0bc-f955-f99814d8c9c4.png)

## 1.5. 仮想プライベート・エンドポイント・ゲートウェイ
OpenShiftのイメージ・レジストリのストレージとして利用するために構成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/27be147b-6685-b713-10e8-df6637bb246c.png)


# 2. VPC用カスタム・イメージ作成
## 2.1. QCOW2形式OSイメージへのkernelとintramfs取り込み
virt-customizeコマンドを用いて、centosのOSイメージにkernelとintramfsをコピーしています。

```bash:classicノード
wget https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2
wget https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.8/4.8.2/rhcos-4.8.2-x86_64-live-kernel-x86_64
wget https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.8/4.8.2/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img

yum -y install libguestfs-tools-c
systemctl start libvirtd
export LIBGUESTFS_BACKEND=direct
virt-customize -a CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2 --upload rhcos-4.8.2-x86_64-live-kernel-x86_64:/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64
### 標準出力↓
[   0.0] Examining the guest ...
[  51.3] Setting a random seed
[  51.7] Uploading: rhcos-4.8.2-x86_64-live-kernel-x86_64 to /boot/rhcos-4.8.2-x86_64-live-kernel-x86_64
[  53.0] Finishing off

virt-customize -a CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2 --upload rhcos-4.8.2-x86_64-live-initramfs.x86_64.img:/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img
### 標準出力↓
[   0.0] Examining the guest ...
[  52.8] Setting a random seed
[  53.3] Uploading: rhcos-4.8.2-x86_64-live-initramfs.x86_64.img to /boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img
[  57.8] Finishing off

# 仮想サーバー作成時の起動ディスクサイズを100GBに変更
qemu-img resize CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2 100G
### 標準出力↓
qemu-img info CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2
image: CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2
file format: qcow2
virtual size: 100 GiB (107374182400 bytes)
disk size: 1.35 GiB
cluster_size: 65536
Format specific information:
    compat: 0.10
    refcount bits: 16

ls -l
### 標準出力↓
-rw-r--r--. 1 root root 2269249536  7月 28 20:20 CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2
-rw-r--r--. 1 root root   89175364  7月 23 03:10 rhcos-4.8.2-x86_64-live-initramfs.x86_64.img
-rw-r--r--. 1 root root   10030400  7月 23 03:10 rhcos-4.8.2-x86_64-live-kernel-x86_64
```

## 2.2. OSイメージをCloud Object Storageにアップロード
■ 前提
・Cloud Object Storageにバケット「ocp-vpc-image」作成済

```bash:classicノード
ibmcloud login --sso
id=`ibmcloud resource service-instance "Cloud Object Storage-vpc" | grep "^ID" | awk '{print $2}'`
LANG=C ibmcloud iam authorization-policy-create is --source-resource-type image cloud-object-storage Reader --target-service-instance-id ${id}
ibmcloud cos upload --bucket=ocp-vpc-image --key=centos-8-custom.qcow2 --file=CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2
```

## 2.3. Cloud Object StorageからOSイメージをインポート
下記はインポート依頼をするのみです。利用可能になるまで10分程度かかります。

```bash:classicノード
ibmcloud is image-create centos-8-custom --file "cos://jp-tok/ocp-vpc-image/centos-8-custom.qcow2" --os-name centos-8-amd64
```

# 3. classicノードの準備
## 3.1. RHCOS(rootfs)の準備
VSIからダウンロードできるように、httpdのDocumentRoot以下に配置します。

```bash:classicノード
systemctl start httpd
cd /var/www/html
wget https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.8/4.8.2/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img
chmod 644 /var/www/html/*.img
ls -l *.img
### 標準出力↓
-rw-r--r--. 1 root root 923635712  7月 23 03:11 rhcos-4.8.2-x86_64-live-rootfs.x86_64.img
```

## 3.2. ignitionファイルの作成
OpenShiftのインストールや管理のために必要なコマンドを導入し、ignitionファイルを作成します。master/workerノードは、chronyにより「2.rhel.pool.ntp.org」で時刻合わせするようになっていますが、ネットワーク構成上VPCからアクセスできないため、IBM Cloud内の「time.adn.networklayer.com」で時刻合わせをするように、MachineConfigマニフェストを追加しています。

```bash:classicノード
cd /root/ocp/install
wget https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.8.2/openshift-client-linux-4.8.2.tar.gz
wget https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.8.2/openshift-install-linux-4.8.2.tar.gz
tar -xvzf openshift-client-linux-4.8.2.tar.gz
tar -xvzf openshift-install-linux-4.8.2.tar.gz
cp -p ./oc /usr/local/bin/

podman run -i --rm quay.io/coreos/butane:release --pretty --strict < 99_master-chrony.bu > 99_master-chrony.yaml
podman run -i --rm quay.io/coreos/butane:release --pretty --strict < 99_worker-chrony.bu > 99_worker-chrony.yaml
ls -l 99_*
### 標準出力↓
-rw-r--r--. 1 root root 398  7月 28 21:25 99_master-chrony.bu
-rw-r--r--. 1 root root 548  7月 28 21:35 99_master-chrony.yaml
-rw-r--r--. 1 root root 399  7月 28 21:24 99_worker-chrony.bu
-rw-r--r--. 1 root root 548  7月 28 21:35 99_worker-chrony.yaml

mkdir bare-metal
cp -p install-config.yaml bare-metal/
./openshift-install create manifests --dir=bare-metal
cp -p 99_*.yaml bare-metal/openshift/
./openshift-install create ignition-configs --dir=bare-metal
cp -p bare-metal/*.ign /var/www/html/
chmod 644 /var/www/html/*.ign
ls -l /var/www/html/*.ign
### 標準出力↓
-rw-r--r--. 1 root root 271601  7月 28 21:37 /var/www/html/bootstrap.ign
-rw-r--r--. 1 root root   1715  7月 28 21:37 /var/www/html/master.ign
-rw-r--r--. 1 root root   1715  7月 28 21:37 /var/www/html/worker.ign
```

```yaml:install-config.yaml
apiVersion: v1
baseDomain: cloud.vpc
proxy:
  httpProxy: http://10.192.36.132:3128
  httpsProxy: http://10.192.36.132:3128
  noProxy: 10.244.0.0/16,.apps.ocp.cloud.vpc,s3.direct.jp-tok.cloud-object-storage.appdomain.cloud
compute:
- hyperthreading: Enabled
  name: worker
  replicas: 3
controlPlane:
  hyperthreading: Enabled
  name: master
  replicas: 3
metadata:
  name: ocp
networking:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  networkType: OVNKubernetes
  serviceNetwork:
  - 172.30.0.0/16
platform:
  none: {}
fips: false
pullSecret: <pullシークレット>
sshKey: <公開鍵文字列>
```

以下はNTPサーバーを指定するためのマニフェストです。

```yaml:99_master-chrony.bu
variant: openshift
version: 4.8.0
metadata:
  name: 99-master-chrony
  labels:
    machineconfiguration.openshift.io/role: master
storage:
  files:
  - path: /etc/chrony.conf
    mode: 0644
    overwrite: true
    contents:
      inline: |
        pool time.adn.networklayer.com iburst
        driftfile /var/lib/chrony/drift
        makestep 1.0 3
        rtcsync
        logdir /var/log/chrony
```

```yaml:99_worker-chrony.bu
variant: openshift
version: 4.8.0
metadata:
  name: 99-worker-chrony
  labels:
    machineconfiguration.openshift.io/role: worker
storage:
  files:
  - path: /etc/chrony.conf
    mode: 0644
    overwrite: true
    contents:
      inline: |
        pool time.adn.networklayer.com iburst
        driftfile /var/lib/chrony/drift
        makestep 1.0 3
        rtcsync
        logdir /var/log/chrony
```

OpenShift 4.8からMachineConfigの作成方法が変更されています。

https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.7/html/post-installation_configuration/using-machineconfigs-to-change-machines#installation-special-config-chrony_post-install-machine-configuration-tasks

https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.8/html/post-installation_configuration/using-machineconfigs-to-change-machines#installation-special-config-chrony_post-install-machine-configuration-tasks

# 4. OpenShiftのUPIインストール
## 4.1. 仮想サーバー・インスタンス作成
master/worker/bootstrapノードのVSIを作成します。

```bash:classicノード
./instance-create.sh master-0 vpc-ocp jp-tok-1 bx2-4x16 subnet-tok1 10.244.0.110
./instance-create.sh master-1 vpc-ocp jp-tok-2 bx2-4x16 subnet-tok2 10.244.64.110
./instance-create.sh master-2 vpc-ocp jp-tok-3 bx2-4x16 subnet-tok3 10.244.128.110
./instance-create.sh worker-0 vpc-ocp jp-tok-1 bx2-4x16 subnet-tok1 10.244.0.111
./instance-create.sh worker-1 vpc-ocp jp-tok-2 bx2-4x16 subnet-tok2 10.244.64.111
./instance-create.sh worker-2 vpc-ocp jp-tok-3 bx2-4x16 subnet-tok3 10.244.128.111
./instance-create.sh bootstrap vpc-ocp jp-tok-3 bx2-4x16 subnet-tok3 10.244.128.120
```

```bash:instance-create.sh
#!/bin/sh

ins=${1}
vpc=${2}
zone=${3}
prof=${4}
sub=${5}
ip=${6}

vpcid=`ibmcloud is vpcs | grep ${vpc} | awk '{print $1}'`
subid=`ibmcloud is subnets | grep ${vpc} | grep ${sub} | awk '{print $1}'`
imageid=`ibmcloud is images --visibility private | grep "centos-8-custom" | awk '{print $1}'`
secgid=`ibmcloud is security-groups | grep ${vpc} | awk '{print $1}'`
keyid=`ibmcloud is keys | grep "sshkey" | awk '{print $1}'`

tmp={\"name\":\"eth0\",\"subnet\":{\"id\":\"${subid}\"},\"primary_ipv4_address\":\"${ip}\",\"security_groups\":[{\"id\":
\"${secgid}\"}]}

ibmcloud is instance-create ${ins} ${vpcid} ${zone} ${prof} ${subid} \
  --image-id ${imageid} \
  --primary-network-interface ${tmp} \
  --key-ids ${keyid}                 \
  --user-data @user-data-${ins}.sh

exit 0
```

以下はVSI作成時にuser-dataとして渡すシェルです。ノード毎に作成しています。grub.cfgを差替えてOSを再起動します。OS再起動後、RHCOSの起動ディスクへのコピーとignitionファイルのロードが実行されて、OpenShiftのインストールが開始されます。

```bash:user-data-bootstrap.sh
#!/bin/bash

cat <<EOF > /boot/grub2/grub.cfg
default=0
timeout=60
menuentry "Bootstrap CoreOS (BIOS)" {
insmod gzio
linux "/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64" rd.neednet=1 ip=10.244.128.120::10.244.128.1:255.255.255.0:bootstrap:ens3:none nameserver=161.26.0.7 nameserver=161.26.0.8 coreos.inst=yes coreos.inst.install_dev=vda coreos.live.rootfs_url=http://10.192.36.132:8080/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img coreos.inst.ignition_url=http://10.192.36.132:8080/bootstrap.ign
initrd "/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img"
}
EOF

reboot
```

```bash:user-data-master-0.sh
#!/bin/bash

cat <<EOF > /boot/grub2/grub.cfg
default=0
timeout=60
menuentry "Master CoreOS (BIOS)" {
insmod gzio
linux "/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64" rd.neednet=1 ip=10.244.0.110::10.244.0.1:255.255.255.0:master-0:ens3:none nameserver=161.26.0.7 nameserver=161.26.0.8 coreos.inst=yes coreos.inst.install_dev=vda coreos.live.rootfs_url=http://10.192.36.132:8080/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img coreos.inst.ignition_url=http://10.192.36.132:8080/master.ign
initrd "/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img"
}
EOF

reboot
```

```bash:user-data-master-1.sh
#!/bin/bash

cat <<EOF > /boot/grub2/grub.cfg
default=0
timeout=60
menuentry "Master CoreOS (BIOS)" {
insmod gzio
linux "/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64" rd.neednet=1 ip=10.244.64.110::10.244.64.1:255.255.255.0:master-1:ens3:none nameserver=161.26.0.7 nameserver=161.26.0.8 coreos.inst=yes coreos.inst.install_dev=vda coreos.live.rootfs_url=http://10.192.36.132:8080/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img coreos.inst.ignition_url=http://10.192.36.132:8080/master.ign
initrd "/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img"
}
EOF

reboot
```

```bash:user-data-master-2.sh
#!/bin/bash

cat <<EOF > /boot/grub2/grub.cfg
default=0
timeout=60
menuentry "Master CoreOS (BIOS)" {
insmod gzio
linux "/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64" rd.neednet=1 ip=10.244.128.110::10.244.128.1:255.255.255.0:master-2:ens3:none nameserver=161.26.0.7 nameserver=161.26.0.8 coreos.inst=yes coreos.inst.install_dev=vda coreos.live.rootfs_url=http://10.192.36.132:8080/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img coreos.inst.ignition_url=http://10.192.36.132:8080/master.ign
initrd "/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img"
}
EOF

reboot
```

```bash:user-data-worker-0.sh
#!/bin/bash

cat <<EOF > /boot/grub2/grub.cfg
default=0
timeout=60
menuentry "Worker CoreOS (BIOS)" {
insmod gzio
linux "/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64" rd.neednet=1 ip=10.244.0.111::10.244.0.1:255.255.255.0:worker-0:ens3:none nameserver=161.26.0.7 nameserver=161.26.0.8 coreos.inst=yes coreos.inst.install_dev=vda coreos.live.rootfs_url=http://10.192.36.132:8080/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img coreos.inst.ignition_url=http://10.192.36.132:8080/worker.ign
initrd "/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img"
}
EOF

reboot
```

```bash:user-data-worker-1.sh
#!/bin/bash

cat <<EOF > /boot/grub2/grub.cfg
default=0
timeout=60
menuentry "Worker CoreOS (BIOS)" {
insmod gzio
linux "/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64" rd.neednet=1 ip=10.244.64.111::10.244.64.1:255.255.255.0:worker-1:ens3:none nameserver=161.26.0.7 nameserver=161.26.0.8 coreos.inst=yes coreos.inst.install_dev=vda coreos.live.rootfs_url=http://10.192.36.132:8080/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img coreos.inst.ignition_url=http://10.192.36.132:8080/worker.ign
initrd "/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img"
}
EOF

reboot
```

```bash:user-data-worker-2.sh
#!/bin/bash

cat <<EOF > /boot/grub2/grub.cfg
default=0
timeout=60
menuentry "Worker CoreOS (BIOS)" {
insmod gzio
linux "/boot/rhcos-4.8.2-x86_64-live-kernel-x86_64" rd.neednet=1 ip=10.244.128.111::10.244.128.1:255.255.255.0:worker-2:ens3:none nameserver=161.26.0.7 nameserver=161.26.0.8 coreos.inst=yes coreos.inst.install_dev=vda coreos.live.rootfs_url=http://10.192.36.132:8080/rhcos-4.8.2-x86_64-live-rootfs.x86_64.img coreos.inst.ignition_url=http://10.192.36.132:8080/worker.ign
initrd "/boot/rhcos-4.8.2-x86_64-live-initramfs.x86_64.img"
}
EOF

reboot
```

## 4.2. UPIインストール完了待機
CSR承認等をシェルで自動化してUPIインストールの完了を待機します。

```bash:classicノード
./wait.sh
### 標準出力↓
INFO Waiting up to 20m0s for the Kubernetes API at https://api.ocp.cloud.vpc:6443...
INFO API v1.21.1+f36aa36 up
INFO Waiting up to 30m0s for bootstrapping to complete...
INFO It is now safe to remove the bootstrap resources
INFO Time elapsed: 13m55s

Error from server: etcdserver: request timed out
Error from server: etcdserver: request timed out
Error from server: etcdserver: request timed out
certificatesigningrequest.certificates.k8s.io/csr-29z78 approved
certificatesigningrequest.certificates.k8s.io/csr-fqz4n approved
certificatesigningrequest.certificates.k8s.io/csr-jz7w6 approved
certificatesigningrequest.certificates.k8s.io/csr-8dqcd approved
certificatesigningrequest.certificates.k8s.io/csr-fh4n8 approved
certificatesigningrequest.certificates.k8s.io/csr-k4jjh approved
Error from server (InternalError): an error on the server ("") has prevented the request from succeeding (get nodes)
Error from server (InternalError): an error on the server ("") has prevented the request from succeeding (get certificatesigningrequests.certificates.k8s.io)
Error from server (InternalError): an error on the server ("") has prevented the request from succeeding (get nodes)
Error from server (InternalError): an error on the server ("") has prevented the request from succeeding (get certificatesigningrequests.certificates.k8s.io)

INFO Waiting up to 40m0s for the cluster at https://api.ocp.cloud.vpc:6443 to initialize...
INFO Waiting up to 10m0s for the openshift-console route to be created...
INFO Install complete!
INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/root/ocp/install/bare-metal/auth/kubeconfig'
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.ocp.cloud.vpc
INFO Login to the console with user: "kubeadmin", and password: "<パスワード>"
INFO Time elapsed: 14m22s
```

```bash:wait.sh
./openshift-install wait-for bootstrap-complete --dir=bare-metal

sleep 120

while true
do
  nodes=`oc get nodes | grep " Ready " | egrep "master|worker" | wc -l`
  if [ ${nodes} -eq 6 ]; then
    break
  else
    oc get csr | grep "Pending" | awk '{print $1}' | xargs oc adm certificate approve 2> /dev/null
  fi
  sleep 10
done

./openshift-install wait-for install-complete --dir=bare-metal
```

「wait.sh」完了後、すべてのオペレーターが正常に稼働していることを確認できます。

```bash:classicノード
oc get co
### 標準出力↓
NAME                                       VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE
authentication                             4.8.2     True        False         False      13m
baremetal                                  4.8.2     True        False         False      41m
cloud-credential                           4.8.2     True        False         False      47m
cluster-autoscaler                         4.8.2     True        False         False      41m
config-operator                            4.8.2     True        False         False      42m
console                                    4.8.2     True        False         False      19m
csi-snapshot-controller                    4.8.2     True        False         False      41m
dns                                        4.8.2     True        False         False      41m
etcd                                       4.8.2     True        False         False      39m
image-registry                             4.8.2     True        False         False      36m
ingress                                    4.8.2     True        False         False      25m
insights                                   4.8.2     True        False         False      34m
kube-apiserver                             4.8.2     True        False         False      39m
kube-controller-manager                    4.8.2     True        False         False      40m
kube-scheduler                             4.8.2     True        False         False      36m
kube-storage-version-migrator              4.8.2     True        False         False      42m
machine-api                                4.8.2     True        False         False      40m
machine-approver                           4.8.2     True        False         False      41m
machine-config                             4.8.2     True        False         False      40m
marketplace                                4.8.2     True        False         False      40m
monitoring                                 4.8.2     True        False         False      23m
network                                    4.8.2     True        False         False      42m
node-tuning                                4.8.2     True        False         False      42m
openshift-apiserver                        4.8.2     True        False         False      36m
openshift-controller-manager               4.8.2     True        False         False      40m
openshift-samples                          4.8.2     True        False         False      34m
operator-lifecycle-manager                 4.8.2     True        False         False      41m
operator-lifecycle-manager-catalog         4.8.2     True        False         False      41m
operator-lifecycle-manager-packageserver   4.8.2     True        False         False      36m
service-ca                                 4.8.2     True        False         False      42m
storage                                    4.8.2     True        False         False      42m
```

## 4.3. イメージレジストリーの設定
OpenShift導入直後は、コンテナイメージを格納するレジストリのストレージ設定がされておらず、コンテナイメージを作成し格納することができません。Red Hatのマニュアルには、イメージレジストリーにオブジェクトストレージが推奨されること、AWS S3を利用可能であることが記述されています。Cloud Object StorageはAWS S3互換なのでイメージレジストリに設定します。

■ 前提
・Cloud Object Storageにバケット「openshift-image-registry」作成済
・HMACを含む資格情報を作成済

```bash:classicノード
oc create secret generic image-registry-private-configuration-user \
  --from-literal=REGISTRY_STORAGE_S3_ACCESSKEY=<access_key_id>     \
  --from-literal=REGISTRY_STORAGE_S3_SECRETKEY=<secret_access_key> \
  -n openshift-image-registry
oc patch configs.imageregistry.operator.openshift.io cluster \
  --type merge                                               \
  --patch '{"spec":{"storage":{"s3":{"bucket":"openshift-image-registry","regionEndpoint":"s3.direct.jp-tok.cloud-object-storage.appdomain.cloud","region":"dummy"}}}}'
oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"managementState":"Managed"}}'

oc get pod -n openshift-image-registry
### 標準出力↓
NAME                                               READY   STATUS    RESTARTS   AGE
cluster-image-registry-operator-5dffdbc944-jf2tv   1/1     Running   3          40m
image-registry-767865b8c6-z7kq7                    1/1     Running   0          28s
node-ca-4wp42                                      1/1     Running   0          20m
node-ca-5z2pj                                      1/1     Running   0          20m
node-ca-jm95c                                      1/1     Running   0          23m
node-ca-kfr5d                                      1/1     Running   0          20m
node-ca-mbjfj                                      1/1     Running   0          23m
node-ca-qdrcb                                      1/1     Running   0          23m
```

下図はCloud Object Storageの資格情報の抜粋です。
![hmac.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/c2e5c992-4fac-96fd-4d87-0e5e29a20f61.png)

# おわりに
マネージドサービス「Red Hat OpenShift on IBM Cloud」のように、すぐに利用可能なストレージクラスは提供されていませんが、Block Storage for VPCは利用可能であるため、infraノードを構成したりPortworxを導入することが可能です。また、IBM Cloudのモニタリングやロギングサービスとの連携も可能です。

- infraノード構成
    - Block Storage for VPC
        - Local Storageオペレーター
        - OpenShift Loggingオペレーター
        - OpenShift Elasticsearchオペレーター

- ソフトウェア定義ストレージ
    - Portworx

- モニタリング
    - IBM Cloud Monitoring with Sysdig

- ロギング
    - IBM Log Analysis with LogDNA

https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.8/html/post-installation_configuration/post-install-creating-infrastructure-machinesets-production#creating-an-infra-node_post-install-cluster-tasks