Внедрение правила iptables после создания сети libvirt с помощью terraform 0.11 - PullRequest
0 голосов
/ 08 ноября 2019

У меня следующий сценарий: я использую terraform (версия 0.11) для создания нескольких виртуальных машин с помощью libvirt. Виртуальные машины подключены к виртуальной сети NAT. В рамках создания виртуальных машин некоторые команды выполняются на каждой виртуальной машине с помощью ssh. Это прекрасно работает, если виртуальные машины создаются на той же машине, где работает terraform.

Теперь я хочу иметь возможность запускать terraform на своем рабочем столе и создавать виртуальные машины на другой машине с большим количеством ресурсов. Я сделал это, изменив URI QEMU, чтобы указать на удаленный сервер. Создание виртуальной машины работает нормально, но когда terraform пытается выполнить ssh в виртуальную машину с моей машины, происходит сбой, поскольку по умолчанию libvirt не предоставляет виртуальным машинам внешний доступ.

Поэтому я создал дополнительный ресурс для запуска командыв удаленной машине добавление правила в iptables после создания виртуальной сети и до обращения к виртуальным машинам. Смотрите код ниже в качестве ссылки. Обратите внимание, что оно отредактировано.

resource "libvirt_network" "network" {
  name   = "${var.stack_name}-network"
  mode   = "${var.network_mode}"  <-- this is NAT
  domain = "${var.dns_domain}"    

  dns = {
    enabled = true
  }

  addresses = ["${var.network_cidr}"]  <- 10.17.0.0/22
}

resource "null_resource" "iptables" {
  depends_on = ["libvirt_network.network"]

  connection {
    host     = <remote server>
    password = "******"
    user     = <ssh user>
    type     = "ssh"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo iptables -I FORWARD 1 -d ${var.network_cidr} -p tcp --dport 22 -j ACCEPT",
    ]
  }
}

resource "libvirt_domain" "vm" {

  depends_on = ["null_resource.iptables"]
  count = "${vars.vms}" 
   ... 
}

resource "null_resource" "config" {
  depends_on = ["libvirt_domain.vm"]

  connection {
    host = "${element(libvirt_domain.vm.*.network_interface.0.addresses.0, count.index)}"
    ...
  }

  provisioner "remote-exec" {   <-- this is the remote exec on vm    

  }
}

Этот вид работает, потому что добавлено правило, НО мне нужно, чтобы новое правило было первым в цепочке FORWARD. Однако я вижу, что правило последовательно добавляется после правил, добавленных libvirt, как показано ниже:

1    ACCEPT     all  --  0.0.0.0/0            10.17.0.0/22         ctstate RELATED,ESTABLISHED
2    ACCEPT     all  --  10.17.0.0/22         0.0.0.0/0           
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
4    REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
5    REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
6    ACCEPT     tcp  --  0.0.0.0/0            10.17.0.0/22         tcp dpt:22

Что я не понимаю, так это почему iptablesправило создается после правил, введенных libvirt, если команда iptables выполняется после создания сети и до выполнения команды ssh для Vms (я проверил это в выводе terraform).

1 Ответ

0 голосов
/ 11 ноября 2019

Я не знаю ответа на вопрос, почему ваш скрипт не работает, но я могу показать вам другой способ достижения той же цели. В Libvirt есть концепция «ловушек», которые представляют собой сценарии, определяемые администратором для запуска в определенных ключевых точках libvirt:

https://libvirt.org/hooks.html

Ниже приведена иллюстрация использования ловушек для переадресации портов:

https://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections

...