Vagrant:不要将主机名映射到/ etc / hosts中的环回地址

时间:2015-10-14 06:17:45

标签: vagrant fedora hosts vagrantfile resolve

我正在使用Vagrant( v1.7.2 )来配置Linux(Fedora 22)主机和vagrant-hostmanager插件( v1.6.1 ) 写/etc/hosts以便主机可以互相访问。

我的Vagrantfile

Vagrant.configure(2) do |config|

  config.vm.box = "workshop"

  config.hostmanager.enabled = true
  config.hostmanager.include_offline = true

  config.vm.define "server" do |server|
    server.vm.network "private_network", ip: "192.168.33.10"
    server.vm.hostname = "server.local"
  end

  config.vm.define "client" do |client|
    client.vm.network "private_network", ip: "192.168.33.20"
    client.vm.hostname = "client.local"
  end

end

当我vagrant up时,server VM具有以下/etc/hosts

127.0.0.1 server.ipademo.local server
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

## vagrant-hostmanager-start
192.168.33.10   server.ipademo.local

192.168.33.20   client.ipademo.local

## vagrant-hostmanager-end

(对于VM client,请仅在第一行上替换s/server/client/。)

因为Vagrant> = 1.5.0在配置之前运行vagrant-hostmanager插件,我还尝试通过将Vagrantfile更改为

来在规定期间运行hostmanager
  config.hostmanager.enabled = false
  config.hostmanager.include_offline = true
  config.vm.provision :hostmanager

这有相同的结果。

问题描述

127.0.0.1 <fqdn> <shortname>行与vagrant-hostmanager添加的信息冲突。我需要禁止主机名与环回地址的关联,以便在每个VM上将主机名解析为专用网络地址,由 vagrant-hostmanager 添加。

我该如何做到这一点?

2 个答案:

答案 0 :(得分:2)

问题的原因是Vagrant为Fedora来宾提供了更改主机名功能。特别是在plugins/guests/fedora/cap/change_host_name.rb

def update_etc_hosts                             
  ip_address = '([0-9]{1,3}\.){3}[0-9]{1,3}'
  search     = "^(#{ip_address})\\s+#{Regexp.escape(current_hostname)}(\\s.*)?$"
  replace    = "\\1 #{fqdn} #{short_hostname}"
  expression = ['s', search, replace, 'g'].join('@')

  sudo("sed -ri '#{expression}' /etc/hosts")
end

update_etc_hosts方法用新主机名替换原始主机名(对于Fedora,这是localhost.localdomain,绑定到环回地址127.0.0.1)。然后,它会使用短主机名更新/etc/hostname,但系统调用仍会返回完整的主机名,因为它显示在/etc/hosts中。

解决方案

我提供了额外的配置程序(在上述hackery发生之后运行)到:

  1. 查询长主机名(FQDN)并将其写回/etc/hostname。这是必需的,因此在我们在下一步修复hostname --fqdn后,/etc/hosts实际上会返回完整的主机名。

  2. 恢复/etc/hosts中的环回线路,以便机器的主机名解析为 vagrant-hostmanager 设置的专用网络地址。

  3. 订单很关键。这是Vagrantfile代码:

    # Vagrant's "change host name" sets the short host name.
    # Before we undo the /etc/hosts silliness (see below) let's
    # reset /etc/hostname to the *full* host name
    #
    config.vm.provision "shell",
      inline: "hostname --fqdn > /etc/hostname && hostname -F /etc/hostname"
    
    # Vagrant's "change host name" capability for Fedora
    # maps hostname to loopback, conflicting with hostmanager.
    # We must repair /etc/hosts
    #
    config.vm.provision "shell",
      inline: "sed -ri 's/127\.0\.0\.1\s.*/127.0.0.1 localhost localhost.localdomain/' /etc/hosts"
    

答案 1 :(得分:0)

当主机名通过Vagrant设置时,大多数Linux发行版都有same issue由change_host_name流浪汉功能(redhatdebianarch等)引起。

change_host_name的以下行在设置主机名时将vm主机名和vm名称作为127.0.0.1的别名,这与vagrant-hostmanager的别名冲突。

sed -i'' '1i 127.0.0.1\\t#{name}\\t#{basename}' /etc/hosts

Vagrant authors have said that this is intentional并且他们并不打算修复它,因为只要您不修改/ etc / hosts(vagrant-hostmanager),它就会按原样运行。

有趣的是,许多工具(dig,host,nslookup)使用LAST指定的别名,这对defualt Vagrant行为很好。不幸的是,其他工具,即使用gethostbyname/etc/nsswitch.conf的工具,具有不同的行为。

例如,Ping似乎使用/ etc / hosts中的第一个别名,而Curl(编译为使用NSS时)使用多个别名作为自上而下的回退。

因此,通常不鼓励使用别名匹配多个IP。

以下Vagrantfile解决方法应该足够了:

config.hostmanager.enabled = true

name = "name"
hostname = "hostname"

config.vm.define name do |machine|
  machine.vm.hostname = hostname
  machine.vm.provision :shell, inline: "sed -i'' '/^127.0.0.1\\t#{hostname}\\t#{name}$/d' /etc/hosts"
  ...
end