Fujitsu K5 Infrastructure as Code (Cookie Cutter)
2017-03-10
Machine-translated — the English original is authoritative.
Mon dernier défi consistait à développer un processus pour déployer un modèle d’infrastructure prédéfini, un réseau simple avec 3 nœuds, de manière cohérente et reproductible. Cependant, ce modèle devait être déployé dans chaque type de saveur (flavor) avec des configurations de disque différentes.
En substance, un client souhaitait un mécanisme reproductible pour tester les performances des différentes saveurs de nœuds à grande échelle.
Nous aurions pu simplement nous appuyer sur les exemples HEAT précédents et rédiger un modèle YAML massif contenant l’infrastructure requise. Cependant, cette approche est sujette aux erreurs, difficile à déboguer et peu efficace ou flexible.
Ce dont nous avons besoin, c’est de séparer les composants statiques et dynamiques de l’infrastructure – définir un modèle qui correspond aux composants statiques et permet de transmettre les composants dynamiques en tant que paramètres. Tout développeur sera familier avec le principe DRY (Don’t Repeat Yourself – Ne vous répétez pas), ce qui s’applique ici également.
Étant donné que nous déployions dans un projet disposant déjà d’une infrastructure, j’ai également transmis certains de ces détails au tas Heat en tant que paramètres d’entrée – par exemple, routerId, kpName.
Le modèle d’infrastructure de base ressemblait à ceci :
Ce fichier contient des caractères Unicode cachés ou bidirectionnels qui peuvent être interprétés ou compilés différemment de ce qui apparaît ci-dessous. Pour les examiner, ouvrez le fichier dans un éditeur qui révèle les caractères Unicode cachés.
En savoir plus sur les caractères Unicode bidirectionnels
Afficher les caractères cachés
| heat_template_version: 2013-05-23 | |
| # Auteur : Graham Land | |
| # Date : 08/03/2017 | |
| # Objectif : Modèle Heat IaaS OpenStack Fujitsu K5 qui déploie 3 serveurs sur un nouveau réseau et attache le réseau à un routeur donné. | |
| # Paramètres d’entrée – | |
| # routerId – identifiant unique du routeur auquel le réseau doit être attaché | |
| # imageName – l’image OS qui sera déployée | |
| # flavorName – la taille des vCPU et de la RAM des serveurs | |
| # dataVolume – la taille du volume de données à attacher aux serveurs | |
| # cidr – détails de l’adresse IP du réseau privé | |
| # azName – la zone de disponibilité dans laquelle déployer les serveurs – évidemment, cela doit correspondre à l’emplacement du routeur | |
| # kpName – le nom d’une paire de clés SSH existante à utiliser dans la zone de disponibilité | |
| # | |
| # | |
| # Paramètres de sortie – les adresses IP des 3 serveurs | |
| # | |
| # Twitter : @allthingsclowd | |
| # Blog : https://allthingscloud.eu | |
| # | |
| description : Modèle Heat IaaS OpenStack Fujitsu K5 qui déploie 3 serveurs sur un nouveau réseau et attache le réseau à un routeur donné. | |
| # Paramètres d’entrée | |
| parameters: | |
| imageName: | |
| type: string | |
| label: Nom de l’image | |
| description: Image à utiliser pour l’instance de calcul | |
| default: "Ubuntu Server 14.04 LTS (English) 02" | |
| flavorName: | |
| type: string | |
| label: Saveur (Flavor) | |
| description: X vCPU et XXXXMB RAM | |
| default: "T-1" | |
| kpName: | |
| type: string | |
| label: Nom de la clé | |
| description: Nom de la paire de clés à utiliser pour l’instance de calcul | |
| default: "k5-loadtest-az1" | |
| cidr: | |
| type: string | |
| label: Détails de l’adresse IP | |
| description: Plage d’adresses réseau | |
| default: "10.99.99.0/24" | |
| dataVolume: | |
| type: string | |
| label: Taille du volume | |
| description: Taille en Go du volume de données à attacher au serveur | |
| default: "3" | |
| osVolume: | |
| type: string | |
| label: Taille du volume | |
| description: Taille en Go du volume OS à attacher au serveur | |
| default: "20" | |
| azName: | |
| type: string | |
| label: Zone de disponibilité | |
| description: Région AZ à utiliser | |
| default: "uk-1a" | |
| securityGroup: | |
| type: string | |
| label: Nom du groupe de sécurité K5 existant | |
| description: Groupe de sécurité du projet | |
| default: "demosecuritygroup" | |
| routerId: | |
| type: string | |
| label: Routeur externe | |
| description: Routeur avec accès externe pour l’allocation d’IP globale | |
| default: "fcb1dddc-e0c8-4dd5-8a3f-4eee3b042912" | |
| # Ressources d’infrastructure K5 à créer | |
| resources: | |
| ############################ Ressources Réseau #################### | |
| # Créer un réseau privé dans la zone de disponibilité | |
| demostack_private_net : | |
| type: OS::Neutron::Net | |
| properties: | |
| name: "private" | |
| availability_zone: { get_param: azName} | |
| # Créer un nouveau sous-réseau sur le réseau privé | |
| 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"] | |
| # Connecter une interface sur le sous-réseau du réseau demostacks au routeur | |
| router_interface: | |
| type: OS::Neutron::RouterInterface | |
| depends_on: [demostack_private_subnet ] | |
| properties: | |
| router_id: { get_param: routerId } | |
| subnet_id: { get_resource: demostack_private_subnet } | |
| ################## Ressources Serveurs ########################### | |
| ################################ créer le serveur demo-mgmt1-server ############################## | |
| # Créer un volume de données à utiliser avec le serveur | |
| demo-mgmt1-server-data-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| description: Stockage de données | |
| size: { get_param: dataVolume} | |
| volume_type: "M1" | |
| # Créer un volume système à utiliser avec le serveur | |
| 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 } | |
| # Construire un serveur en utilisant le volume système défini ci-dessus | |
| 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} ] | |
| # Attacher le volume de données précédemment défini au serveur | |
| 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} | |
| ################################ créer le serveur demo-mgmt2-server ############################## | |
| # Créer un volume de données à utiliser avec le serveur | |
| demo-mgmt2-server-data-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| description: Stockage de données | |
| size: { get_param: dataVolume} | |
| volume_type: "M1" | |
| # Créer un volume système à utiliser avec le serveur | |
| 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 } | |
| # Construire un serveur en utilisant le volume système défini ci-dessus | |
| 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} ] | |
| # Attacher le volume de données précédemment défini au serveur | |
| 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} | |
| ################################ créer le serveur demo-mgmt3-server ############################## | |
| # Créer un volume de données à utiliser avec le serveur | |
| demo-mgmt3-server-data-vol: | |
| type: OS::Cinder::Volume | |
| properties: | |
| availability_zone: { get_param: azName} | |
| description: Stockage de données | |
| size: { get_param: dataVolume} | |
| volume_type: "M1" | |
| # Créer un volume système à utiliser avec le serveur | |
| 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 } | |
| # Construire un serveur en utilisant le volume système défini ci-dessus | |
| 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} ] | |
| # Attacher le volume de données précédemment défini au serveur | |
| 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: IP fixe attribuée au serveur 1 | |
| value: { get_attr: [demo-mgmt1-server, networks, "private", 0]} | |
| server2_ip: | |
| description: IP fixe attribuée au serveur 2 | |
| value: { get_attr: [demo-mgmt2-server, networks, "private", 0]} | |
| server3_ip: | |
| description: IP fixe attribuée au serveur 3 | |
| value: { get_attr: [demo-mgmt3-server, networks, "private", 0]} |
voir le code brut
simple_3_node_template.yml
hébergé avec ❤ par GitHub
Maintenant que nous disposons de notre Infrastructure as Code, comment la déployons-nous à grande échelle tout en modifiant les paramètres d’entrée ? Eh bien, c’est ici que l’« API Economy » entre en jeu. Fujitsu K5 est basé sur OpenStack, qui est une plateforme axée sur les API – en termes simples, plutôt que marketing, cela signifie essentiellement que la plateforme peut être pilotée à 100 % via des interactions API uniquement… toujours confus ? Je peux utiliser plus de code !
Je peux envoyer le modèle Heat ci-dessus ainsi que les différents ensembles de paramètres au moteur d’orchestration de K5 à l’aide d’un script Python qui enverra les données au point de terminaison d’orchestration.
Ce fichier contient des caractères Unicode cachés ou bidirectionnels qui peuvent être interprétés ou compilés différemment de ce qui apparaît ci-dessous. Pour les examiner, ouvrez le fichier dans un éditeur qui révèle les caractères Unicode cachés.
En savoir plus sur les caractères Unicode bidirectionnels
Afficher les caractères cachés
| def deploy_heat_stack(k5token, stack_name, stack_to_deploy, stack_parameters): | |
| """Résumé : Appel API HEAT K5 pour envoyer un tas Heat, enveloppé dans une chaîne, à un projet K5 | |
| Retourne : | |
| TYPE : Objet JSON contenant le nouvel ID de Tas ou les codes d’erreur | |
| """ | |
| 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 ("\nErreur inattendue :", sys.exc_info()) |
voir le code brut
Deploy_Heat_Stack.py
hébergé avec ❤ par GitHub
L’avantage ici est que l’ensemble du processus est désormais défini dans le code – et cela peut facilement être contrôlé par un système de gestion de versions, ce qui aide à garantir des déploiements cohérents.
La version complète de cette solution peut être récupérée ici : https://github.com/allthingsclowd/Fujitsu_OpenStack_K5_Heat_Cookie_Cutter
K5_Stack_Deployer – Modèle OpenStack
Auteur : Graham Land
Date : 08/03/17
Twitter : @allthingsclowd
Github : https://github.com/allthingscloud
Blog : https://allthingscloud.eu
deploy_stacks.py
Ce script démontre comment déployer un modèle OpenStack HEAT
plusieurs fois avec des paramètres différents à chaque fois
k5regionapiv1.py
Ce fichier est importé par deploy_stacks.py et contient des wrappers de fonctions API K5/OpenStack
simple_3_node_stack.py
Ce fichier contient simplement le tas HEAT YAML enveloppé sous forme de chaîne pour une utilisation dans Python
simple_3_node_stack.yml
Est le modèle HEAT natif déployé (non utilisé, sauf si vous souhaitez jouer avec séparément)
k5contractsettingsV12.py
Vous DEVEZ configurer ce fichier pour qu’il corresponde à votre environnement avant de déployer.
Il contient une section environnementale et une section application.
La section environnementale est l’endroit où vous entrez vos détails K5, tandis que la section application est où les « lots » de paramètres à alimenter dans le modèle Heat sont configurés.
Chaque lot contient une liste de paramètres d’entrée du modèle Heat – chaque liste de paramètres représente un tas Heat déployé.
Lien vers Github
https://github.com/allthingsclowd/Fujitsu_OpenStack_K5_Heat_Cookie_Cutter
voir le code brut
K5_Cookie_Cutter.md
hébergé avec ❤ par GitHub
Bon déploiement de tas !
withk5youcan
Originally published on allthingscloud.eu (2017-03-10).
