弊社の技術資料やコラム等を公開しています。
内容に誤りや、社会通念上不適切な点があることが考えられますが、弊社では本サイトの情報の使用により生じたいかなる損害も責任を負いかねますことをご了承ください。
KVMとDockerの両方が入った環境の構築
初出:2019-06-17 00:00:00
更新:2019-08-02 00:00:00
- 2019/08/01~2019/08/02: Open vSwitchセットアップ手順を修正
KVMとDockerの両方が使える環境を構築します。
仮想環境用ストレージ用ディスクはZFS mirrorで冗長化します。
仮想ネットワークスイッチとしてOpen vSwitchを使います。
ZFSやOpen vSwitchを入れなくてもシステムとしては成立します。ここでこれらを使うのは筆者が慣れているからという理由だけです。
OSはDebianを使用します。
LinuxでZFSというとUbuntuが一番とっつきやすいのですが、Ubuntuのやつは配布形態がライセンス的に問題があるかもしれないのでここではDebianのシステム上でソースコードからコンパイルして使う方式をとります。こうすることでライセンスの問題が生じないらしいです。
いちいち手動でコンパイルするのも面倒なので、必要時に自動でコンパイルしてくれるDKMSという仕組みを使います。
構成
- ハードウェア
- CPU: Intel Core i7
- メモリ: 32GB
- ディスク
- 500GB HDD x1(システム用)
- 2TB HDD x2(仮想環境とユーザーデータ用。ミラーして使用する)
- ソフトウェア
- OS: Debian 10 (Buster)
- KVM
- Docker
- ZFS - zfs-dkmsを使用
手順概略
セットアップ
Debianのインストール
- システムディスクの構成は適当に。ここでは”Use entire disk”を使用した。
- taskselで入れるのは標準システムツール(Standard)とSSH serverのみ。
ネットワーク(IPアドレス、ホスト名)の設定
1
2
3
4
5/etc/hostname
# インストール直後はDHCPを使う設定になっているので固定IPに変えるのだが、
# どっちみちOpen vSwitchの設定のところで変えるので、今すぐここでしなくてもよい。
/etc/network/interfaces
/etc/hostsZFSストレージの設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135# 以下全部rootで実施
vi /etc/apt/sources.list
---
# cdromへの参照はコメントアウトしておく
# 以下のような記載のある場所の最後に"contrib"を追加
deb http://ftp.jp.debian.org/debian/ buster main contrib
deb-src http://ftp.jp.debian.org/debian/ buster main contrib
---
apt update
apt install zfs-dkms
# LinuxとZFSのライセンスの互換性についての注意書きが出るので、OKを押して続行し、インストールを完了させる。
# 途中でZFS等のビルド処理が入るので、少し(数分~数十分)時間がかかる。
# 何やら失敗しているように見える
---
Errors were encountered while processing:
zfs-dkms
zfs-zed
zfsutils-linux
---
# しかし、dkms statusで見ると、zfsは"installed"になっているので、一応ビルドはできているようだ。
dkms status
---
spl, 0.7.12, 4.19.0-5-amd64, x86_64: installed
zfs, 0.7.12, 4.19.0-5-amd64, x86_64: installed
---
# zfs-zedだけもう一度インストールしなおす。今度はうまく入った。
# zfs-dkmsとzfsutils-linuxも同じようにやったが、これらは最新のものが入っている旨のメッセージが出るので多分大丈夫。
apt install zfs-zed
# ZFSドライバの読み込み
modprobe zfs
# ZFSボリュームを作成するディスクの確認
# どのディスクを使うかを確認。ここでは/dev/sdaと/dev/sdcだったとする。
fdisk -l
# 使うディスクのデバイス名を確認
ls /dev/disk/by-id | grep sda
---
lrwxrwxrwx 1 root root 9 Jun 15 16:12 ata-ST2000DM001-1CH164_Z1E333WG -> ../../sda
lrwxrwxrwx 1 root root 10 Jun 15 16:12 ata-ST2000DM001-1CH164_Z1E333WG-part1 -> ../../sda1
lrwxrwxrwx 1 root root 9 Jun 15 16:12 wwn-0x5000c5004fe6831d -> ../../sda
lrwxrwxrwx 1 root root 10 Jun 15 16:12 wwn-0x5000c5004fe6831d-part1 -> ../../sda1
---
# "ata-ST2000DM001-1CH164_Z1E333WG"をメモ
ls /dev/disk/by-id | grep sdc
---
lrwxrwxrwx 1 root root 9 Jun 15 16:12 ata-Hitachi_HUA722020ALA330_JK11A4B8H1YUPW -> ../../sdc
lrwxrwxrwx 1 root root 10 Jun 15 16:12 ata-Hitachi_HUA722020ALA330_JK11A4B8H1YUPW-part1 -> ../../sdc1
lrwxrwxrwx 1 root root 9 Jun 15 16:12 wwn-0x5000cca222cefbd9 -> ../../sdc
lrwxrwxrwx 1 root root 10 Jun 15 16:12 wwn-0x5000cca222cefbd9-part1 -> ../../sdc1
---
# "ata-Hitachi_HUA722020ALA330_JK11A4B8H1YUPW"をメモ
# ZFSボリュームの作成。今回はディスクが使いまわしですでにパーティションが切ってあるので、強制作成させるために-fオプションをつけた。
# sdaとかsdbとかをデバイスの指定に使うと、再起動した時に名前が変わってしまってZFSボリュームが読み込めない場合があるのでやめた方がいい。
zpool create -f pool1 mirror ata-ST2000DM001-1CH164_Z1E333WG ata-Hitachi_HUA722020ALA330_JK11A4B8H1YUPW
# 確認
zpool list
---
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
pool1 1.81T 924K 1.81T - 0% 0% 1.00x ONLINE -
---
zpool status
---
pool: pool1
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
pool1 ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-ST2000DM001-1CH164_Z1E333WG ONLINE 0 0 0
ata-Hitachi_HUA722020ALA330_JK11A4B8H1YUPW ONLINE 0 0 0
errors: No known data errors
---
# ファイルシステムの作成。Windows共有とNFS共有の両方をさせるつもりなので、それ相応のオプションをつける。圧縮もonにしておく
# VM用
zfs create -o nbmand=on -o casesensitivity=mixed -o aclinherit=passthrough -o utf8only=on -o compression=on pool1/vm
# Docker用
zfs create -o nbmand=on -o casesensitivity=mixed -o aclinherit=passthrough -o utf8only=on -o compression=on pool1/dc
# その他用
zfs create -o nbmand=on -o casesensitivity=mixed -o aclinherit=passthrough -o utf8only=on -o compression=on pool1/stor
# 確認
zfs list
---
NAME USED AVAIL REFER MOUNTPOINT
pool1 560K 1.76T 104K /pool1
pool1/stor 96K 1.76T 96K /pool1/stor
pool1/vm 96K 1.76T 96K /pool1/vm
---
# NFSとSMB共有の設定
# NFS、SMBサーバーのインストール
# Solaris系のOSだとこういう手順は普通は踏まないと思うが、ZFS On LinuxだとNFSサーバーやSambaのインストールが必要となる。
apt install nfs-kernel-server samba
# SMBユーザーの追加
# Unixグループの追加
groupadd -u [GID] [名前]
# Unixユーザーの追加
useradd -u [UID] -g [GID] [名前]
# SMBユーザーの追加(パスワード設定)
pdbedit -a [名前]
# NFSの有効化。ここでは192.168.0.0/24のネットワーク上のクライアントからのアクセスには読み書き許可をしている。また、root squashをオフした。
# Solaris系だと"root=@192.168.0.0/24"のような指定ができるが、ZOL(というか、LinuxのカーネルNFSサーバー?)ではできないようだ。
zfs set sharenfs="rw=@192.168.0.0/24,no_root_squash" pool1/vm
zfs set sharenfs="rw=@192.168.0.0/24,no_root_squash" pool1/dc
zfs set sharenfs="rw=@192.168.0.0/24,no_root_squash" pool1/stor
# SMBの有効化。共有名は\[プール名\]_\[ファイルシステム名\]となる(例:pool1_vm)。
# Solaris系のようにsharesmb=name=[共有名]は今のところできないようだ。
zfs set sharesmb=on pool1/vm
zfs set sharesmb=on pool1/dc
zfs set sharesmb=on pool1/stor
# 作成したユーザーを、上記ファイルシステムの所有者にする
chown [ユーザー名]:[グループ名] /pool1/vm
chown [ユーザー名]:[グループ名] /pool1/dc
chown [ユーザー名]:[グループ名] /pool1/stor
# 所有者ユーザーとグループが読み書き、その他が読みのみできるようにする
chmod 775 /pool1/vm
chmod 775 /pool1/dc
chmod 775 /pool1/storOpen vSwitchのセットアップ(2019/08/02更新)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# インストール
apt install openvswitch-common openvswitch-switch
# ネットワーク設定。メインで使用するネットワークポート上に仮想ブリッジ(snnbr)を作成することにする
vi /etc/network/interfaces
---
allow-ovs snnbr0
iface snnbr0 inet static
address 192.168.0.10
netmask 255.255.255.0
gateway 192.168.0.1
dns-nameservers 192.168.0.1
ovs_type OVSBridge
ovs_ports enp0s25
allow-snnbr0 enp0s25
iface enp0s25 inet manual
ovs_bridge snnbr0
ovs_type OVSPort
---
# ブリッジの作成
ovs-vsctl add-br snnbr0
ovs-vsctl add-port snnbr0 ensp0s25
# 再起動してブリッジが有効になっているかどうか確認
rebootKVMのセットアップ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26# インストール。virtinstとqemu-utilsは使い方によっては不要かも
# bridge-utilsを入れてないことに注意(Open vSwitchを使うため)
apt install qemu-kvm libvirt-clients libvirt-daemon-system virtinst qemu-utils
# 一旦rebootする
reboot
# テスト用に適当にVMを一つ作ってみる。ここではシリアルコンソールを使ってインストールしている。
virt-install \
--virt-type kvm \
--name test \
--memory 1024 \
--location /pool1/stor/iso/debian.iso \
--disk /pool1/vm/test.qcow2,format=qcow2,size=16,bus=virtio,cache=writeback \
--os-type=linux \
--os-variant=debian9 \
--network bridge=snnbr0,model=virtio,virtualport_type=openvswitch \
--graphics none \
--extra-args 'console=tty0 console=ttyS0,115200n8 serial'
# インストールが開始されると自動的にVMのシリアルコンソールに接続される。
# 抜けるときはCtrl+^ -> Ctrl+]、入るときはvirsh console [vm名]
# インストール後にネットワーク接続が確認できたらシャットダウンする。
# その後後始末
virsh undefine test
rm /pool1/vm/test.qcow2Dockerのセットアップ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
# 確認
apt-key fingerprint 0EBFCD88
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
apt update
apt install docker-ce docker-ce-cli containerd.io
systemctl enable docker
# 確認
docker run --rm -it alpine
# Alpine Linuxのシェルに入るので、pingでネットワーク疎通を確認後にexit
# root以外でもdockerが使えるようにする
usermod -aG docker [ユーザー名]
# DockerのコンテナでOpen vSwitchを使えるようにする
# ツールのダウンロード
wget -O /usr/local/bin/ovs-docker https://raw.githubusercontent.com/openvswitch/ovs/master/utilities/ovs-docker
chmod 755 /usr/local/bin/ovs-docker
# テスト
docker run --rm -it --name testcnt --net none alpine ash
# Ctrl+P -> Ctrl+Qで一旦シェルから抜ける
# Open vSwitchのポートをDockerコンテナに割り当て
ovs-docker add-port snnbr0 enp5s0 testcnt --ipaddress=192.168.0.202/24 --gateway 192.168.0.1
# 再度Dockerコンテナのシェルに入る
docker attach testcnt
# (以下コンテナのシェル内)
ip addr
---
enp5s0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
link/ether ...
inet 192.168.0.202/24 scope global enp5s0
valid_lft forever preferred_lft forever
---
ping www.google.com
exit
# (以下コンテナ外)
# コンテナが無くなってもポートの設定が残ってしまうようなので、手動で削除
ovs-docker del-ports snnbr0 testcnt
# Dockerのmacvlanネットワークを試す
# macvlanネットワークの作成。parentにはOpen vSwitchのブリッジを指定
docker network create -d macvlan -o macvlan_mode=bridge --subnet=192.168.0.0/24 --gateway=192.168.0.1 -o parent=snnbr0 snnnw
# macvlanネットワークを使用してコンテナを起動
docker run --rm -it --name testcnt --net snnnw --ip=192.168.0.202 alpine ash
# (以下コンテナ内)
# 問題なく接続できているように見える
ip addr
ping www.google.com
exit
# (以下コンテナ外)
# DockerのbridgeとOpen vSwitchはかち合わないのだろうかとか
# macvlanのparentにOpen vSwitchのブリッジを指定していいのだろうかとか
# 色々よく分からない点は多いが、とにかくつながったので細かいことは後でよく考える。
# 使い勝手としてはmacvlanでつなぐのがあまり面倒はなさそう。
# ただし、macvlanの制限上、コンテナからDockerホストにはネットワーク接続できないので注意。