Cookies helfen uns bei der Bereitstellung des IMT HilfeWikis. Bei der Nutzung vom IMT HilfeWiki werden die in der Datenschutzerklärung beschriebenen Cookies gespeichert.Weitere Informationen

Cloudcomputing Kochbuch Orchestrierung: Unterschied zwischen den Versionen

IMT HilfeWiki - das Wiki
Wechseln zu:Navigation, Suche
(Die Seite wurde neu angelegt: „{{article |type=Anleitung |service=Service:Cloudcomputing |targetgroup=Angestellte,Studierende,Gäste |hasdisambig=Nein }} {{template caller‏‎ |marker=Stub…“)
 
 
(9 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 8: Zeile 8:
 
|marker=Stub
 
|marker=Stub
 
}}
 
}}
Kurzer Einleitungstext
+
In diesem Artikel erfahren Sie, wie Sie mithilfe der ''HEAT''-Komponente von OpenStack einen eigenen IaC ([https://en.wikipedia.org/wiki/Infrastructure_as_code Infrastructure as Code]) Stack erstellen, testen und starten.
  
== Was ist zu tun? ==
+
== Rezepte ==
* Stichpunktartige Auflistung
+
== Anlegen einer Vorlage ==
* aller Arbeitsschritte
+
Die Konfiguration des Stacks erfolgt nicht wie in den anderen Artikel dieses Bereiches beschrieben über die Weboberfläche oder den Kommandozeilen-Client, sondern wird mithilfe von Templates erstellt.
 +
Die Templates werden als HOT (Heat Orchestration Templates) bezeichnet und werden in [https://de.wikipedia.org/wiki/YAML#:~:text=YAML%20%5B%CB%88j%C3%A6m%C9%99l%5D%20ist%20eine%20vereinfachte,vorgestellten%20E%2DMail%2DFormat YAML] verfasst.
 +
Es werden grundsätzlich vier Dinge definiert:
  
== Schritt-für-Schritt Anleitung ==
+
{| class="wikitable"
Jeder Arbeitschritt wird hier genau erklärt und ggf. mit Screenshots hinterlegt.
+
|-
 +
! Typ !! Beschreibung
 +
|-
 +
| heat_template_version || Die Version des erstellten Templates
 +
|-
 +
| parameters || Variablen, die im laufe des Scripts wieder aufgerufen werden können (z.B. Schlüsselpaare, Flavor)
 +
|-
 +
| resources || Ressourcen, die durch das Template erstellt werden sollen (z.B. Virtuelle Maschinen, Netzwerke)
 +
|-
 +
| outputs || Ausgaben, die nach der Erstellung einsehbar seien sollen (z.B. Floating-IPs)
 +
|-
 +
|}
  
=== Dabei sollten ===
+
Die verfügbaren Heat Template Versionen können Sie in der [https://rdi-cloud.uni-paderborn.de/project/template_versions/ Weboberfläche] unter ''Orchestrierung/Vorlagenversionen'' einsehen.
Unterschritte
+
Hier ist zu empfehlen, dass Sie die neuste Version verwenden, da hier üblicherweise die beste Kompatibilität gewährleistet ist.
 +
Unter [https://rdi-cloud.uni-paderborn.de/project/resource_types/ Ressourcentypen] finden Sie dort auch eine Auflistung der verfügbaren Ressourcen, welche Sie in Ihrem Template definieren können. Wenn Sie auf den Namen einer Ressource klicken, gelangen
 +
Sie zu der Hilfeseite der jeweiligen Ressource, hier werden Ihnen die verfügbare Parameter kurz erklärt.
  
=== in sinnvolle Abschnitte ===
+
<bootstrap_alert color=info>Die Einrückung in einem HOT-Template muss immer zwei Leerzeichen betragen, ansonsten erhalten Sie Fehler bei der Erstellung des Stacks.
unterteilt werden
+
</bootstrap_alert>
  
=== dazu nutzt man dann ===
+
Als ersten Beispiel finden Sie hier ein einfaches Template, in dem zunächst eine Instanz mit Netzwerkport und Floating IP erstellt wird.
Überschriften dritter Ordnung
+
Speichern Sie ihr Template als <code>.yaml</code> Datei ab.
 +
<source lang=YAML>
 +
heat_template_version: 2018-08-31
 +
description: A simple HOT
  
=== Nebenbei ===
+
parameters:
* Hier nochmal der Hinweis auf den Menüpunkt "Mitmachen" links im Hauptmenü, hinter dem sich wertvolle Anleitungen und Hinweise verstecken.
+
  flavor:
* Erfahrene Redakteure finden unterhalb der "Kategorie:Utility templates" interessantes Handwerkszeug für fortgeschrittene Textmanipulationen.
+
    type: string
 +
    description: Flavor used by the server
 +
    default: upb-medium
 +
  image:
 +
    type: string
 +
    description: Image used for server
 +
    default: c315dc8d-8a9a-499d-a03e-9988d246bb77
 +
  user_key:
 +
    type: string
 +
    description: SSH key to connect to the server
 +
  network:
 +
    type: string
 +
    description: The network for the server
 +
    default: uni
 +
  subnet:
 +
    type: string
 +
    description: The subnet for the server
 +
    default: uni-subnet-0
 +
  floating_ip_id:
 +
    type: string
 +
    description: ID of the Floating IP to use
  
== Siehe auch ==
+
resources:
Weitere interessante Artikel zum gleichen Themenfeld verlinken
+
  webserver:
 +
    type: OS::Nova::Server
 +
    properties:
 +
      flavor: { get_param: flavor }
 +
      image: { get_param: image }
 +
      key_name: { get_param: user_key }
 +
      networks:
 +
        - port: { get_resource: webserver_port }
 +
 
 +
  webserver_port:
 +
    type: OS::Neutron::Port
 +
    properties:
 +
      network: { get_param: network }
 +
      fixed_ips:
 +
        - subnet: { get_param: subnet }
 +
      security_groups: [{ get_resource: webserver_security_group }]
 +
 
 +
  webserver_floating_ip:
 +
    type: OS::Neutron::FloatingIPAssociation
 +
    properties:
 +
      floatingip_id: { get_param: floating_ip_id }
 +
      port_id: { get_resource: webserver_port }
 +
 
 +
  webserver_security_group:
 +
    type: OS::Neutron::SecurityGroup
 +
    properties:
 +
      description: Add security group rules for server
 +
      name: security-group
 +
      rules:
 +
        - remote_ip_prefix: 0.0.0.0/0
 +
          protocol: tcp
 +
          port_range_min: 22
 +
          port_range_max: 22
 +
        - remote_ip_prefix: 0.0.0.0/0
 +
          protocol: icmp
 +
 
 +
outputs:
 +
  server_private_ip:
 +
    description: IP address of the server in private network
 +
    value: { get_attr: [ webserver, first_address ] }
 +
</source>
 +
 
 +
Hier wird im oberen Teil zunächst die Template Version festgelegt und eine kurze Beschreibung zum Template gegeben,
 +
danach folgt der Punkt <code>parameters</code>. Die Parameter können beim Deployment des Stacks mit angegeben und bieten so die Möglichkeit z.B. den Flavor einer VM oder ein eigenes Schlüsselpaar einzugeben. Die Struktur der Parameter ist dabei immer die selbe:
 +
<source>
 +
Name_des_Parameters:
 +
    type: Typ des Parameter (string, number, boolean)
 +
    description: Beschreibung des Parameters
 +
    default: Standardwert, falls keine Eingabe gemacht wird
 +
</source>
 +
 
 +
Anschließend folgt die Definition der Ressourcen. Auch hier geben Sie zunächst den Namen und den Typ der Ressource an. Der Typ gibt an, welches Modul von Openstack angesprochen werden soll. Eine Übersicht der verfügbaren Ressourcen erhalten Sie unter [https://rdi-cloud.uni-paderborn.de/project/resource_types/ Ressourcentypen]. Abhängig von der Ressource ändern sich die möglichen Eigenschaften. Mithilfe der Funktionen ''get_param'', ''get_ressource'' und ''get_attr'' können Sie innerhalb des Templates auf die jeweiligen Werte referenzieren. Diese müssen nicht zwingend vorher definiert sein, sondern können auch im Script hinter dem Aufruf stehen.
 +
<source>
 +
Name_der_Ressource:
 +
    type: Typ der Ressource
 +
    properties: Auflistung der Eigenschaften
 +
      Eigenschaft_1: Wert
 +
      Eigenschaft_2: Wert
 +
</source>
 +
 
 +
Am Ende des Templates werden die Ausgaben definiert. Mithilfe der Funktion ''get_attr'' können Sie auf Attribute einer Ressource zugreifen und diese in der Übersicht des Stacks ausgeben. Die möglichen Attribute finden Sie in der Übersicht der [https://rdi-cloud.uni-paderborn.de/project/resource_types/ Ressourcentypen], wenn Sie auf den Namen der Ressource klicken.
 +
<source>
 +
outputs:
 +
  Name_der_Ausgabe:
 +
    description: Beschreibung der Ausgabe
 +
    value: { get_attr: [ Ressource, Attribut ] }
 +
</source>
 +
 
 +
== Einen Stack erstellen und starten ==
 +
Um einen Stack zu starten können Sie auf der Weboberfläche unter ''Orchestrierung/Stacks'' auf den Button ''Stack starten'' klicken. Wählen Sie unter ''Vorlagenquelle'' ihre erstellte <code>.yaml</code>-Datei aus und klicken Sie auf ''Weiter''.
 +
 
 +
[[Datei:Screenshot_OpenStack_Heat_Template_Upload.png |mini|200px|none| Vorlage auswählen]]
 +
 
 +
Im nächsten Dialogfenster müssen Sie zunächst einen Namen und ein Passwort für den Stack vergeben, danach werden ihre im Template definierten Parameter aufgeführt, welche Sie an dieser Stelle eingeben können. Klicken Sie zum erstellen des Stacks auf ''Starten''.
 +
 
 +
[[Datei:Screenshot_OpenStack_Heat_Stack_erstellen.png |mini|200px|none| Parameter eingeben]]
 +
 
 +
Stacks lassen sich auch mithilfe des [https://hilfe.uni-paderborn.de/Cloudcomputing_Kochbuch_Kommandozeilen-Client_erzeugen Kommandozeilen-Clients] starten. Verwenden Sie dafür folgendes Schema:
 +
<source>
 +
openstack stack create --template stack.yaml --parameter "parameter_1=wert" --parameter "parameter_2=wert" NameDesStacks
 +
</source>
 +
 
 +
Mit der Option <code>--dry-run</code> können Sie die Template Datei zuerst testen, ohne den Stack zu erstellen.
 +
 
 +
Die Erstellung kann je nach Größe des Stacks einige Minuten in Anspruch nehmen. Den aktuellen Status der Erstellung können Sie auf der Übersichtsseite des Stack sehen. Klicken Sie dazu in der Übersicht unter ''Orchestrierung/Stacks'' auf den Namen des Stacks.
 +
 
 +
Openstack erstellt automatisch eine grafische Übersicht des Stack. In der oberen Menüleiste wählen Sie den Punkt ''Ressourcen'', hier wird ihnen der Status der einzelnen Ressourcen des Stacks angezeigt und unter ''Veranstaltungen'' werden die letzten Ereignisse angezeigt. Falls es beim erstellen des Stacks zu Fehlern kommt, werden diese hier angezeigt.
 +
 
 +
== Einen Stack aktualisieren ==
 +
Wollen Sie einen Stack aktualisieren, müssen Sie dazu im Kontextmenü, welches sich rechts neben dem Namen des Stack befinden, den Punkt ''Ändern der Stack-Vorlage'' wählen. Wählen Sie hier, wie beim Erstellen des Stacks, das neue Template aus und klicken auf ''Weiter''. Geben Sie ihre Parameter an und klicken anschließend auf ''Aktualisieren''.
 +
 
 +
Openstack schaut nun, welche Parameter und Ressourcen sich geändert haben und nimmt entsprechend Änderungen am Stack vor. Manche dieser Änderungen können im laufenden Betrieb erfolgen, für andere müssen Teile des Stacks neu erstellt werden. Dazu bietet das [https://docs.openstack.org/heat/latest/template_guide/openstack.html Openstack Wiki] Hinweise bei den jeweiligen Parameter mit '''Can be updated without replacement''' oder '''Updates cause replacement'''.
 +
 
 +
== Einen Stack löschen ==
 +
Wollen Sie einen Stack löschen, müssen Sie dazu auf ''Stack löschen'' im Kontextmenü rechts neben dem Namen des Stacks klicken. Die Löschung kann je nach Größe des Stacks einige Minuten in Anspruch nehmen.
 +
 
 +
== Instanzen per Cloud-Config konfigurieren ==
 +
In den meisten Fällen wird es notwendig sein, Instanzen während oder nach dem Start zu konfigurieren. Dies geschieht mithilfe des Cloud-Init Dienstes. Dieser kann in einer separaten <code>cloud-config.yaml</code>-Datei liegen oder direkt in der Template-Datei verfasst werden.
 +
 
 +
Mithilfe des Cloud-Init Dienstes können Sie unteranderem:
 +
* das System aktualisieren
 +
* Softwarepackete installieren
 +
* Benutzer und Gruppen erstellen
 +
* Dateien und Verzeichnisse anlegen
 +
* Git Repositories klonen
 +
* Nutzerdaten einspielen
 +
* Zertifikate hinterlegen
 +
* Datenträger formatieren
 +
<br>
 +
und noch vieles mehr. Einige Beispiele einer <code>cloud-config.yaml</code>-Datei finden Sie [https://cloudinit.readthedocs.io/en/latest/topics/examples.html im Cloud-Init Wiki]. In vielen fällen lassen sich so aufwendige Shell-Scripte vermeiden.
 +
 
 +
In einem Heat-Template können Sie die eine Cloud-Config als Ressource mit der Komponente OS::Heat::CloudConfig anlegen und diese bei der Instanz unter '''user_data''' mit '''get_resource''' wieder aufrufen.
 +
<source>
 +
resources:
 +
  dev_config:
 +
    type: OS::Heat::CloudConfig
 +
    properties:
 +
      cloud_config:
 +
        hostname: kochbuch-server
 +
        manage_etc_hosts: localhost
 +
        package_update: true
 +
        package_upgrade: true
 +
        packages:
 +
          - apache2
 +
        runcmd:
 +
          - sh -c 'hostname -I > /var/www/html/index.html'
 +
        final_message: "The system is finally up, after $UPTIME seconds"
 +
 
 +
  web_server:
 +
    type: OS::Nova::Server
 +
    properties:
 +
      flavor: upb-medium
 +
      image: c315dc8d-8a9a-499d-a03e-9988d246bb77
 +
      key_name: { get_param: user_key }
 +
      user_data: { get_resource: devstack_config }
 +
      user_data_format: RAW
 +
</source>
 +
 
 +
Folgendes wird in der cloud_config festgelgt:
 +
{| class="wikitable"
 +
|-
 +
! Eigenschaft !! Wert
 +
|-
 +
| hostname || Legt den Hostnamen der Instanz fest
 +
|-
 +
| manage_etc_hosts || Stellt mit der Einstellung ''localhost'' sicher, dass Cloud-Init neue Eintrage am Ende der Datei schreibt
 +
|-
 +
| package_update || Nach Updates suchen
 +
|-
 +
| package_upgrade || Verfügbare Updates installieren
 +
|-
 +
| packages || Liste der Pakete die installiert werden sollen
 +
|-
 +
| runcmd || Liste von Kommandos die ausgeführt werden sollen 
 +
|-
 +
| final_message || Ausgabe einer Nachricht am Ende des Scripts
 +
|-
 +
|}
 +
 
 +
 
 +
== Praxisbeispiel Autoscaling Group mit Loadbalancer ==
 +
Nachfolgend finden Sie noch ein Beispiel einer Umfangreicheren Konfiguration eines Stacks.
 +
Bei dem ersten Template (Stack.yaml) wird über einen Loadbalancer eine selbsskalierende Gruppe von Instanzen gesteuert, über die ein Webserver bereitgestellt wird. Zusätzlich wird ein Netzwerk und die für den Loadbalancer nötigen Ressourcen (Pool, Monitor, etc) angelegt.
 +
Der Loadbalancer bekommt zum Schluss eine Floating IP zugeteilt und abschließend werden noch die URLs ausgegeben, über welche die Autoscaling Group hoch- bzw. herunter skaliert werden können.
 +
 
 +
Für die einzelnen Instanzen der Autoscaling Group wurde ein separates Template angelegt (lb_member.yaml), in dem auch gleichzeitig die Konfiguration über ''cloud-config'' erfolgt. Diese Instanzen werden dann als ''Member'' dem Loadbalancer zugeteilt.
 +
 
 +
'''Stack.yaml'''
 +
<source lang=YAML>
 +
heat_template_version: 2018-08-31
 +
description: A load-balancer webserver
 +
 
 +
parameters:
 +
  public_net_id:
 +
    type: string
 +
    description: Public network ID
 +
    default: external
 +
  timeout:
 +
    type: number
 +
    description: Timeout for stack creation to finish
 +
    default: 900
 +
  floatingip_ID:
 +
    type: string
 +
    description: Floating IP to associate
 +
  user_key:
 +
    type: string
 +
    description: Key ID or name
 +
 
 +
resources:
 +
  server_security_group:
 +
    type: OS::Neutron::SecurityGroup
 +
    properties:
 +
      description: Neutron security group rules
 +
      name: kochbuch_security_group
 +
      rules:
 +
      - remote_mode: 'remote_group_id'
 +
        direction: ingress
 +
      - remote_ip_prefix: 0.0.0.0/0
 +
        protocol: icmp
 +
      - remote_ip_prefix: 0.0.0.0/0
 +
        protocol: tcp
 +
        direction: ingress
 +
        port_range_min: 22
 +
        port_range_max: 22
 +
      - remote_ip_prefix: 0.0.0.0/0
 +
        protocol: tcp
 +
        direction: ingress
 +
        port_range_min: 80
 +
        port_range_max: 80
 +
 
 +
  kochbuch_net:
 +
    type: OS::Neutron::Net
 +
    properties:
 +
      name: kochbuch-net
 +
 
 +
  kochbuch_sub_net:
 +
    type: OS::Neutron::Subnet
 +
    properties:
 +
      name: kochbuch-sub-net
 +
      network_id: { get_resource: kochbuch_net }
 +
      cidr: 192.168.0.0/24
 +
      gateway_ip: 192.168.0.1
 +
      enable_dhcp: true
 +
      allocation_pools:
 +
        - start: "192.168.0.2"
 +
          end: "192.168.0.50"
 +
 
 +
  router:
 +
    type: OS::Neutron::Router
 +
 
 +
  router_gateway:
 +
    type: OS::Neutron::RouterGateway
 +
    properties:
 +
      router_id: { get_resource: router }
 +
      network_id: { get_param: public_net_id }
 +
 
 +
  router_interface:
 +
    type: OS::Neutron::RouterInterface
 +
    properties:
 +
      router_id: { get_resource: router }
 +
      subnet_id: { get_resource: kochbuch_sub_net }
 +
 
 +
  monitor:
 +
    type: OS::Octavia::HealthMonitor
 +
    properties:
 +
      delay: 3
 +
      type: HTTP
 +
      http_method: GET
 +
      expected_codes: 200
 +
      timeout: 3
 +
      max_retries: 3
 +
      pool: { get_resource: pool }
 +
 
 +
  pool:
 +
    type: OS::Octavia::Pool
 +
    properties:
 +
      lb_algorithm: ROUND_ROBIN
 +
      protocol: HTTP
 +
      listener: { get_resource: listener }
 +
      loadbalancer: { get_resource: loadbalancer }
 +
 
 +
  listener:
 +
    type: OS::Octavia::Listener
 +
    properties:
 +
      loadbalancer: { get_resource: loadbalancer }
 +
      protocol: HTTP
 +
      protocol_port: 80
 +
 
 +
  loadbalancer:
 +
    type: OS::Octavia::LoadBalancer
 +
    properties:
 +
      vip_subnet: { get_resource: kochbuch_sub_net }
 +
 
 +
  kochbuch_asg:
 +
    type: OS::Heat::AutoScalingGroup
 +
    properties:
 +
      min_size: 1
 +
      desired_capacity: 3
 +
      max_size: 5
 +
      resource:
 +
        type: lb_member.yaml
 +
        properties:
 +
          user_key: { get_param: user_key }
 +
          security_groups: { get_resource: server_security_group }
 +
          network: { get_resource: kochbuch_net }
 +
          subnet: { get_resource: kochbuch_sub_net }
 +
          pool: {get_resource: pool}
 +
 
 +
  web_server_scaleup_policy:
 +
    type: OS::Heat::ScalingPolicy
 +
    properties:
 +
      adjustment_type: change_in_capacity
 +
      auto_scaling_group_id: { get_resource: kochbuch_asg }
 +
      cooldown: 60
 +
      scaling_adjustment: 1
 +
 
 +
  web_server_scaledown_policy:
 +
    type: OS::Heat::ScalingPolicy
 +
    properties:
 +
      adjustment_type: change_in_capacity
 +
      auto_scaling_group_id: { get_resource: kochbuch_asg }
 +
      cooldown: 60
 +
      scaling_adjustment: '-1'
 +
 
 +
  cpu_alarm_high:
 +
    type: OS::Aodh::GnocchiAggregationByResourcesAlarm
 +
    properties:
 +
      description: Scale up if CPU > 75%
 +
      metric: cpu_util
 +
      aggregation_method: mean
 +
      granularity: 600
 +
      evaluation_periods: 1
 +
      threshold: 75
 +
      resource_type: instance
 +
      comparison_operator: gt
 +
      alarm_actions:
 +
        - str_replace:
 +
            template: trust+url
 +
            params:
 +
              url: { get_attr: [web_server_scaleup_policy, signal_url] }
 +
      query:
 +
        list_join:
 +
          - ''
 +
          - - { '=': { server_group: { get_param: "OS::stack_id" } } }
 +
 
 +
  cpu_alarm_low:
 +
    type: OS::Aodh::GnocchiAggregationByResourcesAlarm
 +
    properties:
 +
      description: Scale down if CPU < 15%
 +
      metric: cpu_util
 +
      aggregation_method: mean
 +
      granularity: 600
 +
      evaluation_periods: 1
 +
      threshold: 15
 +
      resource_type: instance
 +
      comparison_operator: lt
 +
      alarm_actions:
 +
        - str_replace:
 +
            template: trust+url
 +
            params:
 +
              url: {get_attr: [web_server_scaledown_policy, signal_url]}
 +
      query:
 +
        list_join:
 +
          - ''
 +
          - - { '=': { server_group: { get_param: "OS::stack_id" } } }
 +
 
 +
  lb_floating_ip:
 +
    type: OS::Neutron::FloatingIPAssociation
 +
    properties:
 +
      floatingip_id: { get_param: floatingip_ID }
 +
      port_id: { get_attr: [loadbalancer, vip_port_id ]}
 +
 
 +
outputs:
 +
  scale_up_url:
 +
    description: This URL is the webhook to scale up the group.
 +
    value: { get_attr: [web_server_scaleup_policy, alarm_url] }
 +
  scale_dn_url:
 +
    description: This URL is the webhook to scale down the group.
 +
    value: { get_attr: [web_server_scaledown_policy, alarm_url] }
 +
</source>
 +
 
 +
'''lb_member.yaml'''
 +
<source>
 +
heat_template_version: 2018-08-31
 +
 
 +
parameters:
 +
  user_key:
 +
    type: string
 +
    description: Key ID or name
 +
    default: uni_pb
 +
  security_groups:
 +
    type: string
 +
    description: Security Group
 +
  network:
 +
    type: string
 +
    description: Network
 +
  subnet:
 +
    type: string
 +
    description: Subnet ID or name
 +
  pool:
 +
    type: string
 +
    description: Pool ID or name
 +
 
 +
resources:
 +
  dev_config:
 +
    type: OS::Heat::CloudConfig
 +
    properties:
 +
      cloud_config:
 +
        hostname: kochbuch-server
 +
        manage_etc_hosts: localhost
 +
        package_update: true
 +
        package_upgrade: true
 +
        packages:
 +
          - apache2
 +
          - php7.2
 +
        runcmd:
 +
          - "sh -c 'hostname -I > /var/www/html/index.html'"
 +
        final_message: "The system is finally up, after $UPTIME seconds"
 +
 
 +
  web_server:
 +
    type: OS::Nova::Server
 +
    properties:
 +
      flavor: upb-medium
 +
      image: c315dc8d-8a9a-499d-a03e-9988d246bb77
 +
      key_name: { get_param: user_key }
 +
      security_groups:
 +
        - { get_param: security_groups }
 +
      networks:
 +
        - network: { get_param: network }
 +
        - subnet: { get_param: subnet }
 +
      user_data: { get_resource: dev_config }
 +
      user_data_format: RAW
 +
 
 +
  member:
 +
    type: OS::Octavia::PoolMember
 +
    properties:
 +
      pool: {get_param: pool}
 +
      address: { get_attr: [web_server, first_address] }
 +
      protocol_port: 80
 +
      subnet: { get_param: subnet }
 +
</source>
 +
 
 +
== Vorlagen Generator ==
 +
Sie haben in der Weboberfläche von Openstack auch die Möglichkeit Templates mit einem Vorlagengenerator grafisch gestützt zu erzeugen. Den Vorlagengenerator finden Sie untern ''Orchestrierung/[https://rdi-cloud.uni-paderborn.de/project/template_generator/ Vorlagengenerator]''.
 +
Eine kurze Anleitung zur Nutzung des Generators finden Sie im [https://docs.openstack.org/heat-dashboard/latest/user/template_generator.html# OpenStack Wiki].

Aktuelle Version vom 23. Juni 2021, 11:39 Uhr

Anleitung
Allgemeine Informationen
Informationen
Betriebssystem Alle
Service Cloudcomputing
Interessant für Angestellte, Studierende und Gäste
HilfeWiki des IMT der Uni Paderborn
no displaytitle found: Cloudcomputing Kochbuch Orchestrierung

In diesem Artikel erfahren Sie, wie Sie mithilfe der HEAT-Komponente von OpenStack einen eigenen IaC (Infrastructure as Code) Stack erstellen, testen und starten.

Rezepte

Anlegen einer Vorlage

Die Konfiguration des Stacks erfolgt nicht wie in den anderen Artikel dieses Bereiches beschrieben über die Weboberfläche oder den Kommandozeilen-Client, sondern wird mithilfe von Templates erstellt. Die Templates werden als HOT (Heat Orchestration Templates) bezeichnet und werden in YAML verfasst. Es werden grundsätzlich vier Dinge definiert:

Typ Beschreibung
heat_template_version Die Version des erstellten Templates
parameters Variablen, die im laufe des Scripts wieder aufgerufen werden können (z.B. Schlüsselpaare, Flavor)
resources Ressourcen, die durch das Template erstellt werden sollen (z.B. Virtuelle Maschinen, Netzwerke)
outputs Ausgaben, die nach der Erstellung einsehbar seien sollen (z.B. Floating-IPs)

Die verfügbaren Heat Template Versionen können Sie in der Weboberfläche unter Orchestrierung/Vorlagenversionen einsehen. Hier ist zu empfehlen, dass Sie die neuste Version verwenden, da hier üblicherweise die beste Kompatibilität gewährleistet ist. Unter Ressourcentypen finden Sie dort auch eine Auflistung der verfügbaren Ressourcen, welche Sie in Ihrem Template definieren können. Wenn Sie auf den Namen einer Ressource klicken, gelangen Sie zu der Hilfeseite der jeweiligen Ressource, hier werden Ihnen die verfügbare Parameter kurz erklärt.

Als ersten Beispiel finden Sie hier ein einfaches Template, in dem zunächst eine Instanz mit Netzwerkport und Floating IP erstellt wird. Speichern Sie ihr Template als .yaml Datei ab.

heat_template_version: 2018-08-31
description: A simple HOT

parameters:
  flavor:
    type: string
    description: Flavor used by the server
    default: upb-medium
  image:
    type: string
    description: Image used for server
    default: c315dc8d-8a9a-499d-a03e-9988d246bb77
  user_key:
    type: string
    description: SSH key to connect to the server
  network:
    type: string
    description: The network for the server
    default: uni
  subnet:
    type: string
    description: The subnet for the server
    default: uni-subnet-0
  floating_ip_id:
    type: string
    description: ID of the Floating IP to use

resources:
  webserver:
    type: OS::Nova::Server
    properties:
      flavor: { get_param: flavor }
      image: { get_param: image }
      key_name: { get_param: user_key }
      networks:
        - port: { get_resource: webserver_port }

  webserver_port:
    type: OS::Neutron::Port
    properties:
      network: { get_param: network }
      fixed_ips:
        - subnet: { get_param: subnet }
      security_groups: [{ get_resource: webserver_security_group }]

  webserver_floating_ip:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_param: floating_ip_id }
      port_id: { get_resource: webserver_port }

  webserver_security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      description: Add security group rules for server
      name: security-group
      rules:
        - remote_ip_prefix: 0.0.0.0/0
          protocol: tcp
          port_range_min: 22
          port_range_max: 22
        - remote_ip_prefix: 0.0.0.0/0
          protocol: icmp

outputs:
  server_private_ip:
    description: IP address of the server in private network
    value: { get_attr: [ webserver, first_address ] }

Hier wird im oberen Teil zunächst die Template Version festgelegt und eine kurze Beschreibung zum Template gegeben, danach folgt der Punkt parameters. Die Parameter können beim Deployment des Stacks mit angegeben und bieten so die Möglichkeit z.B. den Flavor einer VM oder ein eigenes Schlüsselpaar einzugeben. Die Struktur der Parameter ist dabei immer die selbe:

Name_des_Parameters:
    type: Typ des Parameter (string, number, boolean)
    description: Beschreibung des Parameters
    default: Standardwert, falls keine Eingabe gemacht wird

Anschließend folgt die Definition der Ressourcen. Auch hier geben Sie zunächst den Namen und den Typ der Ressource an. Der Typ gibt an, welches Modul von Openstack angesprochen werden soll. Eine Übersicht der verfügbaren Ressourcen erhalten Sie unter Ressourcentypen. Abhängig von der Ressource ändern sich die möglichen Eigenschaften. Mithilfe der Funktionen get_param, get_ressource und get_attr können Sie innerhalb des Templates auf die jeweiligen Werte referenzieren. Diese müssen nicht zwingend vorher definiert sein, sondern können auch im Script hinter dem Aufruf stehen.

Name_der_Ressource:
    type: Typ der Ressource
    properties: Auflistung der Eigenschaften
      Eigenschaft_1: Wert
      Eigenschaft_2: Wert

Am Ende des Templates werden die Ausgaben definiert. Mithilfe der Funktion get_attr können Sie auf Attribute einer Ressource zugreifen und diese in der Übersicht des Stacks ausgeben. Die möglichen Attribute finden Sie in der Übersicht der Ressourcentypen, wenn Sie auf den Namen der Ressource klicken.

outputs:
  Name_der_Ausgabe:
    description: Beschreibung der Ausgabe
    value: { get_attr: [ Ressource, Attribut ] }

Einen Stack erstellen und starten

Um einen Stack zu starten können Sie auf der Weboberfläche unter Orchestrierung/Stacks auf den Button Stack starten klicken. Wählen Sie unter Vorlagenquelle ihre erstellte .yaml-Datei aus und klicken Sie auf Weiter.

Vorlage auswählen

Im nächsten Dialogfenster müssen Sie zunächst einen Namen und ein Passwort für den Stack vergeben, danach werden ihre im Template definierten Parameter aufgeführt, welche Sie an dieser Stelle eingeben können. Klicken Sie zum erstellen des Stacks auf Starten.

Parameter eingeben

Stacks lassen sich auch mithilfe des Kommandozeilen-Clients starten. Verwenden Sie dafür folgendes Schema:

openstack stack create --template stack.yaml --parameter "parameter_1=wert" --parameter "parameter_2=wert" NameDesStacks

Mit der Option --dry-run können Sie die Template Datei zuerst testen, ohne den Stack zu erstellen.

Die Erstellung kann je nach Größe des Stacks einige Minuten in Anspruch nehmen. Den aktuellen Status der Erstellung können Sie auf der Übersichtsseite des Stack sehen. Klicken Sie dazu in der Übersicht unter Orchestrierung/Stacks auf den Namen des Stacks.

Openstack erstellt automatisch eine grafische Übersicht des Stack. In der oberen Menüleiste wählen Sie den Punkt Ressourcen, hier wird ihnen der Status der einzelnen Ressourcen des Stacks angezeigt und unter Veranstaltungen werden die letzten Ereignisse angezeigt. Falls es beim erstellen des Stacks zu Fehlern kommt, werden diese hier angezeigt.

Einen Stack aktualisieren

Wollen Sie einen Stack aktualisieren, müssen Sie dazu im Kontextmenü, welches sich rechts neben dem Namen des Stack befinden, den Punkt Ändern der Stack-Vorlage wählen. Wählen Sie hier, wie beim Erstellen des Stacks, das neue Template aus und klicken auf Weiter. Geben Sie ihre Parameter an und klicken anschließend auf Aktualisieren.

Openstack schaut nun, welche Parameter und Ressourcen sich geändert haben und nimmt entsprechend Änderungen am Stack vor. Manche dieser Änderungen können im laufenden Betrieb erfolgen, für andere müssen Teile des Stacks neu erstellt werden. Dazu bietet das Openstack Wiki Hinweise bei den jeweiligen Parameter mit Can be updated without replacement oder Updates cause replacement.

Einen Stack löschen

Wollen Sie einen Stack löschen, müssen Sie dazu auf Stack löschen im Kontextmenü rechts neben dem Namen des Stacks klicken. Die Löschung kann je nach Größe des Stacks einige Minuten in Anspruch nehmen.

Instanzen per Cloud-Config konfigurieren

In den meisten Fällen wird es notwendig sein, Instanzen während oder nach dem Start zu konfigurieren. Dies geschieht mithilfe des Cloud-Init Dienstes. Dieser kann in einer separaten cloud-config.yaml-Datei liegen oder direkt in der Template-Datei verfasst werden.

Mithilfe des Cloud-Init Dienstes können Sie unteranderem:

  • das System aktualisieren
  • Softwarepackete installieren
  • Benutzer und Gruppen erstellen
  • Dateien und Verzeichnisse anlegen
  • Git Repositories klonen
  • Nutzerdaten einspielen
  • Zertifikate hinterlegen
  • Datenträger formatieren


und noch vieles mehr. Einige Beispiele einer cloud-config.yaml-Datei finden Sie im Cloud-Init Wiki. In vielen fällen lassen sich so aufwendige Shell-Scripte vermeiden.

In einem Heat-Template können Sie die eine Cloud-Config als Ressource mit der Komponente OS::Heat::CloudConfig anlegen und diese bei der Instanz unter user_data mit get_resource wieder aufrufen.

resources:
  dev_config:
    type: OS::Heat::CloudConfig
    properties:
      cloud_config:
        hostname: kochbuch-server
        manage_etc_hosts: localhost
        package_update: true
        package_upgrade: true
        packages:
          - apache2
        runcmd:
          - sh -c 'hostname -I > /var/www/html/index.html'
        final_message: "The system is finally up, after $UPTIME seconds"

  web_server:
    type: OS::Nova::Server
    properties:
      flavor: upb-medium
      image: c315dc8d-8a9a-499d-a03e-9988d246bb77
      key_name: { get_param: user_key }
      user_data: { get_resource: devstack_config }
      user_data_format: RAW

Folgendes wird in der cloud_config festgelgt:

Eigenschaft Wert
hostname Legt den Hostnamen der Instanz fest
manage_etc_hosts Stellt mit der Einstellung localhost sicher, dass Cloud-Init neue Eintrage am Ende der Datei schreibt
package_update Nach Updates suchen
package_upgrade Verfügbare Updates installieren
packages Liste der Pakete die installiert werden sollen
runcmd Liste von Kommandos die ausgeführt werden sollen
final_message Ausgabe einer Nachricht am Ende des Scripts


Praxisbeispiel Autoscaling Group mit Loadbalancer

Nachfolgend finden Sie noch ein Beispiel einer Umfangreicheren Konfiguration eines Stacks. Bei dem ersten Template (Stack.yaml) wird über einen Loadbalancer eine selbsskalierende Gruppe von Instanzen gesteuert, über die ein Webserver bereitgestellt wird. Zusätzlich wird ein Netzwerk und die für den Loadbalancer nötigen Ressourcen (Pool, Monitor, etc) angelegt. Der Loadbalancer bekommt zum Schluss eine Floating IP zugeteilt und abschließend werden noch die URLs ausgegeben, über welche die Autoscaling Group hoch- bzw. herunter skaliert werden können.

Für die einzelnen Instanzen der Autoscaling Group wurde ein separates Template angelegt (lb_member.yaml), in dem auch gleichzeitig die Konfiguration über cloud-config erfolgt. Diese Instanzen werden dann als Member dem Loadbalancer zugeteilt.

Stack.yaml

heat_template_version: 2018-08-31
description: A load-balancer webserver

parameters:
  public_net_id:
    type: string
    description: Public network ID
    default: external
  timeout:
    type: number
    description: Timeout for stack creation to finish
    default: 900
  floatingip_ID:
    type: string
    description: Floating IP to associate
  user_key:
    type: string
    description: Key ID or name

resources:
  server_security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      description: Neutron security group rules
      name: kochbuch_security_group
      rules:
      - remote_mode: 'remote_group_id'
        direction: ingress
      - remote_ip_prefix: 0.0.0.0/0
        protocol: icmp
      - remote_ip_prefix: 0.0.0.0/0
        protocol: tcp
        direction: ingress
        port_range_min: 22
        port_range_max: 22
      - remote_ip_prefix: 0.0.0.0/0
        protocol: tcp
        direction: ingress
        port_range_min: 80
        port_range_max: 80

  kochbuch_net:
    type: OS::Neutron::Net
    properties:
      name: kochbuch-net

  kochbuch_sub_net:
    type: OS::Neutron::Subnet
    properties:
      name: kochbuch-sub-net
      network_id: { get_resource: kochbuch_net }
      cidr: 192.168.0.0/24
      gateway_ip: 192.168.0.1
      enable_dhcp: true
      allocation_pools:
        - start: "192.168.0.2"
          end: "192.168.0.50"

  router:
    type: OS::Neutron::Router

  router_gateway:
    type: OS::Neutron::RouterGateway
    properties:
      router_id: { get_resource: router }
      network_id: { get_param: public_net_id }

  router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: router }
      subnet_id: { get_resource: kochbuch_sub_net }

  monitor:
    type: OS::Octavia::HealthMonitor
    properties:
      delay: 3
      type: HTTP
      http_method: GET
      expected_codes: 200
      timeout: 3
      max_retries: 3
      pool: { get_resource: pool }

  pool:
    type: OS::Octavia::Pool
    properties:
      lb_algorithm: ROUND_ROBIN
      protocol: HTTP
      listener: { get_resource: listener }
      loadbalancer: { get_resource: loadbalancer }

  listener:
    type: OS::Octavia::Listener
    properties:
      loadbalancer: { get_resource: loadbalancer }
      protocol: HTTP
      protocol_port: 80

  loadbalancer:
    type: OS::Octavia::LoadBalancer
    properties:
      vip_subnet: { get_resource: kochbuch_sub_net }

  kochbuch_asg:
    type: OS::Heat::AutoScalingGroup
    properties:
      min_size: 1
      desired_capacity: 3
      max_size: 5
      resource:
        type: lb_member.yaml
        properties:
          user_key: { get_param: user_key }
          security_groups: { get_resource: server_security_group }
          network: { get_resource: kochbuch_net }
          subnet: { get_resource: kochbuch_sub_net }
          pool: {get_resource: pool}

  web_server_scaleup_policy:
    type: OS::Heat::ScalingPolicy
    properties:
      adjustment_type: change_in_capacity
      auto_scaling_group_id: { get_resource: kochbuch_asg }
      cooldown: 60
      scaling_adjustment: 1

  web_server_scaledown_policy:
    type: OS::Heat::ScalingPolicy
    properties:
      adjustment_type: change_in_capacity
      auto_scaling_group_id: { get_resource: kochbuch_asg }
      cooldown: 60
      scaling_adjustment: '-1'

  cpu_alarm_high:
    type: OS::Aodh::GnocchiAggregationByResourcesAlarm
    properties:
      description: Scale up if CPU > 75%
      metric: cpu_util
      aggregation_method: mean
      granularity: 600
      evaluation_periods: 1
      threshold: 75
      resource_type: instance
      comparison_operator: gt
      alarm_actions:
        - str_replace:
            template: trust+url
            params:
              url: { get_attr: [web_server_scaleup_policy, signal_url] }
      query:
        list_join:
          - ''
          - - { '=': { server_group: { get_param: "OS::stack_id" } } }

  cpu_alarm_low:
    type: OS::Aodh::GnocchiAggregationByResourcesAlarm
    properties:
      description: Scale down if CPU < 15%
      metric: cpu_util
      aggregation_method: mean
      granularity: 600
      evaluation_periods: 1
      threshold: 15
      resource_type: instance
      comparison_operator: lt
      alarm_actions:
        - str_replace:
            template: trust+url
            params:
              url: {get_attr: [web_server_scaledown_policy, signal_url]}
      query:
        list_join:
          - ''
          - - { '=': { server_group: { get_param: "OS::stack_id" } } }

  lb_floating_ip:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_param: floatingip_ID }
      port_id: { get_attr: [loadbalancer, vip_port_id ]}

outputs:
  scale_up_url:
    description: This URL is the webhook to scale up the group.
    value: { get_attr: [web_server_scaleup_policy, alarm_url] }
  scale_dn_url:
    description: This URL is the webhook to scale down the group.
    value: { get_attr: [web_server_scaledown_policy, alarm_url] }

lb_member.yaml

heat_template_version: 2018-08-31

parameters:
  user_key:
    type: string
    description: Key ID or name
    default: uni_pb
  security_groups:
    type: string
    description: Security Group
  network:
    type: string
    description: Network
  subnet:
    type: string
    description: Subnet ID or name
  pool:
    type: string
    description: Pool ID or name

resources:
  dev_config:
    type: OS::Heat::CloudConfig
    properties:
      cloud_config:
        hostname: kochbuch-server
        manage_etc_hosts: localhost
        package_update: true
        package_upgrade: true
        packages:
          - apache2
          - php7.2
        runcmd:
          - "sh -c 'hostname -I > /var/www/html/index.html'"
        final_message: "The system is finally up, after $UPTIME seconds"
  
  web_server:
    type: OS::Nova::Server
    properties:
      flavor: upb-medium
      image: c315dc8d-8a9a-499d-a03e-9988d246bb77
      key_name: { get_param: user_key }
      security_groups:
        - { get_param: security_groups }
      networks: 
        - network: { get_param: network }
        - subnet: { get_param: subnet }
      user_data: { get_resource: dev_config }
      user_data_format: RAW

  member:
    type: OS::Octavia::PoolMember
    properties:
      pool: {get_param: pool}
      address: { get_attr: [web_server, first_address] }
      protocol_port: 80
      subnet: { get_param: subnet }

Vorlagen Generator

Sie haben in der Weboberfläche von Openstack auch die Möglichkeit Templates mit einem Vorlagengenerator grafisch gestützt zu erzeugen. Den Vorlagengenerator finden Sie untern Orchestrierung/Vorlagengenerator. Eine kurze Anleitung zur Nutzung des Generators finden Sie im OpenStack Wiki.


Bei Fragen oder Problemen wenden Sie sich bitte telefonisch oder per E-Mail an uns:

Tel. IT: +49 (5251) 60-5544 Tel. Medien: +49 (5251) 60-2821 E-Mail: imt@uni-paderborn.de

Der Servicepoint ist aktuell im Notebook-Café zu finden

Das IMT:Notebook-Café (Raum I0.401) bietet derzeit eingeschränkten Support und hat Montags bis Donnerstags von 08:30 - 16:00 Uhr und Freitags 08:30 - 15:00 Uhr geöffnet. Bitte beachten Sie die derzeit geltenden Hygienebestimmungen.

Das IMT:Servicecenter Medien auf H1 hat aktuell Montags bis Donnerstags von 8:00 - 16:00 Uhr und Freitags von 8:00 - 14:00 Uhr geöffnet.