/ coreos

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.

Installing to Disk

今回は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について。

Container Linux Configについて。

cloud-initについて。