LoginSignup
1
0

More than 1 year has passed since last update.

自宅サーバー構築譚:Docker

Posted at

能書き

自宅サーバー構築譚:基本構想に基づく自宅サーバー構築、Ubuntu22.04LTSインストールその2の続きです。

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

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

目標

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

参考文献

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

スナップショット

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

sudo zfs snapshot tank/ROOT/ubuntu@$(date +%Y%m%d_%H%M%S)_before_install_Docker
sudo zfs snapshot tank/ROOT/ubuntu/var/lib/apt@$(date +%Y%m%d_%H%M%S)_before_install_Docker
sudo zfs snapshot tank/ROOT/ubuntu/var/lib/dpkg@$(date +%Y%m%d_%H%M%S)_before_install_Docker
sudo zfs snapshot tank/ROOT/ubuntu/var/lib/docker@$(date +%Y%m%d_%H%M%S)_before_install_Docker
sudo zfs snapshot tank/ROOT/ubuntu/var/lib/containerd@$(date +%Y%m%d_%H%M%S)_before_install_Docker

インストール

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
?       /etc/init.d/docker
M       /etc/ld.so.cache
?       /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/sockets.target.wants/docker.socket

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
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   19 months ago   13.3kB

綺麗に消しましょう。

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

ネットワークについて

LXD

軽くチェック

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

Xubuntuの場合、この時点でLXDコンテナはネットワークが遮断されたような挙動になります。

$ lxc start container-name
$ lxc exec container-name -- ping -c2 example.com
PING example.com (93.184.216.34) 56(84) bytes of data.

--- example.com ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1006ms

ダメだった場合の対応

※UbuntuServerの場合は前節でpingが通りますので、この節の設定は不要です。

問題は解決方法ですが。

参考文献:LXD と Docker の問題を回避する

これに従うと何やら訳のわからないエラーが。

$ iptables -I $USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables v1.8.7 (nf_tables): Couldn't load match `conntrack':No such file or directory

Try `iptables -h' or 'iptables --help' for more information.

意外と当てになりませんな公式。

こちらの参考文献に従ったら成功しました。

参考文献:LXDとDockerを同時利用するためにiptables設定を調整 - hnakamur's blog

具体的には次の2つのコマンドです。

sudo iptables -I FORWARD -o lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
sudo iptables -I FORWARD 2 -i lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT

こんな感じ。

$ lxc exec container-name -- 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=119 ms
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=52 time=117 ms

--- example.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 2561ms
rtt min/avg/max/mdev = 116.663/117.585/118.508/0.922 ms

但しこれ、起動する度に実行の必要があるとの事。それについても解決策が載っていました。ありがたや。

しかし、私の手順でインストールしていると、なぜかnftコマンドを使えません。UbuntuServerだと使えるようなので、Xubuntuだけかも知れませんが。

$ nft
-bash: nft: command not found

仕方無いのでiptablesコマンドを使った設定にしておきます。

lxd_network=lxdbr0
cat <<___ | sudo tee /etc/systemd/system/iptables-for-lxd-with-docker.service >/dev/null
[Unit]
Description=Add iptables rules for LXD coexisting with Docker
After=docker.service

[Service]
Type=oneshot
# https://discuss.linuxcontainers.org/t/lxd-and-docker-firewall-redux-how-to-deal-with-forward-policy-set-to-drop/9953/7
ExecStart=iptables -I FORWARD -o $lxd_network -m comment --comment "generated for LXD network $lxd_network" -j ACCEPT
ExecStart=iptables -I FORWARD 2 -i $lxd_network -m comment --comment "generated for LXD network $lxd_network" -j ACCEPT

[Install]
WantedBy=multi-user.target
___
sudo systemctl daemon-reload
sudo systemctl enable --now iptables-for-lxd-with-docker

これで、再起動してもLXDコンテナでネットワークがOKになります。

sudo reboot
$ lxc exec container-name -- 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=117 ms
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=52 time=118 ms

--- example.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1258ms
rtt min/avg/max/mdev = 116.933/117.549/118.166/0.616 ms

動作確認

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

lxc exec -- container-name apt install -y nginx

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

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

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

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

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

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

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

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

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

$ diff -s --label GET <(echo -en "GET /\r\n" | nc 172.16.1.3 10080) --label IN_CONTAINER <(lxc file pull container-name/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.3 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.3 20080) --label IN_CONTAINER /tmp/test.html
Files GET and IN_CONTAINER are identical

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

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

docker compose down --rmi all --volumes

仕舞い

/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"Docker with LXD setting"

今回はDockerをインストールし、LXDとDockerが同時に稼働できる事を確認しました。Xubuntuの場合はダメのようですが、対応する設定をして、そして同時に稼働できました。
やったね:thumbsup_tone1:

1
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
1
0