Install Container Linux to disk(What is Ignition?)
CoreOS社のLinuxディストリビューションであるCoreOSが、Container Linuxに名称変更しましたね(もう1年経つのか…)。
今回Container LinuxをISOイメージからディスク(VMware)へインストールする機会があったのでやり方をメモします。以前とやりかたが変わっていたので。 😮
インストール方法
ISOイメージでブート後、coreosユーザでログインされるのでrootユーザに切り替えて以下のコマンドを実行することでディスクへインストール出来ます。
- インストールするディスクのデバイスファイルを指定
- stable版を選択
sudo su - root
coreos-install -d /dev/sda -C stable
さて、上の例ではインストールはされるものの、ユーザのパスワードもsshの公開鍵も設定されていないので、起動後にログインすることが出来ません。
Container Linuxはプロビジョニングユーティリティを使用して初期設定を行うことができるので、これを利用します。
対応しているプロビジョニングユーティリティはcloud-initとignitionです。オプションで指定できます。cloud-initと言っても本家をContainer Linux用に改造したcoreos-cloudinitのようです。
-c CLOUD Insert a cloud-init config to be executed on boot.
-i IGNITION Insert an Ignition config to be executed on boot.
今回はignitionを利用してみます。
Ignitionとは
ignitionとはContainer Linux用に設計されたプロビジョニングユーティリティです。よく見かけるのはcloud-initですよね。AWSとかでYAMLで書くアレ。何が違うのでしょうか。
Ignitionがリリースされた際の記事を見てみると、まずcloudinitの課題が書かれていました。
- cloudinitは設定を書くためにYAMLに似た言語が使われている(cloud-config)
- YAMLとの小さな違いとして、cloud-configは行頭にcloud-configであることを示すためのコメント行が必要である
- 多くの言語にはYAMLを解析するライブラリがあるが、cloud-configを解析するライブラリは無い
- この結果、プログラムでcloud-configを作成する際に先頭のコメント行が取り除かれてしまったり、8進数のファイルパーミッションが10進数に変換されてしまったりする現象が起きる
- そしてディスク上に無効なファイルパーミッションが設定されてしまったりするなどの問題が起きる
- また、cloudinitはブートプロセスの後半で実行されるため、初期のシステムサービス、特にネットワーキングを適切に設定することが困難
Ignitionはこの問題を解決するために作成されたようです。
- YAMLベースのcloud-configではなく、純粋なjsonを利用する
- ブートプロセスの後半ではなく、前半に発動する
- 前半とは具体的にはSystemd(PID=1)が起動する前、ストレージがマウントされる前
- つまりSystemdが起動する前にファイルシステムの再フォーマットやRAIDアレイの作成、ネットワークの設定を行うことができる
- これによりSystemdがより適切に動作することができる
- また、coreos-cloudinitと異なり、Ignitionは初回の起動時にのみ実行される(再起動するたびに元の設定で上書きされることが無い)
ignition.jsonの作成方法
ignition.jsonの例は以下。
ですが、jsonを手で書くのは非常に辛いので既存のcloud-configを変換するツールがあります。
以下のように使います。
ct < cloud-config.yaml
するとjsonが吐かれるのでこれをそのまま使います。
coreos-install -d /dev/sda -C stable -i ignition.json
ignition.jsonとcoreos-cloudinitのバリデータもあります。
container-linux-config-transpilerについては以下で使い方が説明されています。
cloud-configの書き方は以下のドキュメントをつらつら眺めていました。
作成したcloud-config.yamlとignition.json
今回はこんな感じで最小限の設定をやってみました。公開鍵の登録、ネットワークの設定、Dockerの自動起動の設定。
-
cloud-config.yaml
passwd: users: - name: core ssh_authorized_keys: - ssh-rsa XXXXXXXX networkd: units: - name: ens32.network contents: | [Match] Name=ens32 [Network] DNS=8.8.8.8 Address=192.168.1.100/24 Gateway=192.168.1.1 systemd: units: - name: docker.service enable: true
-
ignition.json
{"ignition":{"config":{},"timeouts":{},"version":"2.1.0"},"networkd":{"units":[{"contents":"[Match]\nName=ens32\n\n[Network]\nDNS=8.8.8.8\nAddress=192.168.1.100/24\nGateway=192.168.1.1\n","name":"ens32.network"}]},"passwd":{"users":[{"name":"core","sshAuthorizedKeys":["ssh-rsa XXXXXXXX"]}]},"storage":{},"systemd":{"units":[{"enable":true,"name":"docker.service"}]}}
感想
ブート時にIgnitionやcloudinitが実行されるという部分についてもう少し詳しく知りたいと思った。どんな感じで実行されるのかいまいち実感出来てない…。
ignition.jsonは最初手で作っていて辛すぎました。もっと目立つところにcontainer-linux-config-transpilerについて書いてほぴい。 😂
cloud-init, coreos-cloudinit, cloud-config, metadata, userdataとか概念が多くて難しい…。AWSとかDigitalocean固有の言葉なのか一般的な話なのか分かり辛い印象…。
参考リンク
インストール方法について。
ignitionについて。
- What Is Ignition?
- Introducing Ignition: The new CoreOS machine provisioning utility | CoreOS
- Provisioning
Container Linux Configについて。
cloud-initについて。