LoginSignup
5
4

More than 5 years have passed since last update.

【Windows】Docker Desktop for WindowsとVagrantの便利な環境を共存させる #3/3【Hyper-V】

Last updated at Posted at 2019-03-21

※本稿は以下の一連の記事のうちの一つです。
【Windows】Docker Desktop for WindowsとVagrantの便利な環境を共存させる #1/3【Hyper-V】
【Windows】Docker Desktop for WindowsとVagrantの便利な環境を共存させる #2/3【Hyper-V】
【Windows】Docker Desktop for WindowsとVagrantの便利な環境を共存させる #3/3【Hyper-V】 ←いまココ

Hyper-V通常VM用のネットワーク設定を自動化する

ここまでの作業で、Hyper-Vの仮想ネットワークの設定・WinNATの設定・VagrantでVMインスタンスを立ち上げる、ということができました。
今回設定した仮想ネットワークにはDHCP機能がないため、VMインスタンスのIPアドレスは自動では設定されません。
これを自動化するためには、大きく以下の2通りの方法があります。

  • VagrantによるVMインスタンス構築時、IPv4設定を併せて行う
  • ホストOS側でDHCPサーバを稼働させ、「Hyper-V Internal with WinNAT」ネットワークに所属するゲストOSがDHCPでIPv4設定できるようにする

VagrantによるVMインスタンス構築時、IPv4設定を併せて行う

まずはこちらの方が簡単です。
Vagrantの「Shell Provisioner」の機能を使います。

Shell Scripts - Provisioning - Vagrant by HashiCorp
https://www.vagrantup.com/docs/provisioning/shell.html

Vagrantfileに下記のように「config.vm.provision」から始まる2行を追加します。Optionとして「inline」を指定し、実行コマンドを直接書きます。
Optionとして「path」を指定し、シェルスクリプトファイルを指定することが可能ですが、今回は使えません。「path」を指定する場合、実行前にファイルをVM内にSSH経由でコピーするという動作になるようで、ネットワークの設定ができていない状態ではファイルのコピーに失敗するからです。

Vagrantfile(抜粋)
  # 下記2行を追加
  config.vm.provision "shell",
    inline: "ip address add 192.168.254.13/23 dev eth0; route add default gw 192.168.254.1"

先ほど作ったVagrantfileに追加すると、下記のようになるでしょう。

Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "Yojimbo108/AmazonLinux2"

  config.vm.provider "hyperv" do |v|
    v.memory = 1024
    v.cpus = 1
  end

  config.vm.define :"stdsv3" do |c1|
    c1.vm.hostname = "stdsv3"
  end

  # 下記2行を追加
  config.vm.provision "shell",
    inline: "ip address add 192.168.254.13/23 dev eth0; route add default gw 192.168.254.1"

end

いったん、vagrant destroyしたのち、再度vagrant upを実行します。初回は失敗し、先ほどと同じ状況になります。
詳細な理由は未調査ですが、「config.vm.provision "shell"」による設定が行われる前にSMBによるフォルダ共有をしようとしたため、エラーになっているように見えます。
またその後、VM内でnetworkサービスがリスタートされています。eth0はDHCPで設定されるようになっているので、networkサービスの実行に失敗します。

vagrant up(1回目)
$ vagrant up
Bringing machine 'stdsv3' up with 'hyperv' provider...
==> stdsv3: Verifying Hyper-V is enabled...
==> stdsv3: Verifying Hyper-V is accessible...
==> stdsv3: Importing a Hyper-V instance
    stdsv3: Creating and registering the VM...
    stdsv3: Successfully imported VM
    stdsv3: Please choose a switch to attach to your Hyper-V instance.
    stdsv3: If none of these are appropriate, please open the Hyper-V manager
    stdsv3: to create a new virtual switch.
    stdsv3:
    stdsv3: 1) DockerNAT
    stdsv3: 2) Hyper-V Internal with WinNAT
    stdsv3:
    stdsv3: What switch would you like to use? 2
    stdsv3: Configuring the VM...
==> stdsv3: Starting the machine...
==> stdsv3: Waiting for the machine to report its IP address...
    stdsv3: Timeout: 120 seconds
    stdsv3: IP: fe80::215:5dff:fe14:2512
==> stdsv3: Waiting for machine to boot. This may take a few minutes...
    stdsv3: SSH address: fe80::215:5dff:fe14:2512:22
    stdsv3: SSH username: vagrant
    stdsv3: SSH auth method: private key
    stdsv3:
    stdsv3: Vagrant insecure key detected. Vagrant will automatically replace
    stdsv3: this with a newly generated keypair for better security.
    stdsv3:
    stdsv3: Inserting generated public key within guest...
    stdsv3: Removing insecure key from the guest if it's present...
    stdsv3: Key inserted! Disconnecting and reconnecting using new SSH key...
==> stdsv3: Machine booted and ready!
==> stdsv3: Preparing SMB shared folders...
    stdsv3: You will be asked for the username and password to use for the SMB
    stdsv3: folders shortly. Please use the proper username/password of your
    stdsv3: account.
    stdsv3:
    stdsv3: Username: ****
    stdsv3: Password (will be hidden):
