0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

私的サーバー構築日誌:Docker on ZFS

Last updated at Posted at 2023-08-19

能書き

私的サーバー構築日誌:仕切り直しからの自宅サーバー構築の続きです。

前回はLXDをインストールして、一通り触ってみました。今回はLXDと併存する形でDockerをインストールします。

但しDockerとの同時インストールはLXDの公式も否定的であるようです。その辺も確認します。

目標

  • Dockerでアプリケーションコンテナを起動
  • Dockerコンテナに外部からアクセス
  • LXDのシステムコンテナも同時に動く事を確認

参考文献

zfsを利用する時には/var/lib/dockerを独立したデータセットにしておいた方が、管理上、都合が良いです。

事前にLXDをインストールしている事が、今回の前提条件です。

アプリケーションコンテナDocker

スナップショット

今回のスナップショットはこんな感じです。

sudo zfs snapshot tank/root/ubuntu@$(date +%Y%m%d_%H%M%S)_before_Docker

zfs

最初にdocker用のデータセットを作ります。

sudo zfs create -o mountpoint=/var/lib/docker tank/docker

インストール

定番のapt update

sudo apt update

Dockerのaptリポジトリを追加するのに必要な道具をインストールします。

sudo apt install -y ca-certificates curl gnupg

DockerのGPG鍵を追加します。

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

リポジトリのセットアップ。

echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

そして再度apt updateです。

sudo apt update

ここでいよいよ Docker Engine のインストール!最新バージョンが良いでしょう。

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

インストールは以上となります。

docker --version

/etc

/etcはこんな風に変化しました。

$ sudo svn st /etc
?       /etc/apt/keyrings/docker.gpg
?       /etc/apt/sources.list.d/docker.list
?       /etc/bash_completion.d
?       /etc/containerd
?       /etc/default/docker
?       /etc/docker
M       /etc/group
M       /etc/gshadow
?       /etc/init.d/docker
M       /etc/ld.so.cache
?       /etc/perl
?       /etc/rc0.d/K01docker
?       /etc/rc1.d/K01docker
?       /etc/rc2.d/S01docker
?       /etc/rc3.d/S01docker
?       /etc/rc4.d/S01docker
?       /etc/rc5.d/S01docker
?       /etc/rc6.d/K01docker
?       /etc/systemd/system/multi-user.target.wants/containerd.service
?       /etc/systemd/system/multi-user.target.wants/docker.service
?       /etc/systemd/system/multi-user.target.wants/snap-core20-2015.mount
?       /etc/systemd/system/snap-core20-2015.mount
?       /etc/systemd/system/snapd.mounts.target.wants/snap-core20-2015.mount
?       /etc/systemd/system/sockets.target.wants/docker.socket
  • いつものld.so.cache、init.d関連、systemd関連。
  • perlの/etcが追加された模様です。中身を調べるとlibnetとかいう物のようです。
  • docker関連の/etc設定。
  • /etc/containerdというのがありますが、containerdとはコンテナのライフサイクルを管理する為のDockerコンポーネントの一つ、らしい。
  • /etc/bash_completion.dはbashの補完スクリプト…?何やってくれるんでしょうね。
  • keyringsとsources.list.dは、恐らく、Dockerインストールに先立って入れたキーなどでしょう。
  • dockerグループが追加されています(groupとgshadow)

Subversionで登録します。

sudo svn st /etc | grep "^?" | cut -b9- | xargs -I{} sudo find {} -type f -or -type d -or -type l | xargs -t sudo svn add
sudo svn ci /etc -m"install Docker"

ユーザーグループ

dockerグループに所属しているユーザーならば、dockerコマンド実行時にsudoは不要のようです。

sudo usermod -aG docker $USER

自分自身のグループを変更したので、反映させる為に一度ログアウトしてログインし直します。

logout

正しく動作できるかの確認は、下記を実行します。

docker run hello-world

「hello, world」の1行を表示するだけかと思ったら、何だか色々とメッセージを表示してくれますね。一瞬、エラーが発生したのかと勘違いしました。

終わった後もDockerが残っています。

$ docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
302ff60f2e92   hello-world   "/hello"   16 seconds ago   Exited (0) 15 seconds ago             gifted_wright

zfs にも痕跡が残っています。

$ zfs list -r tank/docker
NAME                                                                                USED  AVAIL     REFER  MOUNTPOINT
tank/docker                                                                         716K  1.80T      456K  /var/lib/docker
tank/docker/0212ade3da9f427cf650704111949e1f7e3a516660788ba6a65906a880649b48         64K  1.80T      116K  legacy
tank/docker/0212ade3da9f427cf650704111949e1f7e3a516660788ba6a65906a880649b48-init    88K  1.80T      116K  legacy
tank/docker/e100ba7cebe0945b77644f7cd60774da7119b74599aecad44171e2de3bd74e78        108K  1.80T      108K  legacy

綺麗に消しましょう。

