Fedora CoreOSのIgnitionでOSと一緒にdocker-composeのインストールもやる

ちょっとしたサービスを動かしたいとき、docker-composeを使うと環境を丸ごとバージョン管理出来てかなり便利です。

では、そのサーバ環境を手軽に準備するにはどうしたら良いかというと…Fedora CoreOSというコンテナ向けのOSを使うのが良いような気がします。

名前からなんとなく想像が付く通り、CoreOSのContainer LinuxをRedHatが買収して出来たものがFedora CoreOSだそうです。 基本的には同じ路線なのですが、RedHatらしくrktでもDockerでもなくてPodman推しだったり、etcdとかflannelが無かったりと細かい違いが色々あります。

PodmanはPodmanで楽しいのですが、今回は手軽にdocker-composeでやりたい。 というわけで、CoreOSのインストール時の初期設定を担うIgnitionファイルだけでDockerの有効化やdocker-composeのインストールをやるようにしてみました。

そもそもIgnitionでパッケージは入れられない

しょっぱなから大問題なのですが、Ignitionは冪等で宣言的をウリにしているので、シェルコマンドを書いたりは出来ません。packages的な便利ディレクティブもありません。 今年の頭くらいにシェルコマンドを書けるようにする提案が上げられていますが、2020年末時点で導入に向けた話は進んでいないみたいです。

というわけで回避方法として、systemd-firstboot的な仕組みを使うことにします。 systemdのUnitにConditionFirstBoot=yesを設定しておくと初回起動時にしか実行されなくなる、みたいなやつですね。

成功したのか失敗したのか若干分かりづらいとか、インストールの進捗がさっぱり分からないとかそういう問題はありますが、とりあえず動くので良しとしておきます。 手間を惜しまずに分かりやすさを優先するならAnsibleとか使った方が良いかも。

ともあれIgnitionファイルを作る

というわけでまずはIgnitionファイルを作ります。 このIgnitionファイルでdocker-composeをインストールするsystemd用のserviceを作って、そのserviceがdocker-composeをインストールしてくれる流れになります。

variant: fcos
version: 1.2.0

passwd:
  users:
    - name: core
      groups:
        - docker
      ssh_authorized_keys:
        - ssh-ed25519 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA your@localhost

systemd:
  units:
    - name: docker.service
      enabled: true
    - name: install-docker-compose.service
      enabled: true
      contents: |
        [Unit]
        Description=Install docker-compose on first boot
        DefaultDependencies=no
        Conflicts=shutdown.target
        After=network-online.target
        Before=shutdown.target
        ConditionFirstBoot=yes

        [Service]
        Type=oneshot
        RemainAfterExit=no
        ExecStart=/usr/bin/rpm-ostree install -r docker-compose

        [Install]
        WantedBy=network-online.target        

だいたい見たまんまです。 ポイントは以下の3点です。

  • sudoせずにdockerを使いたいので、passwd.users[].groupsで、coreユーザにdockerグループを設定している。
  • systemd.units[]docker.serviceをenabledにしてDockerが自動起動するようにしている。
  • 同じくsystemd.units[]install-docker-compose.serviceを追加して、docker-composeをインストールするようにしている。

install-docker-compose.serviceの中身は基本的には普通のサービスですが、前述したConditionFirstBoot=yesが付いているのが特徴でしょうか。 あとはなんか雰囲気で書いています。

トランスパイルしてインストールする

ここは普通にFedora CoreOSをインストールするときと同じです。

以下は別のPCでやる準備。

$ docker run -i --rm quay.io/coreos/fcct --strict <ignition.yml >ignition.json  # トランスパイルする
$ python -m http.server  # インストール対象のPCに配るためにHTTPサーバを立てる

で、以下がインストール対象のPCでインストールディスクから起動したあとでやる作業。

[core@localhost ~]$ sudo coreos-installer install /dev/sda --ignition-url http://10.0.0.1:8000/ignition.json --insecure-ignition

10.0.0.1の部分はHTTPサーバを立てているPCのIPアドレスで置き換えてください。

サーバを立てるのが面倒臭かったらUSBメモリか何かでコピーして以下の方法を使うのもアリ。

[core@localhost ~]$ sudo coreos-installer install /dev/sda --ignition-file ./path/to/ignition.json

インストールが出来たら、PCを再起動します。

docker-composeが入るのを見守る

PCが立ち上がってくると、ネットワークに繋がり次第docker-composeのインストールが始まるはずです。

この状態でSSHログインしてrpm-ostreeの様子を見てみると、おそらく以下のようになっているはず。

[core@localhost ~]$ rpm-ostree status
State: busy
Transaction: install -r docker-compose 
  Initiator: client(id:cli dbus:1.11 unit:install-docker-compose.service uid:0)
Deployments:
● ostree://fedora:fedora/x86_64/coreos/stable
                   Version: 32.20201104.3.0 (2020-11-17T10:56:39Z)
                    Commit: 318de830c2f30a97333cd43aa1d500a46ccfedcb2de70a04d0c48228944346da
              GPGSignature: Valid signature by 97A1AE57C3A2372CCA3A4ABA6C13026D12C944D0

もしもTransaction: install -r docker-composが表示されていなかったら、上手くinstall-docker-compose.serviceを起動出来ていないのかもしれません。 その場合はsystemctl status install-docker-compose.serviceなどでエラーログを見れるはずです。

ダウンロードやらインストールやらをやるのでしばらく時間が掛かりますが、それが終わると自動的に再起動が走ります。

再起動したら、ステータスが以下のようになっているはず。

[core@localhost ~]$ rpm-ostree status
State: idle
Deployments:
● ostree://fedora:fedora/x86_64/coreos/stable
                   Version: 32.20201104.3.0 (2020-11-17T10:56:39Z)
                BaseCommit: 318de830c2f30a97333cd43aa1d500a46ccfedcb2de70a04d0c48228944346da
              GPGSignature: Valid signature by 97A1AE57C3A2372CCA3A4ABA6C13026D12C944D0
           LayeredPackages: docker-compose

  ostree://fedora:fedora/x86_64/coreos/stable
                   Version: 32.20201104.3.0 (2020-11-17T10:56:39Z)
                    Commit: 318de830c2f30a97333cd43aa1d500a46ccfedcb2de70a04d0c48228944346da
              GPGSignature: Valid signature by 97A1AE57C3A2372CCA3A4ABA6C13026D12C944D0

インストール完了。 これでDockerもdocker-composeも使えるようになっているはずです。 やったぜ。