Error! Your console doesn't support hiding input. We'll ask for
input again below, but we WILL NOT be able to hide input. If this
is a problem for you, ctrl-C to exit and fix your stdin.
     stdsv3: Password (will be hidden): ********

Vagrant requires administrator access to create SMB shares and
may request access to complete setup of configured shares.
==> stdsv3: Setting hostname...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

service network restart

Stdout from the command:

Restarting network (via systemctl):  [FAILED]


Stderr from the command:

Job for network.service failed because the control process exited with error code. See "systemctl status network.service" and "journalctl -xe" for details.

次にvagrant provisionを実行します。Shell Provisionerが実行され、指定したIPアドレスが設定されます。

vagrant provision(2回目)
$ vagrant provision
==> stdsv3: Running provisioner: shell...
    stdsv3: Running: inline script

vagrant sshを実行してログインしてみます。ifconfigコマンドを実行すると、指定したIPアドレスが付与されていることを確認できます。
netstatコマンドを実行すると、IPv4アドレスでSSH接続していることを確認できます。

vagrant ssh
$ vagrant ssh
Last login: Fri Mar  1 15:21:31 2019

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[vagrant@stdsv3 ~]$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.254.13  netmask 255.255.254.0  broadcast 0.0.0.0
        inet6 fe80::215:5dff:fe14:2512  prefixlen 64  scopeid 0x20<link>
        ether 00:15:5d:14:25:12  txqueuelen 1000  (Ethernet)
        RX packets 7649  bytes 1955138 (1.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 682  bytes 114005 (111.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[vagrant@stdsv3 ~]$ netstat -an|grep ESTABLISHED
tcp        0      0 192.168.254.13:22       192.168.254.1:64372     ESTABLISHE

この状態では、OS再起動時などにIPアドレスが消えてしまいます。
/etc/sysconfig/network-scripts/ifcfg-eth0に必要な設定を書き込みます。その他、必要な設定を実施します。
まとめると以下のような変更が必要になります。

  • /etc/sysconfig/network-scripts/ifcfg-eth0に、IPv4設定を書き込む
  • /etc/resolv.confに、自分のISPから提供されているDNSサーバを設定する
  • /etc/ssh/sshd_configを変更し、SSH経由でユーザ名・パスワードでログインできるように設定する

Vagrantfileを以下のように変更します。実行コマンドの行数が多くなるので、Inline Scriptsの機能を利用します。

Shell Scripts - Provisioning - Vagrant by HashiCorp -> Inline Scripts
https://www.vagrantup.com/docs/provisioning/shell.html#inline-scripts

Vagrantfile
$provisioner_script = <<-SCRIPT

  ip address add 192.168.254.13/23 dev eth0;
  route add default gw 192.168.254.1;

  echo '# This file has been overwritten by Vagrant Shell Provisioner' > /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo BOOTPROTO=none >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo DEVICE=eth0 >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo NM_CONTROLLED=no >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo ONBOOT=yes >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo IPADDR=192.168.254.13 >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo NETMASK=255.255.254.0 >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo GATEWAY=192.168.254.1 >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo DNS1=xxx.xxx.xxx.xxx >> /etc/sysconfig/network-scripts/ifcfg-eth0;
  echo DNS2=xxx.xxx.xxx.yyy >> /etc/sysconfig/network-scripts/ifcfg-eth0;

  sed -i 's/^nameserver .*$/nameserver xxx.xxx.xxx.xxx\nnameserver xxx.xxx.xxx.yyy/' /etc/resolv.conf

  sed -i 's/^PasswordAuthentication .*$/PasswordAuthentication yes/' /etc/ssh/sshd_config;
  systemctl reload sshd;

SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = "Yojimbo108/AmazonLinux2"

  config.vm.provider "hyperv" do |v|
    v.memory = 1024
    v.cpus = 1
  end

  config.vm.define :"stdsv3" do |c1|
    c1.vm.hostname = "stdsv3"
  end

  config.vm.provision "shell", inline: $provisioner_script

end

もう一度、vagrant privisionを実行します。その後VMインスタンスにログインし、意図したとおりの設定になっていることを確認します。

ホストOS側でDHCPサーバを稼働させ、「Hyper-V Internal with WinNAT」ネットワークに所属するゲストOSがDHCPでIPv4設定できるようにする

大きく、以下の作業を実施する必要があります。

  • Open DHCP Serverをインストールし、Serviceとして実行させる
  • Windows Firewallの設定をする

詳細は下記記事にまとめました。
【Windows】非Server EditionでDHCPサーバを構築する【DHCP】 - Qiita

おわりに

Hyper-Vのネットワーク機能は一部不安定なところがあること、VagrantはHyper-Vの仮想ネットワークを操作する機能がないことから、
Hyper-Vを作業用のVMのハイパーバイザとして利用するにはまだ少し難があります。
現状では、VirtualBoxの利便性にはまだまだかなわないという感触です。

しかしながら、Docker Desktop for Windowsは今後、Hyper-Vに注力していくように見えますので、Hyper-Vの重要性が高まっていくように予測しています。

でもこんな話もありますし、これが実現できるんだったら無理してHyper-Vでいろいろ頑張らなくても良いような気がしてきました。
VirtualBox 6.0 から Hyper-V と共存できるはず - Qiita

5
4
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
5
4