小型・
サーバー版ではなくUbuntu Coreをサーバーとして使う
第646回の
Raspberry Piを
それに対してUbuntu Coreはセキュリティ上の制約からできることが限られているため普通のLinuxサーバーのように運用するとなるといろいろな壁が立ちはだかります。それでもDockerコンテナを立ち上げるならそこまで難しくありませんし、
ここではDockerとLXDのふたつを例に、
Ubuntu Coreそのものは制約が大きいためそのままでは普通のパッケージはインストールできませんし、
Ubuntu Coreの上でDockerをセットアップ
サーバー上で動かしたいサービスが出来合いのものであるのなら、
$ snap info docker name: docker summary: Docker container runtime publisher: Canonical✓ store-url: https://snapcraft.io/docker contact: https://github.com/docker-snap/docker-snap/issues?q= license: Apache-2.0 description: | Build and run container images with Docker. This build requires all files that Docker uses, such as dockerfiles, to be in $HOME. Keep files there for 'docker build', 'docker save' and 'docker load'. This snap is built by Canonical based on source code published by Docker, Inc. It is not endorsed or published by Docker, Inc. Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries. Docker, Inc. and other parties may also have trademark rights in other terms used herein. snap-id: sLCsFAO8PKM5Z0fAKNszUOX0YASjQfeZ channels: latest/stable: 19.03.11 2020-06-09 (474) 102MB - latest/candidate: 19.03.11 2020-06-09 (474) 102MB - latest/beta: 19.03.13 2020-11-18 (654) 104MB - latest/edge: 19.03.13 2020-12-19 (738) 104MB - 17.03/stable: 17.03.2-ce-1 2017-07-20 (161) 38MB - 17.03/candidate: 17.03.2-ce-1 2017-06-30 (161) 38MB - 17.03/beta: ↑ 17.03/edge: 17.03.2-ce-1 2017-06-30 (161) 38MB -
インストールは次のコマンドを実行するだけです。
$ snap install docker
ちなみにDockerのdata-root
は、/var/
」/media
」/mnt
」/media
」
外部ストレージのマウント方法は、/media/
にストレージがマウントされたものとします。なお、data-root
はDokcerを起動する上で必須といえるディレクトリです。これを外部ストレージに頼るのであれば、
[Unit] Description=External Storage for Nextcloud Before=snap.docker.dockerd.service [Mount] What=/dev/disk/by-label/EXT Where=/media/data Type=ext4 [Install] WantedBy=multi-user.target RequiredBy=snap.docker.dockerd.service
追加したのはBefore=
」RequiredBy=
」snap.
」
/media/
がマウントできるようになったら、data-root
の移行を行います。
$ sudo systemctl stop snap.docker.dockerd.service $ sudo cp -a /var/snap/docker/common/var-lib-docker/ /media/data/docker $ sudo mv /var/snap/docker/common/var-lib-docker/ ~/var-lib-docker.old $ sudo mkdir /var/snap/docker/common/var-lib-docker/ $ sudo mount --bind /media/data/docker /var/snap/docker/common/var-lib-docker $ sudo snap connect docker:removable-media $ sudo systemctl start snap.docker.dockerd.service
これで無事に/media/
以下にDockerのファイルが作られるようになるはずです。試しに適当なインスタンスを立ち上げてみましょう。
RasPi 2/3/4を32bitで起動している場合 $ sudo docker run arm32v7/hello-world RasPi 3/4を64bitで起動している場合 $ sudo docker run arm64v8/hello-world
問題なければ~/var-lib-docker.
」
$ sudo rm -rf ~/var-lib-docker.old/ $ sudo systemctl stop snap.docker.dockerd.service $ sudo umount /var/snap/docker/common/var-lib-docker
unitファイルを次の手順で作成します。
$ cat <<'EOF' | sudo tee /etc/systemd/system/var-snap-docker-common-var\\x2dlib\\x2ddocker.mount [Unit] Description=External Storage for Docker After=media-data.mount Before=snap.docker.dockerd.service [Mount] What=/media/data/docker Where=/var/snap/docker/common/var-lib-docker Options=bind [Install] WantedBy=multi-user.target [Install] WantedBy=multi-user.target RequiredBy=snap.docker.dockerd.service Requires=media-data.mount EOF
気をつけなければいけないのはハイフンの扱いです。前回の記事でも説明したように、systemd-escape
コマンドで確認できます。
$ systemd-escape -p /var/snap/docker/common/var-lib-docker var-snap-docker-common-var\x2dlib\x2ddocker
ハイフンは\x2d
」\
」\\
」var\\x2dlib\\x2ddocker.
」
前回と同様動作確認して、
$ sudo systemctl daemon-reload $ sudo systemctl start var-snap-docker-common-var\\x2dlib\\x2ddocker.mount $ sudo systemctl enable var-snap-docker-common-var\\x2dlib\\x2ddocker.mount $ sudo systemctl start snap.docker.dockerd.service
念のためシステムを再起動して、
あとは普通のDockerとして利用できます。snap版のdockerパッケージにはdocker-compose
」
snap版のDockerは
Ubuntu Coreの上でLXDをセットアップ
ここまで説明したように、
LXDはシステムコンテナにもamd64/
注意すべきなのはストレージの設定でしょう。LXDは作成するコンテナをどこに・
Raspberry PiならUSBストレージを増設しましょう。今回は単にLXDをインストールするだけでなく、/media/
」
まずはsnap版のlxdパッケージをインストールして、
$ snap install lxd --channel=4.0/stable $ sudo lxd init (中略) Do you want to configure a new storage pool? (yes/no) [default=yes]: Name of the new storage pool [default=default]: Name of the storage backend to use (lvm, ceph, btrfs, dir) [default=btrfs]: Create a new BTRFS pool? (yes/no) [default=yes]: Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: Size in GB of the new loop device (1GB minimum) [default=5GB]: 20 (後略)
上記ではストレージプールに関する部分のみを抜き出してみました。ポイントは
上記のように/var/
」
方法はいくつかあるのですが、/var/
を外部ストレージからのbind mountにしてしまうのが簡単です。
$ sudo lxc stop --all $ sudo systemctl stop snap.lxd.daemon.unix.socket $ sudo systemctl stop snap.lxd.daemon.service $ sudo cp -a /var/snap/lxd/common/lxd/disks/ /media/data/lxd $ sudo mv /var/snap/lxd/common/lxd/disks/ ~/lxd.old $ sudo mkdir /var/snap/lxd/common/lxd/disks/
前回と同様に起動時に自動的にマウントするよう、
$ cat <<'EOF' | sudo tee /etc/systemd/system/var-snap-lxd-common-lxd-disks.mount [Unit] Description=External Storage for LXD After=media-data.mount Before=snap.snap.lxd.daemon.service [Mount] What=/media/data/lxd Where=/var/snap/lxd/common/lxd/disks Options=bind [Install] WantedBy=multi-user.target [Install] WantedBy=multi-user.target RequiredBy=snap.lxd.daemon.service Requires=media-data.mount EOF
unitファイルを再読込して、
$ sudo systemctl daemon-reload $ sudo systemctl start var-snap-lxd-common-lxd-disks.mount $ sudo systemctl enable var-snap-lxd-common-lxd-disks.mount $ sudo systemctl start snap.lxd.daemon.unix.socket $ sudo systemctl start snap.lxd.daemon.service
問題なければ次のようにストレージプールの情報が表示されるはずです。
$ sudo lxc storage show default config: size: 20GB source: /var/snap/lxd/common/lxd/disks/default.img description: "" name: default driver: btrfs used_by: - /1.0/profiles/default status: Created locations: - none
最後に実際にLXDでインスタンスを作ってみます。
$ sudo lxc launch ubuntu:20.04 focal Creating focal Starting focal
ストレージプールの情報を表示すると、
$ sudo lxc storage show default config: size: 20GB source: /var/snap/lxd/common/lxd/disks/default.img description: "" name: default driver: btrfs used_by: - /1.0/images/982ae89228891ed6306876ad21d83c7c1b08d93e2f470067a890f65426a0bf9e - /1.0/instances/focal - /1.0/profiles/default status: Created locations: - none $ sudo lxc storage info default info: description: "" driver: btrfs name: default space used: 1.05GB total space: 20.00GB used by: images: - 982ae89228891ed6306876ad21d83c7c1b08d93e2f470067a890f65426a0bf9e instances: - focal profiles: - default
サーバーとして運用することを考えると、
$ sudo lxc config device add focal eth1 nic nictype=macvlan parent=eth0 $ sudo lxc exec focal ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:16:3e:59:35:3f brd ff:ff:ff:ff:ff:ff link-netnsid 0 13: eth1@if2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 00:16:3e:33:c7:2b brd ff:ff:ff:ff:ff:ff link-netnsid 0
ここで最初のコマンドの末尾にあるeth0
」wlan0
」
たとえばDHCPでeth1にIPアドレスを設定したいのであれば、
$ cat <<'EOF' | sudo lxc exec focal -- tee -a /etc/netplan/eth1.yaml network: version: 2 ethernets: eth1: dhcp4: true EOF
あとはNetplanで適用するとIPアドレスが割り当てられているはずです。
$ sudo lxc exec focal netplan apply $ sudo lxc exec focal ip addr show eth1 13: eth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:33:c7:2b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.42.0.218/24 brd 10.42.0.255 scope global dynamic eth1 valid_lft 3565sec preferred_lft 3565sec inet6 fe80::216:3eff:fe33:c72b/64 scope link valid_lft forever preferred_lft forever
ここまですればほぼ普通のUbuntuサーバーとして利用可能です。もしLXDのUbuntuインスタンスの上でDockerを動かしたい場合は、
$ sudo lxc config set focal security.nesting true $ sudo lxc restart focal
あとはUbuntuリポジトリの
$ sudo lxc exec focal apt install docker.io $ sudo lxc exec focal docker run arm64v8/hello-world
その他のLXDそのものの使い方は、
システムの自動アップデートの無効化
Ubuntu Coreは組み込み向けという扱いなので、
セキュリティの観点に立つと、
しかしながらサーバーとして使う場合は、
自動アップデートのスケジュールについての詳細はsnapパッケージのドキュメントにある
前回のアップデートと次のアップデート予定の日時は次の方法で確認可能です。
$ snap refresh --time timer: 00:00~24:00/4 last: today at 17:01 JST next: today at 22:53 JST
これを、
$ sudo snap set system refresh.hold="$(date --date=+60days +%Y-%m-%dT%H:%M:%S%:z)" $ sudo snap get system refresh.hold 2021-02-18T20:31:17+09:00
再度確認してみると、
$ snap refresh --time timer: 00:00~24:00/4 last: today at 17:01 JST hold: in 60 days, at 17:01 JST next: today at 22:53 JST (but held)
今の段階では、snap refresh
」
なお、
Ubuntu Coreをサーバーとして使用するメリット
ここまでRaspberry Pi上のUbuntu Coreを普通のUbuntuサーバー化する方法を説明してきました。それではUbuntu Coreそのものはどんな用途で採用すべきでしょうか。最後にその可能性について考えてみましょう
利便性よりもセキュリティを重視する場合
あらゆるものがネットワークに繋がる時代において、
セキュリティは利便性とのトレードオフな関係になることが多々あります。つまりよりセキュアな環境にしようと思ったら、
AppArmorの場合、
このように
さらにUbuntu Coreは、
ちなみにUbuntu Coreのサイトでは
サーバーの上で動かすものがコンテナだけである場合
Dockerの登場以降
コンテナベースで運用する場合、
Ubuntu Coreは
コンテナ化による利便性のひとつが、
つまりUbuntu Core自体は小さく作られているものの、
停電等の突然の障害時に対する耐久性がほしい場合
現代人にとって電気は空気と同じくらい重要です。空気を読むのは苦手だけれども、
商用のサーバーなら、
また、
Ubuntu Coreはシステムの基本部分を読み込み専用で用意し、
とにかく、
なお、
- Linuxサーバーの学習用途
- システムをかなり細かくカスタマイズ・
チューニングしたい - パッケージ化されていない独自バイナリ・
PPAを多用したい - DKMSを利用したい
また、
出来合いのものをそのまま使いたいもしくはカーネルのビルドから含めて全部自分でシステムを構築したい、