Die HU Cloud… Ein Beispiel mit Script (Teil 2)

Im zweiten Teil zur Erstellung eines Skripts werden die restlichen Netzwerk-Ressourcen erzeugt.

Die Liste der zu erzeugenden Komponenten umfasst nach der Skizze im ersten Teil:

  • 1 „network“
  • 1 „subnet“
  • 1 „router“
  • 4 „ports“
  • 3 „server“

Das „network“ und das „subnet“ wurden schon angelegt, als nächstes sollen die 4 „ports“ und der „router“ konfiguriert werden.

Über Ports werden in Neutron alle Filter und Sicherhheitsregeln zugewiesen und so benötigt dieser Bereich etwas mehr Aufmerksamkeit, als man es von der Analogie eines „Switch-Ports“ erwarten würde. Gleichzeitig ist es dadurch möglich, die Filter sehr genau für jede Ressource zu kontrollieren. Wie bei einer realen Switch auch, muss jede Ressource an einen Port binden.

Der Prototyp für die „ports“ umfasst:

  type: OS::Neutron::Port
  properties:
   admin_state_up: Boolean
   allowed_address_pairs: [{"ip_address": String, "mac_address": String}, {"ip_address": String, "mac_address": String}, ...]
   device_id: String
   device_owner: String
   fixed_ips: [{"subnet_id": String, "subnet": String, "ip_address": String}, {"subnet_id": String, "subnet": String, "ip_address": String}, ...]
   mac_address: String
   name: String
   network: String
   security_groups: [Value, Value, ...]
   value_specs: {...}

„admin_state_up“ bedeutet, wenn true, dass die Komponente zur Verfügung steht. Über „fixed_ips“ können IPs z.B. für Ressourcen reserviert werden, die eine IP nicht über DHCP, sondern statisch zugewiesen bekommen sollen.

Für den ersten Teil ergibt sich für jeden „port“:

 my_port1:
  type: OS::Neutron::Port
  properties:
   admin_state_up: true
   name: Port01
   network_id: { get_resource: my_first_network }
   security_groups: []

Das „network“ wurde schon im ersten Teil dieses Beitrags vereinbart und so kann es mit „get_resource“ wieder abgefragt werden. Für die Erstellung der „ports“ fehlen jedoch noch die Sicherheitsregeln mit einzelnen „security_group“-Angaben.

Die Vorlage hierfür sieht so aus:

  type: OS::Neutron::SecurityGroup
  properties:
   description: String
   name: String
   rules: [{"remote_group_id": String, "direction": String, "remote_ip_prefix": String, "port_range_min": Integer, "remote_mode": String, "ethertype": String, "port_range_max": Integer, "protocol": String}, {"remote_group_id": String, "direction": String, "remote_ip_prefix": String, "port_range_min": Integer, "remote_mode": String, "ethertype": String, "port_range_max": Integer, "protocol": String}, ...]

Im Beispiel soll eine Basis-Regel für ICMP, und SSH und eine zusätzliche Regel für HTTP-Server definiert werden. Das Skript erweitert sich dadurch um:

 my_basic_security_group:
  type: OS::Neutron::SecurityGroup
  properties:
   description: Allow ICMP, SSH
   name: BasicRules
   rules: [
    {remote_ip_prefix: 0.0.0.0/0,
    direction: ingress,
    protocol: tcp,
    port_range_min: 22,
    port_range_max: 22},
    {remote_ip_prefix: 0.0.0.0/0,
    direction: ingress,
    protocol: icmp},
    {remote_ip_prefix: 0.0.0.0/0,
    direction: egress,
    protocol: icmp}]

 my_http_security_group:
  type: OS::Neutron::SecurityGroup
  properties:
   description: Allow HTTP
   name: HTTPRules
   rules: [
    {remote_ip_prefix: 0.0.0.0/0,
    direction: ingress,
    protocol: tcp,
    port_range_min: 80,
    port_range_max: 80}]

Zwei Server sollen den einfachen Regelsatz, ein Server zusätzlich den HTTP-Regelsatz zugewiesen bekommen. Der Router bekommt eine eigene Regel über Port4.

my_port1:
  type: OS::Neutron::Port
  properties:
   admin_state_up: true
   name: Port01
   network_id: { get_resource: my_first_network }
   security_groups: [ {get_resource: my_basic_security_group }, { get_resource: my_http_security_group } ]

 my_port2:
  type: OS::Neutron::Port
  properties:
   admin_state_up: true
   name: Port02
   network_id: { get_resource: my_first_network }
   security_groups: [ { get_resource: my_basic_security_group } ]

 my_port3:
  type: OS::Neutron::Port
  properties:
   admin_state_up: true
   name: Port03
   network_id: { get_resource: my_first_network }
   security_groups: [ { get_resource: my_basic_security_group } ]

 my_port4:
  type: OS::Neutron::Port
  properties:
   admin_state_up: true
   name: Port04
   network_id: { get_resource: my_first_network }
   fixed_ips: [{ "subnet_id": { get_resource: my_first_subnet }, "ip_address": { get_param: gateway_address } }]
   security_groups: [ { get_resource: my_router_security_group } ]

Da der Router auch als Gateway nach außen eingesetzt werden soll, darf die IP-Adresse nicht wie bei den Servern per DHCP vergeben werden, sondern soll statisch auf die Netzwerkbasisadresse gelegt werden, die vom Anwender abgefragt wurde. Dies geschieht hier über „fixed_ips:“ unter Angabe des „subnet“ und der „gateway_address“.

Nun fehlt nur noch der Router selbst als Ressource.

Die Vorlage für Router sieht folgendermaßen aus:

 my_router:
  type: OS::Neutron::Router
  properties:
   admin_state_up: Boolean
   external_gateway_info: {"enable_snat": Boolean, "network": String}
   l3_agent_id: String
   name: String
   value_specs: {...}

weiterhin benötigt der Router eine Gateway-Angabe und ein Interface nach innen. Die Gateway-Vorlage ist

    type: OS::Neutron::RouterGateway
    properties:
      network: String
      router_id: String

(„OS::Neutron::RouterGateway“ ist deprecated und es sollte external_gateway_info“ aus „OS::Neutron::Router“ benutzt werden, dies hat im ersten Anlauf hier jedoch nicht funktioniert. Vielleicht bei dem kommenden JUNO-Release?)

Die Vorlage für ein Router-Interface ist

    type: OS::Neutron::RouterInterface
    properties:
      port_id: String
      router_id: String
      subnet: String

der komplette Skript-Teil hierfür ist dann:

 my_router:
  type: OS::Neutron::Router
  properties:
   admin_state_up: true
   name: MyRouter

 my_router_gateway:
  type: OS::Neutron::RouterGateway
  properties:
   network_id: { get_param: external_net_id }
   router_id: { get_resource: my_router }

 my_router_int:
  type: OS::Neutron::RouterInterface
  properties:
   router_id: { get_resource: my_router }
   port_id: { get_resource: my_port4 }

Für das Router Gateway ist die Angabe der ID des externen Netzwerks notwendig. Diese wird zu Beginn des Skripts abgefragt. Für das Router-Interface ist hier nur ein „port“ anstelle eines „subnet“ angegeben, um direkt auf die statisch vergebene IP zu verweisen.

Der Stack sieht nun schon etwas komplexer aus:

 

15. August 2014 | Veröffentlicht von Malte Dreyer
Veröffentlicht unter Technik
Verschlagwortet mit , ,

Schreiben Sie einen Kommentar

(erforderlich)