docker ps -aq | xargs -rt docker rm
docker images -q | xargs -rt docker rmi

zfs上の痕跡も消えます。

$ zfs list -r tank/docker
NAME          USED  AVAIL     REFER  MOUNTPOINT
tank/docker   368K  1.80T      368K  /var/lib/docker

上手くいったので/etcを確認。

sudo svn st /etc

グループ追加の影響が出てます。

$ sudo svn st /etc
M       /etc/group
M       /etc/gshadow

いつもの手順で登録。

sudo svn st /etc | grep "^?" | cut -b9- | xargs -I{} sudo find {} -type f -or -type d -or -type l | xargs -rt sudo svn add
sudo svn ci /etc -m"set $USER's group"

ネットワークについて

LXD

軽くチェック

どうやらUbuntuServerとXubuntuとで、ネットワークの挙動が違うようです。どなたか詳しい方がいらっしゃいましたら、詳細について記事を書いて、コメントください。私はお手上げです。

Xubuntuの場合、この時点でLXDコンテナはネットワークが遮断されたような挙動になります。これについては以前の記事を参照ください。UbuntuServerでは問題無いようなので、今回は省略します。

取り敢えず、ネットワークの確認だけ。LXDコンテナ内でpingを実行してみます。

lxc launch images:ubuntu/22.04 test --device eth0,ipv4.address=192.168.0.2
lxc exec test -- ping -c2 example.com

成功します。

$ lxc launch images:ubuntu/22.04 test --device eth0,ipv4.address=192.168.0.2
Creating test
Starting test
$ lxc exec test -- ping -c2 example.com
PING example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=52 time=94.3 ms
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=52 time=110 ms

--- example.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 94.276/102.383/110.491/8.107 ms

動作確認

コンテナ内から外部へのネットワーク接続を確認できたら、ソフトをインストールしてみます。

lxc exec -- test apt install -y nginx

外部からコンテナ内への接続を定義。

  • lxdbr0は今回のLXDコンテナのブリッジネットワーク
  • 172.16.1.2はホストマシンのIPアドレス
  • 192.168.0.2はLXDコンテナのIPアドレス

前回の続きでlxdbr0の設定が残っていたら、このcreateは飛ばして次のport addだけ実行してください。

lxc network forward create lxdbr0 172.16.1.2
lxc network forward port add lxdbr0 172.16.1.2 tcp 10080 192.168.0.2 80

ここで……
食らえ!HTTP/0.9!

echo -en "GET /\r\n" | nc 172.16.1.2 10080

なぜ化石のような規格のHTTP/0.9を使うかと言いますとですね。レスポンスにヘッダが付かないというメリットがあるんですね。
だからこんな荒技も出来るんです。

diff -s --label GET <(echo -en "GET /\r\n" | nc 172.16.1.2 10080) --label IN_CONTAINER <(lxc file pull test/var/www/html/index.nginx-debian.html -)

実行結果はこうなります。

$ diff -s --label GET <(echo -en "GET /\r\n" | nc 172.16.1.2 10080) --label IN_CONTAINER <(lxc file pull test/var/www/html/index.nginx-debian.html -)
Files GET and IN_CONTAINER are identical

美しい……

以上でLXDの方は動作確認できました。

Docker

今度はDockerです。

まず設定ファイルdocker-compose.ymlを準備。難しい事はしないのでDockerfileは要りません。

mkdir ~/nginx
cd ~/nginx
cat >docker-compose.yml <<___
version: '3'
services:
  nginx:
    image: nginx:latest
    build: .
    ports:
      - "20080:80"
___

バックグラウンドで起動します。

docker compose up -d

今度もHTTP/0.9でアクセスしますが……

今回は、docker compose cpコマンドで出力にハイフン - を指定する(これは標準出力を表す)と、良く分からないデータを頭にくっつけやがる(そして抑制できない)という謎仕様の為、1行に纏める事が出来ませんでした。
なぜかプロセス置換もエラーになってしまってダメです。

仕方が無いので/tmpに一時ファイルを作成しました。

docker compose cp nginx:/usr/share/nginx/html/index.html /tmp/test.html >&/dev/null
diff -s --label GET <(echo -en "GET /\r\n" | nc 172.16.1.2 20080) --label IN_CONTAINER /tmp/test.html

実行結果。

$ docker compose cp nginx:/usr/share/nginx/html/index.html /tmp/test.html >&/dev/null
$ diff -s --label GET <(echo -en "GET /\r\n" | nc 172.16.1.2 20080) --label IN_CONTAINER /tmp/test.html
Files GET and IN_CONTAINER are identical

ま、とにかく、Dockerコンテナがちゃんと動いている事は間違い無いようです。

確認が終わったら、綺麗に消しましょう。

docker compose down --rmi all --volumes
cd ..
rm -r nginx

仕舞い

今回はDockerをインストールし、LXDとDockerが同時に稼働できる事を確認しました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?