【OpenShift 4】CodeReady Containers 1.2.0をWindowsで動かそうとしたら大変だった話

本記事は[OpenShift Advent Calendar 2019](https://qiita.com/advent-calendar/2019/openshift)の4日目のエントリになります。
仕事でOpenShift(3.11)のインストールばかり1年以上やっていますが結構しんどい(笑)です。
(GitOpsとかCI/CDとかクラウドネイティブなアプリ開発とか色々やってみたい…！)

実は初めてのアドベントカレンダー参加ですがよろしくお願いします。

- [code-ready/crc: CodeReady Containers is a tool that manages a local OpenShift 4.x cluster optimized for testing and development purposes](https://github.com/code-ready/crc)
    - [Releases · code-ready/crc](https://github.com/code-ready/crc/releases)
- [Getting Started Guide](https://code-ready.github.io/crc/)

---

2020.09.23追記:
ver1.16(OCP ver 4.5.9)で試すと、本記事内の「あらかじめcrcという名前で仮想スイッチを作っておく」必要が無くなり、"Default Switch"でデプロイできるようになった模様。(正確には、本記事作成時に"crc"に名前変更したスイッチを、また別の名前にして試してもうまくいった)
また、DNSに関してもOS設定が変更されないようになり、stop後もそのまま使えるようになっています。(どこでCRC用DNS設定を参照しているのか不明…)

[個人環境で無料で利用できるOpenShift 4.x環境4選 - zaki work log](https://zaki-hmkc.hatenablog.com/entry/2020/09/23/202914)

# TL;DR

実を言うとVirtualBoxはもうだめです。突然こんなこと言ってごめんね。でも本当です。もうしばらくするとクリスマスになります。それが終わりの合図です。

というわけで、WindowsにCodeReady Containersをセットアップするにはv1.2.0時点ではHyper-Vほぼ一択。
ただしそれでもv1.2.0では`crc`という名前で仮想スイッチを事前準備する必要があったり、まだ他のプラットフォーム程お手軽セットアップはできない。
ちなみに古いバージョン(2019年12月時点でのv1.1.0以前など)のCodeReady Containersは、証明書の期限が切れているためデプロイできない。

環境があるならLinuxにデプロイするのがトラブルが少ないです💦
macOSは環境持ってないので試せず…すみません。(なんとなくWindowsよりはトラブル少ない感じはしますが)

# CodeReady Containersとは

(以下、個人の解釈が入り混じっています)

OpenShift version 4をシングルノードVM環境にデプロイするツールです。
Kubernetesユーザであれば、[Minikube](https://kubernetes.io/ja/docs/tasks/tools/install-minikube/)というシングルノード環境をデプロイするツールがありますが、あれのOpenShift 4版だと思っていただいて大丈夫なはずです。
MinikubeのようなことをするOpenShift用ツールは、以前は[Minishift](https://docs.okd.io/latest/minishift/getting-started/installing.html)があったのですが(いや、今もあるけど)、小耳に挟んだ情報では3.11で対応が終了してしまったらしいです。
4.x以降はCodeReady Containersを使うようになりました。

[code-ready/crc: CodeReady Containers is a tool that manages a local OpenShift 4.x cluster optimized for testing and development purposes](https://github.com/code-ready/crc)

MinikubeやMinishiftを使ったことある方ならイメージ付きやすいですが、導入したホストOS上で動作する仮想環境(libvirt/HyperKit/Hyper-V)を使ってVMを作成し、そのVMをノードとしてOpenShift 4をデプロイします。

図にするとこんな感じ。

![crc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/eca16830-81b1-40f2-8f8f-c8ae3922e268.png)

ただ、Minikube/Minishiftと違って、主に以下の違いがあります。

- プロファイル切り替えによる複数クラスタ管理ができない
- ノードへの(`minikube ssh`のようなわかりやすい)ssh接続機能がない
- DNS設定が別途必要

ちなみに、似た名前のツールに[CodeReady Workspaces](https://developers.redhat.com/products/codeready-workspaces/overview)というものがあります。
これはコンテナで動作する[Eclipse Che](https://www.eclipse.org/che/)をベースにオーケストレーション環境で動作するIDEです。
が、CodeReady Containersとは関係ないっぽいです。
うーむ、なぜこんな紛らわしいネーミングになったのだろう…

# システム要件

[1.3. Minimum system requirements](https://code-ready.github.io/crc/#minimum-system-requirements_gsg)

HW要件に以下の通り記載があります。

|項目|要件|
|---|---|
|vCPU|4|
|memory|8GB|
|storage|35GB|

これ、ホストOSのスペックだと勘違いしそうだけど(というか、私は勘違いした)、実は「OpenShift 4をデプロイするためのCodeReady Containersが作成するVMのHW要件」になってます。
つまりこのスペックのVMが仮想環境に作成されるので、ホストOSのHW要件は推して知るべし。

# インストール

__基本的な__ インストールの流れを説明します。
といっても、[公式のドキュメント](https://code-ready.github.io/crc/)通りに進めれば特に難しいことはないです。
Windowsの場合はv1.2.0だとドキュメントの通りでは足りないため、一手間二手間加える必要があります(後述)。

- (事前準備)無料のRed Hatの開発者アカウントを作成する(必須)
    - アカウントの登録はそんな難しくないです
        - [Red Hat Developer Program参加とRHEL無償サブスクリプションの取得＆更新 - のぴぴのメモ](http://nopipi.hatenablog.com/entry/2018/09/09/110613)
        - [Red Hat Enterprise Linux Server を開発用に無償利用するために Red Hat Developer Program に参加する - Qiita](https://qiita.com/takuya0301/items/e59fa07f87d8d6e97923)
        - [RHEL 開発者向け無料サブスクリプション提供開始 - 一馬力のメモ帳](https://ichibariki.hatenablog.com/entry/2016/04/30/150017)
    - この辺を確認すれば大丈夫なはず
    - [Red Hat Developer Programに参加して最新技術を学習しよう - 赤帽エンジニアブログ](https://rheb.hatenablog.com/entry/developer-program)
- (Linuxの場合)[1.4. Required software packages](https://code-ready.github.io/crc/#required-software-packages_gsg)に書かれているパッケージをインストールしておく
- [Red Hat OpenShiftのCluster ManagerのLaptop](https://cloud.redhat.com/openshift/install/crc/installer-provisioned)のページにアクセスし、プラットフォーム毎のCodeReady Containersと、Pull Secretをダウンロードする。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/4e6c3096-cb7f-175b-7fa9-629d933f2acc.png)

    と

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/48b56e80-4839-009d-1bee-232995666962.png)

    ※ [Copy Pull Secret]でクリップボードにコピーされるので、インストール時にそのテキストを貼り付けても良いが、データ量が多いのでファイルでダウンロードしてファイルのパスをオプション引数で指定する方がオペレーション的には(個人的には)楽かも。この辺はお好みで。

- ダウンロードした`crc-(platform)-amd64.*`を適当なパスへ展開して環境変数の`$PATH`を設定し、`crc`を実行可能にする
- `crc setup`を実行
- `crc start --pull-secret-file $(DLしたpull secretのファイルのパス)`を実行

以上で基本的にOKです。

Linuxであれば、これで動きます。
また、CodeReady Containersへアクセスするための名前解決の設定もCodeReady Containersが(DNS入れてくれたりして)やってくれます。

## Hyper-V環境へのインストール

本記事の本題です。

実はv1.0.0のときにVirtualBoxへのインストールは(だいぶ苦労したけど)実現してて、Hyper-Vは公式サポートしてるから楽勝だろうと高を括ってて、本当は「Windows環境へのCodeReady ContainersはちょっとコツがあるけどこうすればHyper-VもVirtualBoxもできるぜっ！！！」という記事にしたかったのですが、いろいろ制限多すぎて挫折しかけました。

Hyper-Vへのインストールはv1.2.0はなんとか成功したので、その手順について説明します。

以下、システム要件(スペック＆バージョン: Fall Creators Update (version 1709))は満たしているものとします。

### 準備

基本と同じです。

- crc-windows-amd64.zip
- pull-secret.txt

crc-windows-amd64.zipを展開し、環境変数PATHの設定をします。

```ps1
PS C:\Users\zaki> crc version
crc version: 1.2.0+c2e3c0f
OpenShift version: 4.2.8 (embedded in binary)
PS C:\Users\zaki>
```

バージョンが出力されればOKです。

__また、`ipconfig /all`などで、DNSサーバの設定を控えておいてください。__

### crc setup

`crc setup`を実行します。

```ps1
PS C:\Users\zaki> crc setup
INFO Checking if running as normal user
INFO Caching oc binary
INFO Unpacking bundle from the CRC binary
INFO Check Windows 10 release
INFO Hyper-V installed
INFO Is user a member of the Hyper-V Administrators group
ERRO User is not a member of the Hyper-V administrators group
INFO Will run as admin: add user to hyperv admins group
INFO Does the Hyper-V virtual switch exist
ERRO Virtual Switch not found
ERRO Unable to perform Hyper-V administrative commands. Please make sure to re-login or reboot your system
FATA Unable to perform Hyper-V administrative commands. Please make sure to re-login or reboot your system
PS C:\Users\zaki>
```

しかしv1.2.0ではドキュメントの通りに何度やってもこのエラーになります。
`crc setup`を実行しているユーザが`Hyper-V Adminitrator`グループに含まれていてもこのエラーになります。

![2019-11-28_08h16_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/df990a03-e0ad-e054-db5d-6d2fc30b99a0.png)

メッセージを見る限り、CodeReady Containersで使用するVirtual Switchが無いという状態だけど、実はソースコードを確認すると、[「Virtual Switchが無い場合は作成する」というロジックが現状まだ存在しません](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/preflight/preflight_checks_windows.go#L142-L145)。

```go:preflight_checks_windows.go
// Unable to do for now
func fixHyperVVirtualSwitch() (bool, error) {
    return false, errors.New("Unable to perform Hyper-V administrative commands. Please make sure to re-login or reboot your system")
}
```

ではどうすれば良いかと言うと話は単純で、必要なVirtual Switchをあらかじめ作っておけばOKです。
では必要なVirtual Switchが何かというと、[ここのcheckIfHyperVVirtualSwitchExists()というチェック関数](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/preflight/preflight_checks_windows.go#L130)から参照している、[hyperv.AlternativeNetwork](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/machine/hyperv/constants_windows.go#L5)にある`crc`という名前のVirtual Switchがあればよいです。

```go:constants_windows.go
package hyperv

const (
    // Alternative
    AlternativeNetwork = "crc"
)
```

Hyper-VのVirtual Switchはちょっと複雑(と個人的に思い込んでる)なので、「新規で追加」するのがいろいろ設定が面倒な場合は、既存の通信可能なVirtual Switchの「名前」を変更してもOK (手元の環境ではそれで動作した)
手元の環境では、Hyper-V導入時に自動で作成される`outbound-vswitch`を`crc`に名称変更すれば大丈夫でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/d8b28285-5ad9-5374-0c9f-e7ab3cf3a6f0.png)

これで、`crc setup`は「`crc`というVirtual SwitchがあるのでOK」という動作をします。

```ps1
PS C:\Users\zaki> crc setup --log-level debug
INFO Checking if running as normal user
INFO Caching oc binary
DEBU oc binary already cached
INFO Unpacking bundle from the CRC binary
INFO Check Windows 10 release
INFO Hyper-V installed
INFO Is user a member of the Hyper-V Administrators group
INFO Does the Hyper-V virtual switch exist
INFO Found Virtual Switch to use: crc
Setup is complete, you can now run 'crc start' to start the OpenShift cluster
PS C:\Users\zaki>
```

### crc start

繰り返しますが、__`crc start`前に、DNS設定を控えておいてください__。
DNS設定をメモったら`crc start`します。

```ps1
PS C:\Users\zaki> crc start --pull-secret-file .\Downloads\pull-secret.txt
INFO Checking if running as normal user
INFO Checking if oc binary is cached
INFO Check Windows 10 release
INFO Hyper-V installed and operational
INFO Is user a member of the Hyper-V Administrators group
INFO Does the Hyper-V virtual switch exist
INFO Found Virtual Switch to use: crc
INFO Extracting bundle: crc_hyperv_4.2.8.crcbundle ...
INFO Creating CodeReady Containers VM for OpenShift 4.2.8...
INFO Verifying validity of the cluster certificates ...
INFO Will run as admin: add dns server address to interface vEthernet (crc)
INFO Check internal and public DNS query ...
INFO Copying kubeconfig file to instance dir ...
INFO Adding user's pull secret and cluster ID ...
INFO Starting OpenShift cluster ... [waiting 3m]
INFO
INFO To access the cluster, first set up your environment by following 'crc oc-env' instructions
INFO Then you can access it by running 'oc login -u developer -p developer https://api.crc.testing:6443'
INFO To login as an admin, username is 'kubeadmin' and password is *****-*****-*****-*****
INFO
INFO You can now run 'crc console' and use these credentials to access the OpenShift web console
Started the OpenShift cluster
WARN The cluster might report a degraded or error state. This is expected since several operators have been disabled to lower the resource usage. For more information, please consult the documentation
PS C:\Users\zaki>
```

何事もなく成功しました。

`oc login`するには、出力にある通り`oc login -u developer -p developer https://api.crc.testing:6443`すれば通常ユーザでログインできます。
cluster-adminが必要であれば、`kubeadmin`ユーザでパスワードも記載されている通りの内容で`oc login`できます。

`Extracting bundle: crc_hyperv_4.2.8.crcbundle`はかなり時間かかります。
また、`Will run as admin: add dns server address to interface vEthernet (crc)`は特権が必要なのでUACのダイアログで実行を許可する操作が必要。

`--pull-secret-file .\Downloads\pull-secret.txt`は、pull secretのファイルをダウンロードしていた場合に指定します。
指定しない場合は処理中にsecretの値を聞いてくるので、[Copy Pull Secret]でクリップボードにsecretの内容をコピーし、それを貼り付けてもOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/6b5c0cb6-7f10-069f-d7cd-d0b890fac4c5.png)

### DNS設定

`crc start`処理内の特権を使って何をしているかと言うと、Windowsのネットワーク設定のDNSサーバーのアドレスを、CodeReady Containersで作成するノードのアドレスに設定します。

図にするとこんな感じ

![crc on Hyper-V DNS設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/d8487dc7-78ce-c867-34c5-8dae7d90c13a.png)

ノードの中はdnsmasqが稼働しており、ホストOSに元々設定されていたDNSサーバを上位DNSとして設定して動作しています。

これでOpenShift ClusterへのコンソールやpodへのワイルドカードDNSが必要なアクセスの名前解決ができるようになります。

ただこれ、__CodeReady Containersを停止しても自動では元に戻りません。__
なので`crc stop`で停止するとDNSサーバーが居なくなる状態になるため、__手動で元に戻す必要があります。__

再度`crc start`すれば、DNSサーバー設定はまたCodeReady Containersのノードになります。

ちなみにLinuxの場合は、ホストOS上にdnsmasqがインストールされ、必要なゾーン設定が行われます。

あとは`crc oc-env`で`oc`コマンドの場所を確認し、OpenShiftを使い倒せばOKです。

## VirtualBox環境へのインストール

本記事のおまけです。

VirtualBoxへのインストールはv1.2.0で実質不可能になりました。
リソースはまだ提供されてますが、`crc`コマンドでVirtualBox用のロジックが消え始めており、v1.2.0では動作しなくなっています。
以下、なぜ動かないのかざっくり調べました。

また、現時点(2019年12月上旬のCodeReady Containers v1.2.0リリース済みの今)で、VirtualBoxへ __無理やり__ OpenShiftクラスタをデプロイする手順について(アドカレ公開前日の朝に回避策を思いついてしまったので)説明します。

インストールに使用するcrc-windows-amd64.zipはHyper-Vの場合と同じです。
ただし追加でVirtualBox用のcrcbundleファイルが必要です。これはサーバーのファイル一覧から直接ダウンロードします。
(その他のプラットフォームの場合は`crc setup`の処理内でダウンロードされます)

[Index of /pub/openshift-v4/clients/crc/1.2.0](https://mirror.openshift.com/pub/openshift-v4/clients/crc/1.2.0/)

### crc setup --vm-driver virtualboxが失敗する

合っているはずのコマンド実行。

```ps1
PS C:\Users\zaki> crc setup  --vm-driver virtualbox --log-level debug
INFO Checking if running as normal user
INFO Caching oc binary
DEBU oc binary already cached
INFO Unpacking bundle from the CRC binary
DEBU CreateFile C:\Users\zaki\.crc\cache\crc_hyperv_4.2.8.crcbundle: The system cannot find the file specified.
INFO Check Windows 10 release
INFO Hyper-V installed
ERRO Hyper-V not installed
DEBU Hyper-V not installed
INFO Will run as admin: enable Hyper-V
ERRO Please reboot your system
INFO Is user a member of the Hyper-V Administrators group
ERRO User is not a member of the Hyper-V administrators group
DEBU User is not a member of the Hyper-V administrators group
DEBU exit status 1
ERRO Unable to get group name
FATA Unable to get group name
PS C:\Users\zaki>
```

`--vm-driver virtualbox`を指定しているのにHyper-Vとして処理されてしまう。なぜ。(ログレベルを見てもわからない)

ちなみにv1.0.0の`crc`で実行した場合…

```ps1
PS C:\Users\zaki> C:\local\crc-windows-1.0.0-amd64\crc.exe setup -d virtualbox --log-level debug
INFO Checking if running as normal user
INFO Caching oc binary
DEBU oc binary is not cached
DEBU Downloading oc
DEBU Downloading https://mirror.openshift.com/pub/openshift-v4/clients/oc/latest/windows/oc.zip to C:\Users\zaki\AppData\Local\Temp\crc871007279
DEBU Download saved to C:\Users\zaki\AppData\Local\Temp\crc871007279\oc.zip
DEBU Uncompressing C:\Users\zaki\AppData\Local\Temp\crc871007279\oc.zip to C:\Users\zaki\AppData\Local\Temp\crc871007279
DEBU Copying 'C:\Users\zaki\AppData\Local\Temp\crc871007279\oc.exe' to 'C:\Users\zaki\.crc\bin\oc.exe'
DEBU oc binary cached
INFO Unpacking bundle from the CRC binary
DEBU FindFirstFile C:\Users\zaki\.crc\crc_hyperv_4.2.0.crcbundle: The system cannot find the file specified.
Setup is complete, you can now run 'crc start' to start the OpenShift cluster
PS C:\Users\zaki>
```

ですよね。
v1.2.0では`virtualbox`というパラメタが無視されている？

### なぜHyper-Vとして処理されるのか

#### virtualboxの処理を探す

というわけで、Windowsに関するドキュメントほぼ見当たらないので、ソースを当たってみます。
まずは`virtualbox`をキーに検索してみると…

[crc/driver_windows.go at v1.2.0 · code-ready/crc](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/machine/driver_windows.go#L41)

```go:driver_windows.go
    // Supported drivers
    switch machineConfig.VMDriver {

    case "virtualbox":
        logging.Warn("Virtualbox support is deprecated and will be removed in the next release.")
        driver = virtualbox.CreateHost(machineConfig)
    case "hyperv":
        driver = hyperv.CreateHost(machineConfig)

    default:
        errors.ExitWithMessage(1, "Unsupported driver: %s", machineConfig.VMDriver)
    }
```

はい、どうやら次のバージョンではVirtualBoxは削除されるようです。
[Remove Virtualbox support (deprecated) · Issue #838 · code-ready/crc](https://github.com/code-ready/crc/issues/838)

ん、でも、じゃあ現在のv1.2.0ではなぜ動かない？

[crc/client_windows.go at v1.2.0 · code-ready/crc](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/machine/client/client_windows.go)

```go:client_windows.go
        switch driverName {
        case "virtualbox":
            plugin.RegisterDriver(virtualbox.NewDriver("", ""))
        case "hyperv":
            plugin.RegisterDriver(hyperv.NewDriver("", ""))
        default:
            errors.ExitWithMessage(1, fmt.Sprintf("Unregistered driver: %s\n", driverName))
        }
```

この辺は定義は残っている。

[crc/driver.go at v1.2.0 · code-ready/crc](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/machine/virtualbox/driver.go)

```go:driver.go
func CreateHost(machineConfig config.MachineConfig) *virtualbox.Driver {
    virtualboxDriver := virtualbox.NewDriver(machineConfig.Name, constants.MachineBaseDir)

    virtualboxDriver.CPU = machineConfig.CPUs
    virtualboxDriver.BundleName = machineConfig.BundleName
    virtualboxDriver.Memory = machineConfig.Memory

    // Network
    virtualboxDriver.HostOnlyCIDR = "192.168.130.1/24"

//[snip]
```

VirtualBoxを指定した場合のホスト作成のパラメタあたり。この辺も大丈夫そう。(たぶんこのソースが無くなるのかな？)

これらの呼び出し元もざっと検索した限りでは「もし`virtualbox`だったら処理しない」という感じにはなっていなかった。
はっはっは、全くわからない。(Goちからが絶望的に不足している)

#### setupの処理を見ていく

`virtualbox`の場合の処理を探しても見つからなさそうなので、`crc setup`の処理を見ていく。

ひとまず定義されてないドライバ名を指定。(もしかしてパラメタに関係なく`hyperv`として扱われてたりする？)

```ps1
PS C:\Users\zaki> crc setup -d zzz --log-level debug
ERRO Unsupported driver: zzz, use '--vm-driver' option to provide a supported driver [hyperv virtualbox]
PS C:\Users\zaki>
```

んなこたーない。ちゃんとチェックされてる。
ということは、強制的に`hyperv`として処理されている？

`setup`のコマンドのソースから見てみよう。
[crc/setup.go at v1.2.0 · code-ready/crc](https://github.com/code-ready/crc/blob/v1.2.0/cmd/crc/cmd/setup.go)

```go:setup.go
func runSetup(arguments []string) {
    if err := validateSetupFlags(); err != nil {
        errors.Exit(1)
    }
```

まずはvalidation処理があります。
すぐ下に定義してある`validateSetupFlags()`をコールしてる。

```go:setup.go
func validateSetupFlags() error {
    if err := validation.ValidateDriver(vmDriver); err != nil {
        return err
    }
    return nil
}
```

長くなるので省略するけど、「[Windowsの場合は`hyperv`か`virtualbox`の場合](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/machine/driver_windows.go#L14-L29)」以外を弾くようになっているので、「`virtualbox`の場合も問答無用で`hyperv`にしちゃう」みたいなコードはさすがになかった。

その次の処理

```go:setup.go
    preflight.SetupHost()
```

結論としてはここだった。

[crc/preflight_windows.go at v1.2.0 · code-ready/crc](https://github.com/code-ready/crc/blob/v1.2.0/pkg/crc/preflight/preflight_windows.go)
このWindowsの場合のソースなんだけど、Hyper-Vの処理は実装されてるけど、VirtualBoxの場合の処理はない。
この処理が`virtualbox`の場合も呼ばれているため、Hyper-Vの処理に失敗してエラーとなってしまう。

[v1.1.0のときのソース](https://github.com/code-ready/crc/blob/v1.1.0/pkg/crc/preflight/preflight_windows.go)を見ればすぐわかるけど、以前は「`hyperv`の場合のみ処理する」というロジックになっていた。
[この変更によって、常にHyper-Vの場合の処理が行われるようになった模様](https://github.com/code-ready/crc/commit/92f049650dd7341e5e87a6bdbbef588c7bc57381)。

[Remove all VirtualBox preflight checks from our codebase · Issue #662 · code-ready/crc](https://github.com/code-ready/crc/issues/662)

うーん、残念。
まぁもともとWindowsでの利用はHyper-Vをサポートだったからなぁ。。

ということで、VirtualBoxでどうしてもという場合(Windows 10 homeとか)、v1.1.0で一応動くかと思いきや、v1.1.0は証明書の期限の問題で動作しない。

### v1.1.0のインストールを試してみる(失敗した手順)

以下のことを試してみたけどダメでした。

| やったこと                                           | 結果                                    |
| --------------------------------------------------- | ------------------------------------- |
| 普通にv1.1.0インストール                              | 2019.11.30で証明書期限切れ(VMは起動するがOCPは起動しない) |
| ホストOS/BIOSの日付を11/29にしてv1.1.0インストール     | VM内の日付は騙せなかったせいかある程度起動するが同様に起動失敗(6443/TCPのAPIサーバは起動する等かなり良いところまで行くが、route podのhaproxyが起動しないため`oc login`をはじめあらゆるアクセスが通らない)           |

ちょっとゴニョゴニョする程度ではやっぱり使用できないようです。
おそらく、`virtualbox`指定の場合はHyper-Vの処理をスキップするように修正した`crc`のソースをリビルドすれば動作すると思う。(未確認)

### v1.1.0のcrcでv1.2.0のcrcbundleを入れてみる(成功編)

思いつく限り、現在(2019.12上旬)VirtualBoxへCodeReady Containersを入れるには、(`crc`の修正版リビルドを行う以外には)これしかないかも。
そして証明書の期限を考えると、クリスマス頃までの期間限定手順。(それ以降は自分であらゆるバイナリを用意する必要がありそう)

当然ながら無保証です。
大まかな流れは以下の通り。

1. `crc`はv1.1.0、`crcbundle`は最新のv1.2.0を用意
2. `crcbundle`のファイル名を、v1.1.0に対応した`4.2.2`にリネーム(v1.2.0だと`4.2.8`)
3. 展開されたVMのパスも`4.2.2`にリネーム
4. sshの秘密鍵を入れ替える
5. ノードOSのIPアドレスをhostsファイルに設定

これで起動します。
また、作業をスムーズに行うために、ターミナルは2つ(`crc setup|start`実行用と、鍵設定と`crc ip`実行用)起動しておき、名前解決用のhostsファイルをすぐ編集できるようにエディタで開いておきます。

以下、具体的な作業手順。

#### crc version

```ps1
PS C:\Users\zaki> crc version
crc version: 1.1.0+95966a9
OpenShift version: 4.2.2 (embedded in binary)
PS C:\Users\zaki>
```

#### crc setup

```ps1
PS C:\Users\zaki> crc setup --vm-driver virtualbox --log-level debug
INFO Checking if running as normal user
INFO Caching oc binary
DEBU oc binary is not cached
DEBU Downloading oc
DEBU Downloading https://mirror.openshift.com/pub/openshift-v4/clients/oc/latest/windows/oc.zip to C:\Users\zaki\AppData\Local\Temp\crc191759951
DEBU Download saved to C:\Users\zaki\AppData\Local\Temp\crc191759951\oc.zip
DEBU Uncompressing C:\Users\zaki\AppData\Local\Temp\crc191759951\oc.zip to C:\Users\zaki\AppData\Local\Temp\crc191759951
DEBU Copying 'C:\Users\zaki\AppData\Local\Temp\crc191759951\oc.exe' to 'C:\Users\zaki\.crc\bin\oc.exe'
DEBU oc binary cached
INFO Unpacking bundle from the CRC binary
DEBU CreateFile C:\Users\zaki\.crc\crc_hyperv_4.2.2.crcbundle: The system cannot find the file specified.
Setup is complete, you can now run 'crc start' to start the OpenShift cluster
PS C:\Users\zaki>
```

ここまでは普通です。

#### crc start

v1.2.0用の`crc_virtualbox_4.2.8.crcbundle`を`4.2.2`にリネームして`--bundle`で指定して`crc start`実行します。(4.2.8のまま実行するとエラーになる)

```p1
PS C:\Users\zaki> crc start --vm-driver virtualbox --bundle .\archives\crc\1.2.0\crc_virtualbox_4.2.2.crcbundle --pull-secret-file .\archives\crc\pull-secret.txt
WARN A new version (1.2.0) has been published on https://cloud.redhat.com/openshift/install/crc/installer-provisioned
INFO Checking if running as normal user
INFO Checking if oc binary is cached
INFO Extracting bundle: crc_virtualbox_4.2.2.crcbundle ...
ERRO Error getting bundle metadata: Could not find cached bundle info
```

ただし、これもエラーになります。
というのも、ファイルの実体が4.2.8なcrcbundleはファイルを展開するとパスも4.2.8になるため。

```ps1
PS C:\Users\zaki> ls .\.crc\cache\

    ディレクトリ: C:\Users\zaki\.crc\cache

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2019/12/03     23:21                crc_virtualbox_4.2.8

PS C:\Users\zaki>
```

これもディレクトリ名も`4.2.8`から`4.2.2`にリネームしてやります。

```ps1
PS C:\Users\zaki> mv .\.crc\cache\crc_virtualbox_4.2.8\ .\.crc\cache\crc_virtualbox_4.2.2
PS C:\Users\zaki> ls .\.crc\cache\

    ディレクトリ: C:\Users\zaki\.crc\cache

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2019/12/03     23:21                crc_virtualbox_4.2.2

PS C:\Users\zaki>
```

これで、再度`crc start`を実行。
ただしここでもコツが要ります。

```ps1
PS C:\Users\zaki> crc start --vm-driver virtualbox --bundle .\archives\crc\1.2.0\crc_virtualbox_4.2.2.crcbundle --pull-secret-file .\archives\crc\pull-secret.txt
WARN A new version (1.2.0) has been published on https://cloud.redhat.com/openshift/install/crc/installer-provisioned
INFO Checking if running as normal user
INFO Checking if oc binary is cached
INFO Loading bundle: crc_virtualbox_4.2.2.crcbundle ...
INFO Creating CodeReady Containers VM for OpenShift 4.2.8...
INFO Verifying validity of the cluster certificates ...
Please follow instructions in the documentation about setting hostnames for Virtualbox.
INFO Check internal and public DNS query ...
INFO Copying kubeconfig file to instance dir ...
INFO Adding user's pull secret and cluster ID ...

```

この辺までログが出力されたら、以下の鍵入れ替えとhosts設定を __すみやかに__ 行います。

#### ssh秘密鍵入れ替え

[[BUG] CRC failed to restart when use virtualbox · Issue #691 · code-ready/crc](https://github.com/code-ready/crc/issues/691)

この不具合があるため、VirtualBoxでのCodeReady Containers利用はssh秘密鍵の入れ替えを手動で行う必要があります。(ステータスがclosedになってるけど、解決済みじゃなくてサポート終了っぽい…)

入れ替えと言っても、単に`.crc\machines\crc\id_rsa`にある秘密鍵のファイルを`.crc\cache\crc_virtualbox_4.2.2\id_rsa_crc`へコピー＆リネームしてやればOKです。
コマンド的にはホームディレクトリにいる状態で以下の2つを連続で実行すればOK。

- `mv .\.crc\cache\crc_virtualbox_4.2.2\id_rsa_crc .\.crc\cache\crc_virtualbox_4.2.2\id_rsa_crc.bak`
- `cp .\.crc\machines\crc\id_rsa .\.crc\cache\crc_virtualbox_4.2.2\id_rsa_crc`

```ps1
PS C:\Users\zaki> mv .\.crc\cache\crc_virtualbox_4.2.2\id_rsa_crc .\.crc\cache\crc_virtualbox_4.2.2\id_rsa_crc.bak
PS C:\Users\zaki> cp .\.crc\machines\crc\id_rsa .\.crc\cache\crc_virtualbox_4.2.2\id_rsa_crc
```

#### hosts設定

Hyper-Vのノードと違って、VirtualBoxのノードでは、ホストOSのDNS設定をVMのアドレスにしても、名前解決はしてくれませんでした。
なので、hostsを使って名前解決の設定をしてやります。

hostsに最低限加える内容は以下の通り。

```text:hosts
192.168.130.100 api.crc.testing oauth-openshift.apps-crc.testing console-openshift-console.apps-crc.testing
```

ホスト名はそれぞれ

- api.crc.testing: APIサーバ
- oauth-openshift.apps-crc.testing: 認証するときにアクセスするサーバ
- console-openshift-console.apps-crc.testing: webコンソール

`oc`でCLI操作する場合も、oauthのサーバへアクセスできる必要がある。(`oc login`の際にアクセス)

入力するIPアドレスは、`crc ip`を実行すれば確認できます。

```ps1
PS C:\Users\zaki> crc ip
192.168.130.100
```

起動時は最低限これだけあれば大丈夫。
クラスタ構築後、podを作成して`oc expose`とかしていく場合、都度ホスト名を追加してください。
基本は`oc get route -A`の`HOST/PORT`のホスト名一覧を全部書いておけば良いです。(面倒だけど)

#### crc start続き

ssh鍵入れ替えとhosts設定の内容がうまいこと処理されれば、インストールが進むはずです。
全体としてはこんな感じになるはず。

```ps1
PS C:\Users\zaki> crc start --vm-driver virtualbox --bundle .\archives\crc\1.2.0\crc_virtualbox_4.2.2.crcbundle --pull-secret-file .\archives\crc\pull-secret.txt
WARN A new version (1.2.0) has been published on https://cloud.redhat.com/openshift/install/crc/installer-provisioned
INFO Checking if running as normal user
INFO Checking if oc binary is cached
INFO Loading bundle: crc_virtualbox_4.2.2.crcbundle ...
INFO Creating CodeReady Containers VM for OpenShift 4.2.8...
INFO Verifying validity of the cluster certificates ...
Please follow instructions in the documentation about setting hostnames for Virtualbox.
INFO Check internal and public DNS query ...
INFO Copying kubeconfig file to instance dir ...
INFO Adding user's pull secret and cluster ID ...
INFO Starting OpenShift cluster ... [waiting 3m]
INFO
INFO To access the cluster, first set up your environment by following 'crc oc-env' instructions
INFO Then you can access it by running 'oc login -u developer -p developer https://api.crc.testing:6443'
INFO To login as an admin, username is 'kubeadmin' and password is *****-*****-*****-*****
INFO
INFO You can now run 'crc console' and use these credentials to access the OpenShift web console
Started the OpenShift cluster
WARN The cluster might report a degraded or error state. This is expected since several operators have been disabled to lower the resource usage. For more information, please consult the documentation
PS C:\Users\zaki>
```

これで`crc console`すればブラウザでwebコンソールが起動します。
`oc`も普通に動く。

`oc login`はHyper-Vの章に書いた内容と同じく、出力にある通り`oc login -u developer -p developer https://api.crc.testing:6443`で通常ユーザでログイン、cluster-adminが必要であれば`kubeadmin`ユーザで記載されているパスワードの内容で`oc login`すればOKです。

# Tipsや制限など

## ノードOSへssh

[3.2. Getting shell access to the OpenShift cluster](https://code-ready.github.io/crc/#_getting_shell_access_to_the_openshift_cluster) より。

```console
(host os)$ oc get node
(host os)$ oc debug nodes/$(node-name)
(pod)# chroot /host
```

する。

```ps1
PS C:\Users\zaki> oc get node
NAME                 STATUS   ROLES           AGE   VERSION
crc-2n9vw-master-0   Ready    master,worker   9d    v1.14.6+6ac6aa4b0
PS C:\Users\zaki> oc debug nodes/crc-2n9vw-master-0
Starting pod/crc-2n9vw-master-0-debug ...
To use host binaries, run `chroot /host`
Pod IP: 192.168.0.52
If you don't see a command prompt, try pressing enter.
sh-4.2#
sh-4.2# chroot /host
sh-4.4# hostname
crc-2n9vw-master-0
sh-4.4#
sh-4.4# uname -a
Linux crc-2n9vw-master-0 4.18.0-147.0.3.el8_1.x86_64 #1 SMP Mon Nov 11 12:58:36 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
sh-4.4# echo $SHELL
/bin/bash
sh-4.4# cat /etc/redhat-release
Red Hat Enterprise Linux CoreOS release 4.2
sh-4.4#
```

こんな感じ。

ちなみに、`ssh`で直接入ることもできる。

1. `crc ip`でノードのIPアドレスを確認
2. ノードアクセス用のssh秘密鍵は`~/.crc/machines/crc/id_rsa`にある
3. ノードOS上のユーザ名は`core`(固定)

Vagrantのsshアクセスでゴニョゴニョしたことあれば手順はピンとくるはず。

```ps1
PS C:\Users\zaki> crc ip
192.168.0.52
PS C:\Users\zaki> ssh -i .\.crc\machines\crc\id_rsa core@192.168.0.52
Red Hat Enterprise Linux CoreOS 42.81.20191119.1
WARNING: Direct SSH access to machines is not recommended.

---
Last login: Mon Dec  2 11:51:05 2019 from 192.168.0.10
[core@crc-2n9vw-master-0 ~]$
```

> Direct SSH access to machines is not recommended

と出ているので、そのつもりで。

とはいえ、VMは起動してるのにOpenShiftクラスタは起動してない場合とか、いろいろ調査が必要な時にアクセスしてみると、OSを直で見れるので良いかも。(`ss -anpt`でLISTENしてるのか？とか)

ちなみに、VMのOSってFedora CoreOSだろうと思ってたんだけど、RHCOSなのね。

## 証明書30日制限

ドキュメントにはv1.2.0以降は自動更新とある。
しばらく様子を見よう。。

古いCodeReady Containersを使っていて証明書期限が切れてる場合は、残念ながら一度`crc delete`して再度セットアップしましょう。

---

11/27にv1.0.0-rcを起動

> 1か月半ぶりくらいに1.0.0-rcをcrc startしたら「Certs have expired, they were valid till: 28 Oct 19 10:58 +0000 」だって…

![2019-11-27_20h48_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/9d0598f4-6447-1a64-9140-0deb36740034.png)

同じく11/27にv1.0.0を起動

> Certs have expired, they were valid till: 16 Nov 19 05:02 +0000

![2019-11-27_21h01_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/0e5617a4-7b12-07f8-847f-0f07ee9fc295.png)

サーバー上のタイムスタンプを見る限り、1.0.0-rc0は9/29に、1.0.0は10/19にリリースされている。

| バージョン                      | リリース日 | expire |
| -------------------------- | ----- | ------ |
| 1.2.0-4.2.8                | 11/26 | 🎄？  |
| 1.1.0-4.2.2                | 11/1  | 11/30  |
| 1.0.0-4.2.0                | 10/19 | 11/16  |
| 1.0.0-rc.0-4.2.0-0.nightly | 9/28  | 10/28  |

証明書の30日サイクルがあるということは、次バージョンのリリース日もある程度予測できるってことなのかな。

# さいごに

何だかんだでクライアントPCはWindowsという方、それなりにいらっしゃると思います。(いるよね？)
v1.2.0の時点ではまだセットアップに苦労しますが、これからもっと簡単に使えるようになっていくと思います。
何はともあれ、WindowsでCodeReady Containersを使ったOpenShift 4デプロイ、ちょっと苦労あって環境も選びますが、手元で動かせるのは何かと便利です。

とはいえ……Dockerだってそのまま使えるし、Linux使っておくほうが無難かもしれない(あ、言っちゃった)

VirtualBoxは、、、残念ですね……

# お知らせなど

- 12/20: [OPENSHIFT.RUN 2019](https://www.openshift.run/)
- 12/9: [Japan Rook Meetup #1 - connpass](https://rook.connpass.com/event/152741/)
- [OpenShift Japan Community](https://openshift.connpass.com/)
- [meetupの動画：OpenShift Japan | crash.academy](https://crash.academy/community/openshiftjapan)
- [OpenShift Japan Community Twitter](https://twitter.com/openshiftjp)
- [Red Hat OpenShift 4 入門](https://redhat.lookbookhq.com/OCP4Intro_Mook)