貧弱な自宅サーバをコンテナが最低限稼働するサーバに変えたいと思います。余計なものを入れないために Fedora Server から Fedroa Core OS に変えたいと思います。また合わせて Podman のコンテナを IPv6 に対応します。
Fedora Core OS
自宅サーバは Shuttle DS57U と DS77U の 2 台に仮想サーバ、KVM+oVirt で運用していました。サーバスーペックが低いために、昨年仮想サーバはやめて、Fedora Server 上にコンテナをたてて運用していました。今回、さらに余計なものを排除しようと思い、コンテナサーバ専用に Fedora Core OS に変えたいと思います。
Installing CoreOS on Bare Metalを参考にインストールを進めます。まずFedora CoreOS のダウンロードページから Bare Metal の ISO ファイルをダウンロードして USB に焼き付けます。USB の作成方法はこちらを参考にしてみてください。環境は Mac です。
USB でリブートする前に、ignition ファイルを作ります。このファイルは、USB でリブートした後に利用します。またこのファイルの読み込み方法はいくつかあるようですが、今回は http 経由で ignition ファイルを変えながらテストしたいと思います。
sudo coreos-installer install /dev/sda \ --ignition-url https://example.com/example.ign
Ignition ファイルの作成
Ignition ファイルはProvisioning and Configurationを参考に yaml 形式で作成します。最初は複雑なことはしないで最低限のものだけ定義してインストールしたいと思います。設定は、variant とバージョン、そして ssh でアクセスするためのキーを設定するだけです。ハードディスクやネットワークなどは何も指定しないでやってみたいと思います。
variant: fcos
version: 1.2.0
passwd:
users:
- name: core
ssh_authorized_keys:
- ssh-rsa xxxxxxxxx aaa@bbb
次に、fcct を使って yaml 形式を json 形式に変換します。別のコンテナサーバ上で podman で作成します。ただこの程度ならば直接 json ファイル作成できるレベルですけど。
podman run -i --rm quay.io/coreos/fcct:release --pretty --strict < default.fcc > default.ign
あとはこの default.ign ファイルを適当な http サーバに配置します。私はコンテナでたてていた web サーバに仕込みました。
いくつかテストしようかと思うので、Visual Studio Code で ignition ファイルを作成したらあとは自動で deploy させてます。VSC - git - gitlab - ci/cd json 変換 + web サーバ登録。いくつかファイル作って ignition ファイルをアップしておきました。
あとは、USB を入れてリブートしてコンソール入力待ちになったら、coreos-installer コマンドでインストールをしていきます。インストール先のディスクと ingnition ファイルを置いている URL を指定するだけです。なお、インストール先のディスクはフォーマットしていなかったので、リブートしたあと fdisk でパーティションを消してから以下のコマンドを入れました。
sudo coreos-installer install /dev/sda --ignition-url https://www.xxxx.xxxx/default.ign
途中何も入力する必要がなくインストールも数分であっけなく終わりました。インストール後はリモートから ssh でしかアクセスできませんので ssh core ユーザでサーバにアクセスしてみます。私は、ルータ側で MAC アドレスをキーに固定 IP にしていたので特に迷いませんでしたが、そうでないときは、起動した時に ip アドレスが表示されますのでそれを確認すればいいと思います。ただししばらくするとメッセージが流れて来るので消えないうちに確認してください。hostnamectl で確認すると Kernel は 5.9 でした。Fedora はやはり早いですね。
Static hostname: xxxxxxx
Icon name: computer-laptop
Chassis: laptop
Machine ID: yyyyyyyyyyyyyyyy
Boot ID: zzzzzzzzzzzzzzzz
Operating System: Fedora CoreOS 33.20210104.2.0
CPE OS Name: cpe:/o:fedoraproject:fedora:33
Kernel: Linux 5.9.16-200.fc33.x86_64
Architecture: x86-64
Fedora CoreOS のインストール ダイジェスト
- CoreOSをダウンロードする。
- ダウンロードした iso ファイルを USB に焼く (Mac 版)
hdiutil convert -format UDRW -o fedora-coreos-xx.x86_64.img fedora-coreos-xx.x86_64.img
mv fedora-coreos-xx.x86_64.img.dmg fedora-coreos-xx.x86_64.img
sudo dd if=fedora-coreos-xx.x86_64.img of=/dev/rdiskX bs=1m - ignition ファイルを作成する。(Yaml)
- ignition ファイルを Json ファイルに変換する。
podman run -i —rm quay.io/coreos/fcct:release —pretty —strict < default.fcc > default.ign - ignition ファイルを web サーバに配置する。
- USB を挿入しリブートする。
- Fedora CoreOS をインストールする。
sudo coreos-installer install /dev/sda —ignition-url https ://www.xxxx.xxxx/default.ign - クライアント PC から ssh で接続する。
ssh core@xxxx
以上で終了です。
おまけ コンテナの IPv6 対応
このプログは、IPv6、IPv4 どちらで接続しているか nginx で判断しています。今までホストサーバの nginx を利用していましたが、今回こちらもコンテナに変えました。しかしテストしてみると IPv6 からの通信もコンテナ上では同じローカルの IPv4 となっていたため、今回コンテナ の IPv6 対応も合わせて行いました。その時の tip も記載しておきます。
podman のディフォルトは IPv6 になっていないようです。またコンテナ上の nginx では$remote_addr が 全て 127.0.0.1 となってしまいます。接続先の IP アドレレスを取るためには、rootful コンテナにしないとダメなようです。rootless コンテナにできないのは残念。またコンテナの IPv6 対応は network の設定に手を加えることになりますが、確か手動で/etc/cni/net.d/87-podman-bridge.conflist のファイルをいじったり、 iptables を修正したり、あるいは podman run -published で[::]:443 みたいにしていたと記憶しています。今回試行錯誤していたのですが、改めて network のヘルプをみていたら IPv6 の指定がありました。設定してみるとあっさり IPv6 通信が可能となりました。また iptables も適切に設定されていました。Fedora CoreOS よりもこちの設定に時間をとってしまいました。ドキュメントを最初からよくみればよかったですね。
今回は、グローバルな IPv6 ではなく、ユニークローカルユニキャストアドレス(ULA)で行いました。ULA は、こちらで MAC アドレス+timestamps でアドレスを決めました。
【rootful】新規にネットワークを作成してPodに設定した例
podman network create --ipv6 --subnet fdxx:xxxx:xxxx::/64 ネット名
podman pod create --name ポッド名 --net=ネット名 -p 443:52101 -p [::]:443:52101
podman run -dt --pod ポッド名 --name コンテナ名 ・・・
podman pod start ポッド名
ERRO[0000] Error adding network: failed to allocate for range 0: ・・・・, duplicate allocation is not allowed
この時は、/var/lib/cni/networks/ネットワーク名フォルダにある ip ファイルを削除すれば起動できるようになると思います。 pod の stop 処理をしないでリブートしたのが原因かなと想像してます。systemd で pod の起動、停止するようにした方がいいと思います。
systemd の作り方はこちらを参考にしてください。
podman generate systemd --files --name ポッド名
root ユーザで作成すると/etc/systemd/system/フォルダ内に該当する
pod-ポッド名(インフラのコンテナ)と pod に含まれるコンテナが自動でファイルが作成されます。
systemctl start pod-ポッド名 で起動できます。