Fujitsu K5 Infrastructure as Code (Cookie Cutter)
2017-03-10
Machine-translated — the English original is authoritative.
Meine neueste Herausforderung bestand darin, einen Prozess zur Bereitstellung eines vordefinierten Infrastrukturmodells – ein einfaches Netzwerk mit 3 Knoten – in einer konsistenten und wiederholbaren Weise zu entwickeln. Dieses Modell musste jedoch in jeder Geschmacksrichtung (Flavor) mit unterschiedlichen Konfigurationen bereitgestellt werden.
Im Grunde wollte ein Kunde einen wiederholbaren Mechanismus, um die verschiedenen Knoten-Geschmacksrichtungen im großen Maßstab zu Leistungstests zu verwenden.
Wir hätten einfach auf den vorherigen HEAT-Beispielen aufbauen und eine massive YAML-Vorlage schreiben können, die die erforderliche Infrastruktur enthält. Dies ist jedoch fehleranfällig, schwer zu debuggen und weder sehr effizient noch flexibel.
Was wir benötigen, ist die Trennung der statischen und dynamischen Infrastrukturkomponenten – eine Vorlage zu definieren, die den statischen Komponenten entspricht und es ermöglicht, die dynamischen Komponenten als Parameter zu übergeben. Jeder Programmierer kennt das DRY-Code-Prinzip (Don’t Repeat Yourself – Wiederhole dich nicht) – das Gleiche gilt hier.
Da wir in ein Projekt mit bestehender Infrastruktur bereitstellten, habe ich auch einige dieser Details als Eingabeparameter an den Heat-Stack übergeben – z. B. routerId, kpName.
Die grundlegende Infrastrukturvorlage sah wie folgt aus:
Diese Datei enthält versteckte oder bidirektionale Unicode-Zeichen, die anders interpretiert oder kompiliert werden könnten als das, was unten angezeigt wird. Um sie zu überprüfen, öffnen Sie die Datei in einem Editor, der versteckte Unicode-Zeichen anzeigt.
Erfahren Sie mehr über bidirektionale Unicode-Zeichen
| heat_template_version: 2013-05-23 | |
| # Autor: Graham Land | |
| # Datum: 08/03/2017 | |
| # Zweck: Fujitsu K5 OpenStack IaaS Heat-Vorlage, die 3 Server in einem neuen Netzwerk bereitstellt und das Netzwerk an einen bestimmten Router anschließt. | |
| # Eingabeparameter – | |
| # routerId – eindeutige ID des Routers, an den das Netzwerk angeschlossen werden soll | |
| # imageName – das zu bereitstellende Betriebssystem-Image | |
| # flavorName – die vCPU- und RAM-Größe der Server | |
| # dataVolume – die Größe des an die Server anzuschließenden Datenvolumens | |
| # cidr – Details zur privaten Netzwerk-IP-Adresse | |
| # azName – die Verfügbarkeitszone, in der die Server bereitgestellt werden sollen – dies muss offensichtlich mit dem Speicherort des Routers übereinstimmen | |
| # kpName – der Name eines vorhandenen SSH-Schlüsselpaares, das in der Verfügbarkeitszone verwendet werden soll | |
| # | |
| # | |
| # Ausgabeparameter – die IP-Adressen der 3 Server | |
| # | |
| # Twitter: @allthingsclowd | |
| # Blog: https://allthingscloud.eu | |
| # | |
| description: Fujitsu K5 OpenStack IaaS Heat-Vorlage, die 3 Server in einem neuen Netzwerk bereitstellt und das Netzwerk an einen bestimmten Router anschließt. | |
| # Eingabeparameter | |
| parameters: | |
| imageName: | |
| type: string | |
| label: Image-Name oder ID | |
| description: Zu verwendendes Image für die Compute-Instanz | |
| default: "Ubuntu Server 14.04 LTS (Englisch) 02" | |
| flavorName: | |
| type: string | |
| label: Flavor | |
| description: X vCPU und XXXXMB RAM | |
| default: "T-1" | |
| kpName: | |
| type: string | |
| label: Schlüsselname | |
| description: Name des für die Compute-Instanz zu verwendenden Schlüsselpaares | |
| default: "k5-loadtest-az1" | |
| cidr: | |
| type: string | |
| label: IP-Adressdetails | |
| description: Netzwerk-Adressbereich | |
| default: "10.99.99.0/24" | |
| dataVolume: | |
| type: string | |
| label: Volumengröße | |
| description: Größe in GB des an den Server anzuschließenden Datenvolumens | |
| default: "3" | |
| osVolume: | |
| type: string | |
| label: Volumengröße | |
| description: Größe in GB des an den Server anzuschließenden OS-Volumens | |
| default: "20" | |
| azName: | |
| type: string | |
| label: Verfügbarkeitszone | |
| description: Zu verwendende Region-AZ | |
| default: "uk-1a" | |
| securityGroup: | |
| type: string | |
| label: Vorhandener K5-Sicherheitsgruppenname | |
| description: Projekt-Sicherheitsgruppe | |
| default: "demosecuritygroup" | |
| routerId: | |
| type: string | |
| label: Externer Router | |
| description: Router mit externem Zugriff für die globale IP-Zuweisung | |
| default: "fcb1dddc-e0c8-4dd5-8a3f-4eee3b042912" | |
| # K5-Infrastrukturressourcen, die erstellt werden sollen | |
| resources: | |
| ############################ Netzwerkressourcen #################### | |
| # Erstellen Sie ein privates Netzwerk in der Verfügbarkeitszone | |
| demostack_private_net : | |
| type: OS::Neutron::Net | |
| properties: | |
| name: "private" | |
| availability_zone: { get_param: azName} | |
| # Erstellen Sie ein neues Subnetz im privaten Netzwerk | |
| demostack_private_subnet : | |
| type: OS::Neutron::Subnet | |
| depends_on: demostack_private_net | |
| properties: | |
| availability_zone: { get_param: azName} | |
| network_id: { get_resource: demostack_private_net } | |
| cidr: { get_param: cidr} | |
| dns_nameservers: ["62.60.39.9", "62.60.39.10"] | |
| # Schließen Sie eine Schnittstelle im Subnetz des demostacks-Netzwerks an den Router an | |
| router_interface: | |
| type: OS::Neutron::RouterInterface | |
| depends_on: [demostack_private_subnet ] | |
| properties: | |
| router_id: { get_param: routerId } | |
| subnet_id: { get_resource: demostack_private_subnet } | |
| ################## Server-Ressourcen ########################### | |
| ################################ Server erstellen demo-mgmt1-server ############################## | |
| # Erstellen Sie ein Datenvolumen zur Verwendung mit dem Server | |
| demo-mgmt1-server-data-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| description: Datenspeicher | |
| size: { get_param: dataVolume} | |
| volume_type: "M1" | |
| # Erstellen Sie ein Systemvolumen zur Verwendung mit dem Server | |
| demo-mgmt1-server-sys-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| size: { get_param: osVolume} | |
| volume_type: "M1" | |
| image : { get_param: imageName } | |
| # Erstellen Sie einen Server unter Verwendung des oben definierten Systemvolumens | |
| demo-mgmt1-server: | |
| type: OS::Nova::Server | |
| depends_on: [ demostack_private_subnet ] | |
| properties: | |
| key_name: { get_param: kpName } | |
| image: { get_param: imageName } | |
| flavor: { get_param: flavorName } | |
| security_groups: [{get_param: securityGroup}] | |
| block_device_mapping: [{"volume_size": { get_param: osVolume}, "volume_id": {get_resource: demo-mgmt1-server-sys-vol}, "delete_on_termination": True, "device_name": "/dev/vda"}] | |
| admin_user: "ubuntu" | |
| metadata: { "fcx.autofailover": True, "Example Custom Tag": "Multiple Server Build" } | |
| user_data: | |
| str_replace: | |
| template: | |
| #cloud-config | |
| write_files: | |
| – content: | |
| #!/bin/bash | |
| voldata_id=%voldata_id% | |
| voldata_dev="/dev/disk/by-id/virtio-$(echo ${voldata_id} | |
| mkfs.ext4 ${voldata_dev} | |
| mkdir -pv /mnt/appdata | |
| echo "${voldata_dev} /mnt/appdata ext4 defaults 1 2" >> /etc/fstab | |
| mount /mnt/appdata | |
| chmod 0777 /mnt/appdata | |
| path: /tmp/format-disks | |
| permissions: '0700' | |
| runcmd: | |
| – /tmp/format-disks | |
| params: | |
| "%voldata_id%": { get_resource: demo-mgmt1-server-data-vol } | |
| user_data_format: RAW | |
| networks: ["uuid": {get_resource: demostack_private_net} ] | |
| # Schließen Sie das zuvor definierte Datenvolumen an den Server an | |
| attach-demo-mgmt1-server-data-vol: | |
| type: OS::Cinder::VolumeAttachment | |
| depends_on: [ demo-mgmt1-server-data-vol, demo-mgmt1-server ] | |
| properties: | |
| instance_uuid: {get_resource: demo-mgmt1-server} | |
| mountpoint: "/dev/vdb" | |
| volume_id: {get_resource: demo-mgmt1-server-data-vol} | |
| ################################ Server erstellen demo-mgmt2-server ############################## | |
| # Erstellen Sie ein Datenvolumen zur Verwendung mit dem Server | |
| demo-mgmt2-server-data-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| description: Datenspeicher | |
| size: { get_param: dataVolume} | |
| volume_type: "M1" | |
| # Erstellen Sie ein Systemvolumen zur Verwendung mit dem Server | |
| demo-mgmt2-server-sys-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| size: { get_param: osVolume} | |
| volume_type: "M1" | |
| image : { get_param: imageName } | |
| # Erstellen Sie einen Server unter Verwendung des oben definierten Systemvolumens | |
| demo-mgmt2-server: | |
| type: OS::Nova::Server | |
| depends_on: [ demostack_private_subnet ] | |
| properties: | |
| key_name: { get_param: kpName } | |
| image: { get_param: imageName } | |
| flavor: { get_param: flavorName } | |
| block_device_mapping: [{"volume_size": { get_param: osVolume}, "volume_id": {get_resource: demo-mgmt2-server-sys-vol}, "delete_on_termination": True, "device_name": "/dev/vda"}] | |
| admin_user: "ubuntu" | |
| security_groups: [{get_param: securityGroup}] | |
| metadata: { "fcx.autofailover": True, "Example Custom Tag": "Multiple Server Build" } | |
| user_data: | |
| str_replace: | |
| template: | |
| #cloud-config | |
| write_files: | |
| – content: | |
| #!/bin/bash | |
| voldata_id=%voldata_id% | |
| voldata_dev="/dev/disk/by-id/virtio-$(echo ${voldata_id} | |
| mkfs.ext4 ${voldata_dev} | |
| mkdir -pv /mnt/appdata | |
| echo "${voldata_dev} /mnt/appdata ext4 defaults 1 2" >> /etc/fstab | |
| mount /mnt/appdata | |
| chmod 0777 /mnt/appdata | |
| path: /tmp/format-disks | |
| permissions: '0700' | |
| runcmd: | |
| – /tmp/format-disks | |
| params: | |
| "%voldata_id%": { get_resource: demo-mgmt2-server-data-vol } | |
| user_data_format: RAW | |
| networks: ["uuid": {get_resource: demostack_private_net} ] | |
| # Schließen Sie das zuvor definierte Datenvolumen an den Server an | |
| attach-demo-mgmt2-server-data-vol: | |
| type: OS::Cinder::VolumeAttachment | |
| depends_on: [ demo-mgmt2-server-data-vol, demo-mgmt2-server ] | |
| properties: | |
| instance_uuid: {get_resource: demo-mgmt2-server} | |
| mountpoint: "/dev/vdb" | |
| volume_id: {get_resource: demo-mgmt2-server-data-vol} | |
| ################################ Server erstellen demo-mgmt3-server ############################## | |
| # Erstellen Sie ein Datenvolumen zur Verwendung mit dem Server | |
| demo-mgmt3-server-data-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| description: Datenspeicher | |
| size: { get_param: dataVolume} | |
| volume_type: "M1" | |
| # Erstellen Sie ein Systemvolumen zur Verwendung mit dem Server | |
| demo-mgmt3-server-sys-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| size: { get_param: osVolume} | |
| volume_type: "M1" | |
| image : { get_param: imageName } | |
| # Erstellen Sie einen Server unter Verwendung des oben definierten Systemvolumens | |
| demo-mgmt3-server: | |
| type: OS::Nova::Server | |
| depends_on: [ demostack_private_subnet ] | |
| properties: | |
| key_name: { get_param: kpName } | |
| image: { get_param: imageName } | |
| flavor: { get_param: flavorName } | |
| block_device_mapping: [{"volume_size": { get_param: osVolume}, "volume_id": {get_resource: demo-mgmt3-server-sys-vol}, "delete_on_termination": True, "device_name": "/dev/vda"}] | |
| admin_user: "ubuntu" | |
| security_groups: [{get_param: securityGroup}] | |
| metadata: { "fcx.autofailover": True, "Example Custom Tag": "Multiple Server Build" } | |
| user_data: | |
| str_replace: | |
| template: | |
| #cloud-config | |
| write_files: | |
| – content: | |
| #!/bin/bash | |
| voldata_id=%voldata_id% | |
| voldata_dev="/dev/disk/by-id/virtio-$(echo ${voldata_id} | |
| mkfs.ext4 ${voldata_dev} | |
| mkdir -pv /mnt/appdata | |
| echo "${voldata_dev} /mnt/appdata ext4 defaults 1 2" >> /etc/fstab | |
| mount /mnt/appdata | |
| chmod 0777 /mnt/appdata | |
| path: /tmp/format-disks | |
| permissions: '0700' | |
| runcmd: | |
| – /tmp/format-disks | |
| params: | |
| "%voldata_id%": { get_resource: demo-mgmt3-server-data-vol } | |
| user_data_format: RAW | |
| networks: ["uuid": {get_resource: demostack_private_net} ] | |
| # Schließen Sie das zuvor definierte Datenvolumen an den Server an | |
| attach-demo-mgmt3-server-data-vol: | |
| type: OS::Cinder::VolumeAttachment | |
| depends_on: [ demo-mgmt3-server-data-vol, demo-mgmt3-server ] | |
| properties: | |
| instance_uuid: {get_resource: demo-mgmt3-server} | |
| mountpoint: "/dev/vdb" | |
| volume_id: {get_resource: demo-mgmt3-server-data-vol} | |
| outputs: | |
| server1_ip: | |
| description: Dem Server 1 zugewiesene feste IP | |
| value: { get_attr: [demo-mgmt1-server, networks, "private", 0]} | |
| server2_ip: | |
| description: Dem Server 2 zugewiesene feste IP | |
| value: { get_attr: [demo-mgmt2-server, networks, "private", 0]} | |
| server3_ip: | |
| description: Dem Server 3 zugewiesene feste IP | |
| value: { get_attr: [demo-mgmt3-server, networks, "private", 0]} |
Rohansicht
simple_3_node_template.yml
Gehostet mit ❤ von GitHub
Nun, da wir unsere Infrastructure as Code haben, wie können wir sie im großen Maßstab bereitstellen, während wir die Eingabeparameter ändern? Nun, hier kommt die „API Economy“ ins Spiel. Fujitsu K5 basiert auf OpenStack, einer API-first-Plattform – in einfachen Worten bedeutet dies, dass die Plattform zu 100 % über API-Interaktionen gesteuert werden kann….immer noch verwirrt? Ich kann mehr Code verwenden!
Ich kann die oben genannte Heat-Vorlage zusammen mit den verschiedenen Parametersätzen an die Orchestrierungs-Engine von K5 senden, indem ich ein Python-Skript verwende, das die Daten an den Orchestrierungs-Endpunkt sendet.
Diese Datei enthält versteckte oder bidirektionale Unicode-Zeichen, die anders interpretiert oder kompiliert werden könnten als das, was unten angezeigt wird. Um sie zu überprüfen, öffnen Sie die Datei in einem Editor, der versteckte Unicode-Zeichen anzeigt.
Erfahren Sie mehr über bidirektionale Unicode-Zeichen
| def deploy_heat_stack(k5token, stack_name, stack_to_deploy, stack_parameters): | |
| """Zusammenfassung: K5 HEAT API-Aufruf, um einen Heat-Stack, eingebettet in einen String, an ein K5-Projekt zu senden | |
| Gibt zurück: | |
| TYP: JSON-Objekt, das die neue Stack-ID oder Fehlercodes enthält | |
| """ | |
| orchestrationURL = unicode(get_endpoint(k5token, "orchestration")) + unicode("/stacks") | |
| print orchestrationURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(orchestrationURL, | |
| headers={ | |
| 'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'}, | |
| json={ | |
| "files": {}, | |
| "disable_rollback": True, | |
| "parameters": stack_parameters, | |
| "stack_name": stack_name, | |
| "template": stack_to_deploy, | |
| "timeout_mins": 60 | |
| }) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) |
Rohansicht
Deploy_Heat_Stack.py
Gehostet mit ❤ von GitHub
Der Vorteil hierbei ist, dass der gesamte Prozess nun in Code definiert ist – und dies kann problemlos versioniert werden, was konsistente Bereitstellungen garantiert.
Die vollständige Version dieser Lösung kann hier ausgecheckt werden: https://github.com/allthingsclowd/Fujitsu_OpenStack_K5_Heat_Cookie_Cutter
K5_Stack_Deployer – OpenStack-Vorlage
Autor: Graham Land
Datum: 08/03/17
Twitter: @allthingsclowd
Github: https://github.com/allthingscloud
Blog: https://allthingscloud.eu
deploy_stacks.py
Dieses Skript demonstriert, wie eine OpenStack HEAT-Vorlage
mehrmals mit unterschiedlichen Parametern bei jedem Aufruf bereitgestellt wird.
k5regionapiv1.py
Diese Datei wird von deploy_stacks.py importiert und enthält K5/OpenStack API-Funktions-Wrapper.
simple_3_node_stack.py
Diese Datei enthält einfach die YAML HEAT-Stack-Vorlage, eingebettet als String zur Verwendung in Python.
simple_3_node_stack.yml
Ist die native HEAT-Vorlage, die bereitgestellt wird (wird nicht verwendet, nur falls Sie separat damit spielen möchten).
k5contractsettingsV12.py
Sie MÜSSEN diese Datei konfigurieren, um sie an Ihre Umgebung anzupassen, bevor Sie die Bereitstellung durchführen.
Sie enthält einen Abschnitt für die Umgebung und einen Abschnitt für die Anwendung.
Im Abschnitt für die Umgebung geben Sie Ihre K5-Details ein, während im Anwendungsabschnitt die „Batches“ von Parametern konfiguriert werden, die in die Heat-Vorlage eingespeist werden sollen.
Jeder Batch enthält eine Liste von Heat-Vorlagen-Eingabeparametern – jede Parameterliste repräsentiert einen bereitgestellten Heat-Stack.
Link zu Github
https://github.com/allthingsclowd/Fujitsu_OpenStack_K5_Heat_Cookie_Cutter
Rohansicht
K5_Cookie_Cutter.md
Gehostet mit ❤ von GitHub
Viel Spaß beim Stapeln!
withk5youcan
Originally published on allthingscloud.eu (2017-03-10).
