macOS の VirtualBOX に CoreOS (Container Linux) をインストールする [2018年末版]

> <sub>🐒 &nbsp; 2019/03/03 追記：<br>本記事は「Qiita の諸所の記事を参考に動作確認が取れた結果をまとめたもの」でしたが、その後、調べてみたところ**動きはするものの、現在は推奨されていない方法です**。</sup>
> 
> <sup>厳密には、CoreOS のインストール時に指定する設定ファイル `cloud-config.yml` を `-c` オプションで適用する１箇所が、現在は推奨されていない方法です。それ以外は変わりません。</sup>
> 
> <sup>現在は `cloud-config.yml` はダイレクトに指定せず、`Config Transpiler` という変換ツールで YAML を JSON に変換したファイルを適用する方法が推奨されています。具体的には `cloud-config.yml` を `Config Transpiler` で `ignition.json` に変換したファイルを `-i` オプションで適用する、**２ステップ取る方法（変換→適用の手順）が推奨されています**。</sup>
> 
> - <sub>[Container Linux Config Transpiler](https://github.com/coreos/container-linux-config-transpiler) @ GitHub</sub>
> 
> <sup>**[２ステップ必要になった理由](https://github.com/coreos/container-linux-config-transpiler/blob/master/doc/overview.md#why-a-two-step-process)は、[ポカよけ](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%82%AB%E3%83%A8%E3%82%B1)と速度向上のため**です。YAML 形式は人間にやさしい（書きやすい）反面、データ処理がいささか重いという欠点があります。逆に、機械にやさしい JSON 形式の場合、人間による記述ミスや必須情報の記載漏れが多くなることがわかっているそうです。</sup>
> 
> <sup>複数のプロビジョニング（インスタンス作成）がメリットである CoreOS の場合、起動するまで記述ミスなどの問題がわからないのは大規模な環境では致命傷となりえます。</sup>
> 
> <sup>そこで、YAML -> JSON 変換プロセスを間に挟むことで事前の構文や必須項目のチェックを行い、変換後の JSON ファイルを利用することで、**全体的な速度や安定性を高めるために仕組みが変わった**そうです。どうせ変換するならバイナリ形式が一番速いのですが、「どのような設定がされているか」の確認がのちにできるように、中間を取って JSON 形式に決まったそうです。詳しくは下記の公式ドキュメントをご覧ください。</sup>
> 
>  - <sub>「[Why a two-step process?](https://github.com/coreos/container-linux-config-transpiler/blob/master/doc/overview.md#why-a-two-step-process) | Config transpiler overview」| CoreOS 公式 @ GitHub</sub>
> 
> <sup>そのため、今後 CoreOS Container Linux の継続となる **Fedore CoreOS では `ignition.json` でないと動作しなくなります**。</sup>
> 
> <sup>しかし、OS インストール時（OS をプロビジョンする時）に指定するのが `ignition.json` になるというだけです。つまり、元の設定となる `cloud-config.yml` などの **YAML 設定ファイル自体はなくなるわけではない**ので「まずは、Mac の VirtualBOX で CoreOS が動くのを確認したい」場合は、本記事でも有効ですので、ご覧ください。いずれにしろ、近々、改めて整理した記事を書きたいと思います。（書くとは言ってない</sup>
> 

### 検証環境

以下の環境で動作確認を行いました。

<details><summary>VirtualBOX v5.2, macOS HighSierra, CoreOS v1911</summary><div>

- 検証日：2018/12/25
- macOS HighSierra
    - OSX 10.13.6, MacBookPro Retina, 13-inch, Early 2015, 2.7GHz Intel Core i5, メモリ 8GB
- VirtualBOX
    - v5.2.22 r126460(Qt5.6.3)
- Container Linux by CoreOS
    -  v1911.5.0
    - ISO イメージ MD5
        - `MD5 (coreos_production_iso_image.iso) = 5e1fb24644552e06a2532fc0da693f34`

---

</div></details>

### CoreOS をインストールする際のポイント

- **メモリ割り当てを 2GB 以上**<br>古い記事では 512 MB を１GB（1,024 MB）にせよとありますが、これではメモリ不足で「`[FAILED] Failed to start Switch Root.`」エラーがでます。2,048 MB 以上にします。
- **ダウンロードした ISO イメージはインストーラーで CoreOS 本体ではない**<br>ダウンロードした ISO イメージは CoreOS 本体ではありません。CoreOS をパーティションにインストールするための専用の軽量 OS です。<br>この OS インストール用イメージから起動して、設定ファイルを作成してから `coreos-install` コマンドでストレージ（パーティション）に CoreOS をインストールします。Windows で「DOS のブートディスクで起動して Windows を入れる」ようなイメージです。
- **SSH 接続が前提**<br>CoreOS は SSH 接続を前提としているため `root` などのパスワードはデフォルトで設定されていません。後述する `cloud-config.yml` の設定ファイル内に、あらかじめ SSH ログイン情報を記述しておく必要があります。

## インストール手順

1. VirtualBOX を macOS にインストールします。（`brew cask` でインストールできます）
    - [OS X hosts](https://www.virtualbox.org/wiki/Downloads) | VirtualBox 6.0.0 platform packages @ VirtualBox 公式

    ```shell-session
    $ vboxmanage --version
    5.2.22r126460
    ```

1. Container Linux by CoreOS の ISO イメージをダウンロードします。
    - [Download Stable ISO](https://coreos.com/os/docs/latest/booting-with-iso.html) | Booting CoreOS Container Linux from an ISO | container linux @ CoreOS 公式
    - Note: これが OS インストール用仮想 CD になります。

1. VirtualBOX の「新規」から新しい仮想マシン（以下 VM）を作成します。
    - 名前：`CoreOS`（任意。CoreOS にするとタイプ名などが自動で切り替わります）
    - タイプ：`Linux`
    - バージョン：`Linux 2.6/3.x/4.x（64-bit）`（`Oracle（64-bit）` でも可）
    - メモリーサイズ：`2048MG`
    - ハードディスク：「仮想ハードディスクを作成する」
        - ファイルサイズ：`8.00GB`
        - ハードディスクのファイルタイプ：`VMDK`
        - 物理ハードディスクにあるストレージ：`可変サイズ`
1. 作成した VM に ISO イメージをマウントする。
    - VirtualBOX の左ペインに表示されている、上記で作成した新規 VM を右クリック→「設定」
    - 「ストレージ」タブを選択
    - 左側ペインの「コントローラー：IDE」で「空」になっている CD アイコンを選択
    - 右側ペインの「属性」で「光学ドライブ：IDE セカンダリーマスター」の CD アイコンをクリック
    - ISO イメージを選択
        - 一覧にない場合は「仮想光学ディスクファイルを選択...」からダウンロードした ISO イメージを選択
    - 「Live CD/DVD」にチェックを入れる
    - 「ネットワーク」タブに移動する
    - 「アダプター１」の割り当てが「NAT」であることを確認する
    - 「高度」を開き「ポートフォワーディング」を開く
        - 右側の新規ルール作成ボタン「＋」を押して、以下の設定を行う
            - 名前：Rule 1（任意）
            - プロトコル：`TCP`
            - ホスト IP：`127.0.0.1`
            - ホストポート：`22022` （任意の[未使用の空きポート](https://qiita.com/KEINOS/items/98a5ce4415b3691a0d22)）
            - ゲスト IP：`10.0.2.15`
            - ゲストポート：`22`（ウェルノウン SSH ポート）
        - ※ 上記設定で、ローカル IP（ホスト IP）の `22022` ポートにアクセスすると、ポートが転送され VM（ゲスト IP）の `22` ポートにアクセスできます。

1. VM を「起動」する
    - 作成した VM を選択し「起動」ボタンを押す
    - マウントした ISO（インストール CD）が起動し `core@localhost` プロンプトが表示されます。
1. インストール先の確認（仮想ハードディスク領域の確認）
    - `sudo fdisk -l` で `/dev/sda` デバイスがあることを確認します。
    - これが VM 上のインストール先のディスクになります。
1. インストール設定ファイル `cloud-config.yml` の用意

    これが **CoreOS の OS インストールの一番のキモ**かもしれません。

    CoreOS にはデフォルト・パスワードはないので、この `cloud-config.yml` ファイルにログイン含めた必要情報を、OS のインストール前にあらかじめ準備しておく必要があります。

    ここでは、SSH 接続のログインに公開鍵認証を使うシンプルな記述で案内します。慣れたら `cloud-config.yml` を充実させていく（[`cloud-config.yml` の記述サンプル集](https://github.com/coreos/container-linux-config-transpiler/blob/master/doc/examples.md) @ CoreOS 公式を参照する）のが良いと思います。
    - 自分の SSH 公開鍵を VM 上にダウンロードする。
        - 以下の方法がありますが、**SSH 接続用の RSA 公開鍵情報が取得できればどんな方法でも構いません**。
            1. VM からアクセスできる HTTP サーバー上に SSH 公開鍵をアップロード
                - PHP もしくは Python のビルトインサーバーを使うのが楽
            1. GitHub の自分の SSH 公開鍵使う
                - 自分の GitHub のアカウントの URL + ".keys"
                - 例: https://github.com/KEINOS.keys
                    - `curl -O https://github.com/KEINOS.keys`
            1. GitHub に最低限の記述をした cloud-config.yml のリポジトリを用意する
                - 例：https://github.com/KEINOS/CoreOS_CloudConfig
            1. 気合いと根性で[コピペピピック](https://qiitadon.com/@KEINOS/99692402654853280)する
    - ダウンロードした SSH 公開鍵を `cloud-config.yml` にリネームする。
        - `mv id_rsa.pub cloud-config.yml`
        - ダウンロードと同時にリネームするのも楽
            - `curl -o cloud-config.yml http://url/to/your/id_rsa.pub`
    - `cloud-config.yml` の設定を行う
        - vim で以下のように `cloud-config.yml` 形式の書式に書き換えます。（インデントはスペース２つなので注意）

        ```yml:cloud-config.yml
        #cloud-config
        ssh_authorized_keys:
          - ssh_rsa AAAAB3NzaC1...（以下略）
        ```
        - 他の `cloud-config.yml` の設定が必要な場合は追記します。
            - この設定でローカル（ホスト OS）から `core` ユーザーで SSH 接続できる状態になります。
        - 【追記】<br>記事冒頭の追記にあるように、新形式（`ignition` 方式）で CoreOS をインストールしたい場合は、トランスパイラ・ツール（`ct` コマンド）で事前チェックおよび JSON 形式に変換しておきます。
            - 「[Installation](https://github.com/coreos/container-linux-config-transpiler#installation) | Container Linux Config Transpiler」@ GitHub
            - 変換コマンド： `ct --in-file cloud-config.yml`
            - <font color=red>注意</font>：新しい Ignition 用の YAML ファイルは、従来の Container Linux Configs（`cloud-config.yml`）と[互換はありますが完全互換ではありません](https://github.com/coreos/container-linux-config-transpiler/blob/master/doc/overview.md#how-similar-are-container-linux-configs-and-ignition-configs)。概ね問題なさそうですが、Fedora CoreOS のリリースと共に整備されていくと思われます。

1. OS のインストール開始
    - `coreos-install` コマンドで `/dev/sda` の仮想ハードディスク領域に OS をインストールします。（設定ファイル付き ←ここがポイント）

        ```shell-session:例（従来書式）
        $ ls
        cloud-config.yml
        $ sudo coreos-install -d /dev/sda -C stable -c cloud-config.yml
        ```
    - 記事上部にある追記のように、新形式の `ingnition.json` を使う場合は、`-i` オプションで以下のようになります。

        ```shell-session:例（新書式）
        $ ls
        ignition.json
        $ sudo coreos-install -d /dev/sda -C stable -i ignition.json
        ```

1. VM をシャットダウンします。
    - VirtualBOX のメニューから、[仮想マシン] → [ACPI シャットダウン (Host+U)]

1. VM の「設定」を再度開いて、上記でマウントした ISO イメージをアンマウントします。
    - 「ストレージ」→「coreos_production_iso_image.iso」→「属性」の CD アイコンから「仮想ドライブからディスクを除去」

1. VM を起動します。
    - 下記プロンプトが出るのを確認します。

        ```
        This is localhost (Linux x86_64 4.14.84-coreos) 05:05:59
        SSH host key: SHA256:Ypx... (DSA)
        SSH host key: SHA256:JNw... (ECDSA)
        SSH host key: SHA256:yoU... (ED25519)
        SSH host key: SHA256:2Y/... (RSA)
        enp0se: <IP v4 アドレス> <IP v6 アドレス>
        
        localhost login: _
        ```
    - 先述の「ゲスト IP」で設定した IP アドレスと上記 <IP v4 アドレス> が同じであることを確認します。
    - `login:` とあるので、最初パスワードがわからずパニクりました。先述したように、そもそも `root` や `core` ユーザのパスワードは設定されていないので、ログインすることはできません。（SSH 接続後にパスワード設定した場合除く）

1. ローカル（ホスト OS）から VM に SSH 接続してみます。

- ユーザー：`core`
- IP：`127.0.0.1`（`localhost` or ホストのIP でも可）
- ポート：`22022` （上記の「ポートフォワーディング」設定で指定した「ホストポート」）

    ```shell-session
    $ ssh -p 22022 core@127.0.0.1
    The authenticity of host '[127.0.0.1]:22022 ([127.0.0.1]:22022)' can't be established.
    ECDSA key fingerprint is SHA256:dewZTgUfrqQWKkTMxxxxxxxxxxxxxxxxxxxxxxxxxxx.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '[127.0.0.1]:22022' (ECDSA) to the list of known hosts.
    Last login: Tue Dec 25 03:07:50 UTC 2018 from 10.0.2.2 on pts/0
    Container Linux by CoreOS stable (1911.5.0)
    core@localhost ~ $ 
    ```

### 「Host key verification failed」エラーが出る場合

```shell-session
$ ssh -p 22022 core@127.0.0.1
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:dewZTgUfrqQWKkTMxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Please contact your system administrator.
Add correct host key in /Volumes/xxxxxxx/Users/xxxx/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Volumes/xxxxxxx/Users/xxxx/.ssh/known_hosts:48
ECDSA host key for [127.0.0.1]:22022 has changed and you have requested strict checking.
Host key verification failed.
```

同一 IP のリモート（ゲストOS）に接続した情報が残っており、承認キーが合致しない旨のエラーです。

ローカル（ホストOS）の `~/.ssh/known_hosts` を編集して、該当する IP の行（上記エラーの場合「`[127.0.0.1]:22022 `」から始まる行）を削除して上書き保存します。

## あわせて読みたい

- cloud-config の記述の基本が知りたい
    - 「[【CoreOS】cloud-config解説〜インストール](https://qiita.com/xshsaku/items/1ba3f930ff80bef685a6)」@ Qiita

## 所感

…ということで、**Container Linux（旧 CoreOS）を macOS の VirtualBOX で動かしたい**と思うも、どうもスムーズに立ち上げられませんでした。

また、CoreOS が Container Linux に名称が変わったそうなのですが、さらに今後は Fedora CoreOS に変わるという過渡期（2018 年末現在）にあるため、ネット上の古い情報も多く、CoreOS 初心者で[検索猿人](https://qiitadon.com/@KEINOS/100581103159638457)なアチキには辛いところ。

[CoreOS 公式の VDI イメージ](https://coreos.com/os/docs/latest/booting-on-virtualbox.html)を使ってもログインできなかったり、[CoreOS の公式のインストール手順](https://coreos.com/os/docs/latest/installing-to-disk.html)を読んでも、なんかうまくインストールできず。

しかも、公式サイトをみても CoreOS なのか Container Linux なのか、ChromeOS の派生なのに RedHat CoreOS と呼ばれたり Fedora CoreOS と呼ばれたり。なんかよくわからず。

<details><summary>CoreOS と Container Linux と Fedora CoreOS の違い</summary><div>

> CoreOS = Container Linux < Fedora CoreOS
> Container Linux + Atomic Host = Fedora CoreOS（予定）

- 2018/12/25 現在、オープンソース版 CoreOS の名称は「Container Linux」ですが、**<font color=red>「Container Linux」は「Fedora CoreOS」となる</font>**予定。
- 「Container Linux」と「Fedora Atomic」の良いところ取りが、新生「Fedora CoreOS」になる予定。
- 「Container Linux」は「Fedora CoreOS」がリリースされてから[１年以内、もしくは遅くても **2020 年には終了する予定**](https://coreos.com/blog/fedora-coreos-red-hat-coreos-and-future-container-linux)。
- 今後は「Fedora CoreOS」で培ったノウハウが、企業向けの「Red Hat CoreOS」に反映されるとのこと。
- [旧 Container Linux ドキュメント](https://coreos.com/docs/)（今後は更新されず、Fedora CoreOS が最新となるそうです）
- [Fedora CoreOS 公式サイト](https://coreos.fedoraproject.org/)

</div></details>

最終的に[上記の手順](#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%89%8B%E9%A0%86)でインストールから起動まで出来たので試行錯誤した結果を整理して、**インストール手順をまとめてみました**。

一度、**無事にインストールができると漠然としていた流れが理解できた**ので、[VDI イメージ](https://coreos.com/os/docs/latest/booting-on-virtualbox.html)を使ったインストールも出来そうな気がしてきました。

## 参考文献

- [Installing CoreOS on VirtualBox](https://gist.github.com/noonat/9fc170ea0c6ddea69c58) | gist @ GitHub