public IP when 运行 ifconfig on publicly accessible Azure instance created by Terraform

No public IP when running ifconfig on publicly accessible Azure instance created via Terraform

我正在 Azure 上配置一个集群,我可以在其中使用它们的 public IP 通过 SSH 连接到每台机器。 Terraform 文件:

provider "azurerm" {
  version = "~>2.0"
  features {}
}

resource "azurerm_resource_group" "main" {
  name     = "${var.name}-resources"
  location = "eastus2"
}

resource "azurerm_virtual_network" "main" {
  name                = "${var.name}-network"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
}

resource "azurerm_subnet" "internal" {
  name                 = "internal"
  resource_group_name  = azurerm_resource_group.main.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_network_security_group" "nsg" {
  name                = "${var.name}NetworkSecurityGroup"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name

  security_rule {
    name                       = "SSH"
    priority                   = 1001
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "*"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

resource "azurerm_public_ip" "publicip" {
  name                = "${var.name}PublicIP-${count.index}"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  allocation_method   = "Dynamic"
  count               = 1 + var.workers
}

resource "azurerm_network_interface" "main" {
  name                = "${var.name}-nic-${count.index}"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  count               = 1 + var.workers

  ip_configuration {
    name                          = "${var.name}NICConfig${count.index}"
    subnet_id                     = azurerm_subnet.internal.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.publicip[count.index].id
  }
}

resource "azurerm_network_interface_security_group_association" "main" {
  count                     = 1 + var.workers
  network_interface_id      = azurerm_network_interface.main[count.index].id
  network_security_group_id = azurerm_network_security_group.nsg.id
}

resource "azurerm_linux_virtual_machine" "main" {
  name                  = "${var.name}-${count.index}"
  resource_group_name   = azurerm_resource_group.main.name
  location              = azurerm_resource_group.main.location
  size                  = "Standard_D8s_v3"
  count                 = 1 + var.workers
  admin_username        = "adminuser"
  network_interface_ids = [azurerm_network_interface.main[count.index].id]

  admin_ssh_key {
    username   = "adminuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  source_image_reference {
    publisher = "OpenLogic"
    offer     = "CentOS"
    sku       = "7.7"
    version   = "7.7.2020042900"
  }

  os_disk {
    storage_account_type = "Standard_LRS"
    caching              = "ReadWrite"
  }
}

output "ips" {
  value = ["${azurerm_linux_virtual_machine.main.*.public_ip_address}"]
}

然而,一旦我在机器上,我可以看到虚拟机没有 public IP when 运行 ifconfig:

Last login: Mon Jul 20 10:14:45 2020 from 78.141.104.252
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.5  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::20d:3aff:fe0e:8428  prefixlen 64  scopeid 0x20<link>
        ether 00:0d:3a:0e:84:28  txqueuelen 1000  (Ethernet)
        RX packets 146462  bytes 156556974 (149.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 62320  bytes 12974670 (12.3 MiB)
        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 84  bytes 4400 (4.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 84  bytes 4400 (4.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在这些实例上使用 kubeadm 时会出现问题,因为我需要 public IP 作为现有网络接口。我可以在 Terraform 文件中设置什么来实现这一点吗?我不明白为什么 public IP 不存在,如果我可以使用此 public IP 通过 SSH 进入机器。

Azure 将虚拟机的私有 IP 地址转换为 public IP 地址。因此,虚拟机的操作系统不知道分配给它的任何 public IP 地址,因此无需在操作系统中手动分配 public IP 地址。 Click here for more details

正如 Taguada 回答的那样,Azure 机器不知道它们的 public IP。为了让他们知道,Azure provides a tutorial.

就我而言,在 CentOS 7.7 上,我在所有主机上 运行 这个 Ansible 脚本:

---
- name: Set public IP
  gather_facts: No
  hosts: all
  become: true

  tasks:
    - name: Set public IP in instance
      blockinfile:
        path: /etc/sysconfig/network-scripts/ifcfg-eth0:0
        block: |
          DEVICE=eth0:0
          BOOTPROTO=static
          ONBOOT=yes
          IPADDR={{ ansible_ssh_host }}
          NETMASK=255.255.255.0
        create: true
    - name: restart network
      shell: /etc/init.d/network restart

然后机器知道它们的 public IP。