これは、なにをしたくて書いたもの?
自分はUbuntu Linux上でVagrantを使っていて、VagrantのProviderにはvagrant-libvirtを使っています。
Providers | Vagrant by HashiCorp
GitHub - vagrant-libvirt/vagrant-libvirt: Vagrant provider for libvirt.
Synced Foldersについてはあまり使っていなかったので困っていなかったのですが、ちょっと使いたいことが出てきたので
調べてみることにしました。
実は以前に軽く見ているのですが、その時はさらっと流してしまったんですよね。
vagrant-libvirtを使って仮想マシンを起動した時に、NFSが使えない場合にエラーになるのを回避する - CLOVER🍀
vagrant-libvirtとSynced Folders
vagrant-libvirtの、「Synced Folders」に関する記述を見てみます。
以下の3つの方法が使えるようです。
このうち、NFSはホスト側のサポートが必要になるので、ちょっと面倒…パスしたいです。
すると、9pかrsyncということになります。
vagrant-libvirtでホストとゲストの双方向のフォルダ同期が可能なのは、NFSと9pです。rsyncの場合は、起動時にホスト側から
ゲスト側に1度だけ同期されるものになります。
つまり、rsyncを選んだ場合は、ゲストOSの起動後に同期対象のフォルダをホスト側で変更しても、ゲスト側には反映されない
ということになります。実際、そうなります。
では、ちょっと試してみましょう。
環境。
$ vagrant --version Vagrant 2.2.9 $ vagrant plugin list vagrant-libvirt (0.0.45, global) - Version Constraint: > 0 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.1 LTS Release: 20.04 Codename: focal $ uname -srvmpio Linux 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
まずは仮想マシンを作成しておきます。
$ vagrant init generic/ubuntu2004
rsync
まずは、rsyncを使ってみます。
Vagrantfileに、以下を追加します。
config.vm.synced_folder "./", "/vagrant", type: "rsync"
コメントアウトされているSynced Foldersの定義があるので、このあたりに追加するのがいいでしょう。
# Share an additional folder to the guest VM. The first argument is # the path on the host to the actual folder. The second argument is # the path on the guest to mount the folder. And the optional third # argument is a set of non-required options. # config.vm.synced_folder "../data", "/vagrant_data"
起動。
$ vagrant up
最後に、こんなメッセージが表示されます。
==> default: Rsyncing folder: /path/to/ => /vagrant
仮想マシンに入ってみましょう。
$ vagrant ssh
今回の設定では、「/vagrant」ディレクトリにSynced Folderで設定したディレクトリの中身が見えています。
$ ll /vagrant total 12 drwxrwxr-x 2 vagrant vagrant 4096 Sep 10 08:50 ./ drwxr-xr-x 20 root root 4096 Sep 10 08:51 ../ -rw-rw-r-- 1 vagrant vagrant 3082 Sep 10 08:49 Vagrantfile
ここで、ホスト側で同期対象のディレクトリ上でファイルを作成してみます。
$ echo 'Hello World' > test.txt
ゲスト側には、反映されません。
$ ll /vagrant total 12 drwxrwxr-x 2 vagrant vagrant 4096 Sep 10 08:50 ./ drwxr-xr-x 20 root root 4096 Sep 10 08:51 ../ -rw-rw-r-- 1 vagrant vagrant 3082 Sep 10 08:49 Vagrantfile
これを反映させたかったら、以下を実行。
$ vagrant reload
単純なOS再起動(「sudo reboot」など)ではダメです。
そもそも、ファイルシステムとしてマウントされているわけでもないですからね。
$ df -hT Filesystem Type Size Used Avail Use% Mounted on udev devtmpfs 951M 0 951M 0% /dev tmpfs tmpfs 199M 664K 199M 1% /run /dev/vda3 ext4 124G 2.1G 115G 2% / tmpfs tmpfs 994M 0 994M 0% /dev/shm tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs tmpfs 994M 0 994M 0% /sys/fs/cgroup /dev/vda1 ext4 456M 102M 321M 25% /boot tmpfs tmpfs 199M 0 199M 0% /run/user/1000
9p(Plan 9 Filesystem Protocol)
続いては、9pです。
これは、KVM環境でのVirFS(準仮想ファイルシステム)として機能します。
9p自体は、こちらを参照。
9pを使ったファイルシステムを使うには、ゲスト側のサポートが必要になります。よって、利用できない状況もあるかも
しれません。
vagrant-libvirtのドキュメントでは、以下のどちらかを使え、と書いてあります。
config.vm.synced_folder './', '/vagrant', type: '9p', disabled: false, accessmode: "squash", owner: "1000" # or config.vm.synced_folder './', '/vagrant', type: '9p', disabled: false, accessmode: "mapped", mount: false
違いはなんでしょう?
まず「mount: false」となっている場合は、起動時にマウントが行われません。
ownerは、文字通り所有者のuidを記述しています。1000は、vagrantユーザーのuidです。
accessmodeとは?
こちらを見るのが良さそうです。
21.16.2. ファイルシステム Red Hat Enterprise Linux 6 | Red Hat Customer Portal
passthrough - ゲスト仮想マシン内から設定されるユーザーのアクセス権でソースがアクセスされることを指定します。これは、いずれも指定されていない場合にデフォルトの accessmode になります。
mapped - ソースがハイパーバイザーのアクセス権でアクセスされることを指定します。
squash - 'passthrough' に似ていますが、例外は、chown のような権限による操作の失敗が無視されることです。これにより、ハイパーバイザーを root 以外で実行するユーザーにとって、passthrough のようなモードを使いやすいものとします。
squash、passthroughはゲスト側のユーザーが中心になり、mappedはホスト側の権限が中心になる、ということですね。
確認してみましょう。
こちらから。
config.vm.synced_folder './', '/vagrant', type: '9p', disabled: false, accessmode: "squash", owner: "1000"
起動時には、こんな表示が出ます。
==> default: Should be mounting folders ==> default: /vagrant, opts: {:disabled=>false, :guestpath=>"/vagrant", :hostpath=>"/path/to", :type=>:"9p", :accessmode=>"squash", :owner=>"1000", :__vagrantfile=>true, :target=>"/vagrant", :mount=>true, :readonly=>nil, :mount_tag=>"a68e78e76b9b38fcd41945093f0dfb1"}
仮想マシンにSSHで入って、マウントしているファイルシステムを見てみましょう。
$ df -hT Filesystem Type Size Used Avail Use% Mounted on udev devtmpfs 951M 0 951M 0% /dev tmpfs tmpfs 199M 668K 199M 1% /run /dev/vda3 ext4 124G 2.1G 115G 2% / tmpfs tmpfs 994M 0 994M 0% /dev/shm tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs tmpfs 994M 0 994M 0% /sys/fs/cgroup /dev/vda1 ext4 456M 102M 321M 25% /boot a68e78e76b9b38fcd41945093f0dfb1 9p 269G 244G 12G 96% /vagrant tmpfs tmpfs 199M 0 199M 0% /run/user/1000
「/vagrant」が「9p」ファイルシステムでマウントされています。
確認。
$ ll /vagrant/ total 16 drwxrwxr-x 3 vagrant vagrant 4096 Sep 10 09:35 ./ drwxr-xr-x 20 root root 4096 Sep 10 08:51 ../ drwxrwxr-x 5 vagrant vagrant 4096 Sep 10 08:50 .vagrant/ -rw-rw-r-- 1 vagrant vagrant 3192 Sep 10 09:35 Vagrantfile
ホスト側でファイルを作ってみます。
$ echo 'Hello World' > test.txt
すると、ゲスト側にも表示されます。
$ ll /vagrant/ total 20 drwxrwxr-x 3 vagrant vagrant 4096 Sep 10 09:37 ./ drwxr-xr-x 20 root root 4096 Sep 10 08:51 ../ -rw-rw-r-- 1 vagrant vagrant 12 Sep 10 09:37 test.txt drwxrwxr-x 5 vagrant vagrant 4096 Sep 10 08:50 .vagrant/ -rw-rw-r-- 1 vagrant vagrant 3192 Sep 10 09:35 Vagrantfile $ cat /vagrant/test.txt Hello World
ただ、ここにファイルは作れなさそうですね。
$ mkdir /vagrant/dir mkdir: cannot create directory ‘/vagrant/dir’: Permission denied $ sudo mkdir /vagrant/dir mkdir: cannot create directory ‘/vagrant/dir’: Operation not permitted
ホスト側から、緩いディレクトリを作ってみます。
$ mkdir dir $ chmod 777 dir
確認。
$ ll /vagrant/ total 24 drwxrwxr-x 4 vagrant vagrant 4096 Sep 10 09:38 ./ drwxr-xr-x 20 root root 4096 Sep 10 08:51 ../ drwxrwxrwx 2 vagrant vagrant 4096 Sep 10 09:38 dir/ -rw-rw-r-- 1 vagrant vagrant 12 Sep 10 09:37 test.txt drwxrwxr-x 5 vagrant vagrant 4096 Sep 10 08:50 .vagrant/ -rw-rw-r-- 1 vagrant vagrant 3192 Sep 10 09:35 Vagrantfile
ゲスト側から見えます。
書き込んでみましょう。
$ echo 'from Guest' > /vagrant/dir/hello.txt
これならうまくいきました。
権限を見てみると、こんな感じに。
$ ll /vagrant/dir total 12 drwxrwxrwx 2 vagrant vagrant 4096 Sep 10 09:39 ./ drwxrwxr-x 4 vagrant vagrant 4096 Sep 10 09:38 ../ -rw-rw-r-- 1 64055 127 11 Sep 10 09:39 hello.txt
ホスト側から見ると、こうなっています。
$ ls -l dir 合計 4 -rw-rw-r-- 1 libvirt-qemu kvm 11 9月 10 18:39 hello.txt
ゲスト側からも書き込めることは、確認できましたね。
1度、ホスト側からファイルやディレクトリを削除。
$ rm test.txt $ rm -rf dir
最後に、こちらを確認してみます。
config.vm.synced_folder './', '/vagrant', type: '9p', disabled: false, accessmode: "mapped", mount: false
==> default: Should be mounting folders ==> default: /vagrant, opts: {:disabled=>false, :guestpath=>"/vagrant", :hostpath=>"/path/to", :type=>:"9p", :accessmode=>"mapped", :mount=>false, :__vagrantfile=>true, :target=>"/vagrant", :readonly=>nil, :mount_tag=>"a68e78e76b9b38fcd41945093f0dfb1"}
仮想マシンにSSHで入ってみると、ディレクトリはマウントされていません。
$ df -hT Filesystem Type Size Used Avail Use% Mounted on udev devtmpfs 951M 0 951M 0% /dev tmpfs tmpfs 199M 660K 199M 1% /run /dev/vda3 ext4 124G 2.1G 115G 2% / tmpfs tmpfs 994M 0 994M 0% /dev/shm tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs tmpfs 994M 0 994M 0% /sys/fs/cgroup /dev/vda1 ext4 456M 102M 321M 25% /boot tmpfs tmpfs 199M 0 199M 0% /run/user/1000
これは、「mount: false」にしてあるからですね。起動時にマウントされないのです。
マウントしましょう。起動時に表示されている、「:mount_tag=>"a68e78e76b9b38fcd41945093f0dfb1"」という「mount_tag」の
値を使います。
$ sudo mount -t 9p a68e78e76b9b38fcd41945093f0dfb1 /vagrant
マウントするファイルシステムの種類は、9pです。
見えるようになりました。
$ df -hT Filesystem Type Size Used Avail Use% Mounted on udev devtmpfs 951M 0 951M 0% /dev tmpfs tmpfs 199M 660K 199M 1% /run /dev/vda3 ext4 124G 2.1G 115G 2% / tmpfs tmpfs 994M 0 994M 0% /dev/shm tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs tmpfs 994M 0 994M 0% /sys/fs/cgroup /dev/vda1 ext4 456M 102M 321M 25% /boot tmpfs tmpfs 199M 0 199M 0% /run/user/1000 a68e78e76b9b38fcd41945093f0dfb1 9p 269G 244G 12G 96% /vagrant
先ほどと同じように、ホスト側でファイルやディレクトリを作っておきます。
※ゲスト側から「/vagrant」ディレクトリにファイル等が作れないのは同じだったので
$ echo 'Hello World' > test.txt $ mkdir dir $ chmod 777 dir
ゲスト側からの書き込み。
$ echo 'from Guest' > /vagrant/dir/hello.txt
ゲスト側からは、こんな感じに見えます。
$ ll /vagrant total 24 drwxrwxr-x 4 vagrant vagrant 4096 Sep 10 09:48 ./ drwxr-xr-x 20 root root 4096 Sep 10 08:51 ../ drwxrwxrwx 2 vagrant vagrant 4096 Sep 10 09:48 dir/ -rw-rw-r-- 1 vagrant vagrant 12 Sep 10 09:47 test.txt drwxrwxr-x 5 vagrant vagrant 4096 Sep 10 08:50 .vagrant/ -rw-rw-r-- 1 vagrant vagrant 3303 Sep 10 09:44 Vagrantfile $ ll /vagrant/dir total 16 drwxrwxrwx 2 vagrant vagrant 4096 Sep 10 09:48 ./ drwxrwxr-x 4 vagrant vagrant 4096 Sep 10 09:48 ../ -rw-rw-r-- 1 vagrant vagrant 11 Sep 10 09:48 hello.txt
一方、ホスト側からはこう見えます。
$ ls -l dir 合計 8 -rw------- 1 libvirt-qemu kvm 11 9月 10 18:48 hello.txt
違いは、ゲスト側から見た時の、ゲスト側で作ったファイルの所有者ですね。
$ ll /vagrant/dir total 12 drwxrwxrwx 2 vagrant vagrant 4096 Sep 10 09:39 ./ drwxrwxr-x 4 vagrant vagrant 4096 Sep 10 09:38 ../ -rw-rw-r-- 1 64055 127 11 Sep 10 09:39 hello.txt $ ll /vagrant/dir total 16 drwxrwxrwx 2 vagrant vagrant 4096 Sep 10 09:48 ./ drwxrwxr-x 4 vagrant vagrant 4096 Sep 10 09:48 ../ -rw-rw-r-- 1 vagrant vagrant 11 Sep 10 09:48 hello.txt
ホスト側から見た時は変わらないのですが。
ちなみに、最後に試した設定でも
config.vm.synced_folder './', '/vagrant', type: '9p', disabled: false, accessmode: "mapped", mount: true
というように「mount: true」としていれば、起動時にディレクトリをマウントしてくれます。
ただ、極力「squash」の方を使った方がいいんでしょうね。