Heat est la stack d’orchestration OpenStack. C’est l’outil qui permet d’automatiser le démarrage d’un ensemble d’éléments dans le projet open source d’IaaS.
Son rôle est donc de communiquer avec différentes briques pour créer des réseaux, des volumes, des instances, les paramétrer et les démarrer. Pour plus de détails, voir directement le projet sur openstack.org.
Context de l’exemple
Dans le cadre d’un POC, nous allons essentiellement nous servir de machines virtuelles x86.
+-------------------------+ +--------------------------+ | | | | | | | | | controller01 | | compute01 | | | | | | | | | | eth0 eth2 eth3 | | eth3 eth2 eth0 | +-------------------------+ +--------------------------+ | | | | | | | | | | | | | | | Réseau "privé" | | | | | +--------------------+ | | | | Réseau "public" | | | +------------------------------------+ | | Réseau "admin" | +-------------------------------------------------------+
Nous allons voir des exemples très simples afin de voir les principes de base de l’orchestration.
Pour faciliter le déroulement, les opérations seront effectuées avec le compte admin même si certaines pourraient être faite en tant que simple user du tenant “admin”.
Prérequis
Comme les méthodes de déploiement d’OpenStack varient beaucoup, nous n’allons pas détailler ici comment mettre en place le service. Nous partons du principe que le service est “up and running”. Nous avons donc un service qui fonctionne avec les stack suivantes : keystone, glance, nova, horizon, neutron, et bien sur heat.
Nous avons également les droits d’administration du service chargés dans l’environnement de la ligne de commande.
[root@hostnamedab ~(keystone_admin)]# keystone service-list +----------------------------------+------------+----------------+----------------------------+ | id | name | type | description | +----------------------------------+------------+----------------+----------------------------+ | b0bee0b0e9f34f8bafd4ba7d54ba3d6e | ceilometer | metering | Openstack Metering Service | | 2a06e498c2b84cb48ebd578f6fa48297 | cinder | volume | Cinder Service | | 14fa9ec07e34443bba5daac33266671f | cinder_v2 | volumev2 | Cinder Service v2 | | 1f4e441ee6d5489281d3aa8d64e2a746 | glance | image | Openstack Image Service | | d189a66300e04e9b8ac8cacad3eca3a1 | heat | orchestration | Heat API | | f96774576d8846d7bdd04ec9ccefabb5 | heat-cfn | cloudformation | Heat CloudFormation API | | 9365681a0e3945e2806e83d85b8319bf | keystone | identity | OpenStack Identity Service | | f13396b4b11c45baa59f9de685f25020 | neutron | network | Neutron Networking Service | | 6cf6626654b04b89a988483fb566508d | nova | compute | Openstack Compute Service | | f783eff435804e449d529ef6d03745bf | nova_ec2 | ec2 | EC2 Service | +----------------------------------+------------+----------------+----------------------------+ [root@hostnamedab ~(keystone_admin)]# nova service-list +------------------+-------------+----------+---------+-------+----------------------------+-----------------+ | Binary | Host | Zone | Status | State | Updated_at | Disabled Reason | +------------------+-------------+----------+---------+-------+----------------------------+-----------------+ | nova-consoleauth | hostnamedab | internal | enabled | up | 2014-02-26T14:29:25.000000 | None | | nova-scheduler | hostnamedab | internal | enabled | up | 2014-02-26T14:29:25.000000 | None | | nova-conductor | hostnamedab | internal | enabled | up | 2014-02-26T14:29:24.000000 | None | | nova-cert | hostnamedab | internal | enabled | up | 2014-02-26T14:29:25.000000 | None | | nova-compute | hostnamedbj | nova | enabled | up | 2014-02-26T14:29:28.000000 | None | | nova-console | hostnamedab | internal | enabled | down | 2014-02-26T09:30:20.000000 | None | +------------------+-------------+----------+---------+-------+----------------------------+-----------------+
Composition de la stack Heat
La stack heat n’est composée que du service d’API et du moteur.
Configuration
Ce n’est pas le lieu ici pour discuter de la configuration, mais voici tout de même un extrait des éléments les plus importants pour permettre de resituer le contexte.
[root@hostnamedab ~]# cat /etc/heat/heat.conf | grep -v "^#" |grep -v "^$" [DEFAULT] sql_connection=mysql://heat:patapouf@192.168.41.129/heat heat_metadata_server_url=http://192.168.41.129:8000 heat_waitcondition_server_url=http://192.168.41.129:8000/v1/waitcondition heat_watch_server_url=http://192.168.41.129:8003 heat_stack_user_role=heat_stack_user auth_encryption_key=6028f4e9d45cdbbe65d87f545166416e debug=False verbose=True log_dir=/var/log/heat rpc_backend=heat.openstack.common.rpc.impl_qpid qpid_hostname=192.168.41.129 qpid_port=5672 qpid_username=guest qpid_password=guest qpid_heartbeat=60 qpid_protocol=tcp qpid_tcp_nodelay=True qpid_reconnect_limit=0 qpid_reconnect_interval_min=0 qpid_reconnect_interval=0 qpid_reconnect_timeout=0 qpid_reconnect=True qpid_reconnect_interval_max=0 [ssl] [database] [paste_deploy] [rpc_notifier2] [ec2authtoken] auth_uri=http://192.168.41.129:35357/v2.0 keystone_ec2_uri=http://127.0.0.1:5000/v2.0/ec2tokens [heat_api_cloudwatch] [heat_api] bind_host=0.0.0.0 bind_port=8004 [heat_api_cfn] [auth_password] [matchmaker_ring] [matchmaker_redis] [keystone_authtoken] admin_tenant_name=services admin_user=heat admin_password=patapouf auth_host=192.168.41.129 auth_port=35357 auth_protocol=http auth_uri=http://192.168.41.129:35357/v2.0
Création d’une stack simple
Voici quelques liens de documentation au sujet des templates :
Spécification HOT
Création de stack
Guide pour débuter
Nous allons récupérer les informations de base pour créer une instance : l’image, le flavor, le réseau et le sous-réseau
[root@hostnamedab ~(keystone_admin)]# glance image-list +--------------------------------------+------------+-------------+------------------+----------+--------+ | ID | Name | Disk Format | Container Format | Size | Status | +--------------------------------------+------------+-------------+------------------+----------+--------+ | 38de0608-74fd-47c3-8839-e0d839711171 | cirros-3.2 | qcow2 | bare | 13167616 | active | +--------------------------------------+------------+-------------+------------------+----------+--------+ [root@hostnamedab ~(keystone_admin)]# nova flavor-list +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+ | ID | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public | +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+ | 1 | m1.tiny | 512 | 1 | 0 | | 1 | 1.0 | True | | 2 | m1.small | 2048 | 20 | 0 | | 1 | 1.0 | True | | 3 | m1.medium | 4096 | 40 | 0 | | 2 | 1.0 | True | | 4 | m1.large | 8192 | 80 | 0 | | 4 | 1.0 | True | | 5 | m1.xlarge | 16384 | 160 | 0 | | 8 | 1.0 | True | +----+-----------+-----------+------+-----------+------+-------+-------------+-----------+ [root@hostnamedab ~(keystone_admin)]# neutron net-list +--------------------------------------+-------------+-------------------------------------------------------+ | id | name | subnets | +--------------------------------------+-------------+-------------------------------------------------------+ | 00bcfcc4-236e-40bd-ba54-74c85ae0d05e | mynettenant | efab7729-96ca-4b04-9ab7-3fd6d7c1d22b 192.168.165.0/24 | | 8cce6638-d41f-4b58-8549-2a10f3bf7b06 | public | 67ddd6df-b592-4d9e-9906-34e93563eb2c 10.6.27.0/24 | +--------------------------------------+-------------+-------------------------------------------------------+ [root@hostnamedab ~(keystone_admin)]# neutron subnet-list +--------------------------------------+------+------------------+------------------------------------------------------+ | id | name | cidr | allocation_pools | +--------------------------------------+------+------------------+------------------------------------------------------+ | 67ddd6df-b592-4d9e-9906-34e93563eb2c | | 10.6.27.0/24 | {"start": "10.6.27.150", "end": "10.6.27.249"} | | efab7729-96ca-4b04-9ab7-3fd6d7c1d22b | | 192.168.165.0/24 | {"start": "192.168.165.2", "end": "192.168.165.254"} | +--------------------------------------+------+------------------+------------------------------------------------------+
Nous avons donc une image cirros, un réseau mynettenant, un sous réseau 192.168.165.0/24 et nous allons utiliser le flavor m1.small.
Le template HOT prends la syntaxe suivante :
[root@hostnamedab ~(keystone_admin)]# cat heat_example.hot heat_template_version: 2014-03-28 description: Simple template to deploy a single compute instance resources: my_instance: type: OS::Nova::Server properties: image: cirros-3.2 flavor: m1.small networks: - port: { get_resource: my_port } my_port: type: OS::Neutron::Port properties: network_id: 00bcfcc4-236e-40bd-ba54-74c85ae0d05e fixed_ips: - subnet_id: efab7729-96ca-4b04-9ab7-3fd6d7c1d22b
[root@hostnamedab ~(keystone_admin)]# heat stack-create my_stack01 --template-file=heat_example.hot +--------------------------------------+------------+--------------------+----------------------+ | id | stack_name | stack_status | creation_time | +--------------------------------------+------------+--------------------+----------------------+ | a4b488b5-0bed-4bd5-8b92-bce97d61ef19 | my_stack01 | CREATE_IN_PROGRESS | 2014-03-28T15:33:53Z | +--------------------------------------+------------+--------------------+----------------------+ [root@hostnamedab ~(keystone_admin)]# heat stack-show my_stack01 +----------------------+-----------------------------------------------------------------------------------------------------------------------------------+ | Property | Value | +----------------------+-----------------------------------------------------------------------------------------------------------------------------------+ | capabilities | [] | | creation_time | 2014-03-28T16:18:43Z | | description | Simple template to deploy a single compute instance | | disable_rollback | True | | id | 9141a42c-e1bb-4c05-aa67-fde5658f9400 | | links | http://192.168.41.129:8004/v1/5f8ffb039ce844bc94ba031be85e0936/stacks/my_stack01/9141a42c-e1bb-4c05-aa67-fde5658f9400 | | notification_topics | [] | | outputs | [] | | parameters | { | | | "AWS::StackId": "arn:openstack:heat::5f8ffb039ce844bc94ba031be85e0936:stacks/my_stack01/9141a42c-e1bb-4c05-aa67-fde5658f9400", | | | "AWS::Region": "ap-southeast-1", | | | "AWS::StackName": "my_stack01" | | | } | | stack_name | my_stack01 | | stack_status | CREATE_COMPLETE | | stack_status_reason | Stack create completed successfully | | template_description | Simple template to deploy a single compute instance | | timeout_mins | 60 | | updated_time | 2014-03-28T16:19:29Z | +----------------------+-----------------------------------------------------------------------------------------------------------------------------------+
Exemple un peu plus complexe avec paramétrage dans l’instance
TODO : Pas fini
On commence par générer une paire de clé qui sera utilisée par la suite.
[root@hostnamedab ~(keystone_admin)]# nova keypair-add my_keypair > my_keypair.pem [root@hostnamedab ~(keystone_admin)]# nova keypair-list +------------+-------------------------------------------------+ | Name | Fingerprint | +------------+-------------------------------------------------+ | my_keypair | 5d:41:e8:9f:62:70:52:6b:17:bd:06:31:fb:e7:bf:4d | +------------+-------------------------------------------------+ [root@hostnamedab ~(keystone_admin)]# cat my_keypair.pem -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAwLzO5xVJVTQHxE4L6Z9dE8ZBNJrQ0EiQtW6Ggy82qKnIl0Jp gODlaXPOMcL9u4pdVaEMB4MVQnEce4noVSGBAC/UhcRkhpzpMqTkdDsXji3u3Q4j ZZP82JHRWF+MIwB87ahUhUR5D4kzZ1dN01CrhjhTXFIp9FX7HT4Ukgmqs3T1ssqq muqelc37OW4sqRhmUtHwog7oaCsCOrk6kPaOFLA8WtQQhccTu/4OabNgFpzeOLf9 GjWt6SCcbqK+lC8MGwsAgv1hQZu7sWxGNf3DfwThGfQlxrNDsgZ9O+by/FyifFgL dfoUaJL9kmHHLwyF8krYM8pLqgEY1+M1MfgC6wIBIwKCAQEAsDeYmMMBN/UOalX8 Q0/gEhRY36N9FjO3gU8b5aeCblIWe6pvFr79oj3+WWHSCo0iImdbdJUawGdqf5QH nkqEknTfkD6Hy4glqqVjKHCKkJ8GRnNTkBJGQllu8bZxfxZjl3VUlxoISLf0e72I +7d4QDN/alm/9VXs54k3YPLlNlq3XcivXfkc+cUajgA2RVIMonCXcWTJyVILmSFE IjBkiXWqrclKLATAjCt8e8SSkFj/lh3QzM/EDjYXAaSVCumBhh6d38Buh53v9csy GFKN8ZA/yBaBECULmI99FBpW3+V7YKwoIAXcHxNro5kIcUe9/0m21ZgZIpXtFcgz 1kJFiwKBgQDsmom98Npgra5+ca5DQ1OmyKTFevUmpqpCGsgmqBQitTl1u88m5W7G bZzjol3oSgwyRzUD41FpUZStYlSfxJp3Cg/+3uYrHXOwwMoJz9zFZP+00FSLg+LQ O/Czt0+PHiAXucBtYyZGbca6H3wG9mtYnoVZjZ/3OPwDEQX0Z0uzyQKBgQDQia1s 20fGNu/nvG+uCfMBuIIFgxOFDU8DcHSxY319aR4T8PDAgDMatRGan/Z3fq9UZVJc 1uEGKADF4oIby6UvZkmE91y9P9NMe8v9m4ay2c9mhsb9GSfuxzjYtpqU2VmL0NtS L81lOM8Ft/Ze/Lq1hIzerIv48zEadwpIGFPTEwKBgA2FLHFA9okufv/pPShqP0tb 7CiKruxECbqicdZSv1JwwXRxIce1VsmCm0A1KfAEOzYSspKCBKbuuAnoXJtqUfgs dfFOkM9DgvQoRg8wcwP3JI39Rqji9wSVtfukEyy/5JOkNuGt5O4U5sjOmV97y56p +P3NlBzBbXyEoUEqeVq7AoGAcTTL3AICZEm1byvHmP4WNCJVNjE2e22f6+yXHnfW aKbHL2WKAhm1V6Qff9MuBlq280zyMmYFIJlfgV20WDtZrARTy9a9UMrga1klmE0d PITeTZmfOPBmIoloAJ2kX26s9CDsFqw8TORTIFyNDv45eHsn5pguulgh+GyB7J99 9j0CgYEAyGZMjSWopO6+Ul7BBSHVvB8qW9nGdea4cAhGS+k5e3gRygudciaMu8ed WiSQiF1CYBmzjCErE5jgyp/INhZFyBsw3MgLwhxpS3hpHcmaqLTh6SlN0ok0eIMC 5vmqvzEfrzWugBLH/Ju2caFyPyGo662Ef7fXVx0TulRSqYL9Cz0= -----END RSA PRIVATE KEY-----
Voici le template au format HOT. On ajoute l’association d’une floating IP, l’ajout de security groups, l’ajout d’une clé SSH et la modification d’un fichier dans l’instance. Certains paramètres peuvent être choisis au moment du lancement de la stack.
[root@hostnamedab ~(keystone_admin)]# cat heat_example.hot heat_template_version: 2014-03-31 description: Simple template to deploy a single compute instance and set motd parameters: key_name: type: string label: Key Name description: Name of key-pair to be used for compute instance image: type: string label: Image description: Image to be used for compute instance instance_type: type: string label: Instance Type description: Type of instance (flavor) to be used default: m1.small constraints: - allowed_values: [m1.small, m1.medium, m1.large] description: instance_type must be one of m1.small, m1.medium or m1.large motd: type: string description: Message of the day resources: my_instance: type: OS::Nova::Server properties: key_name: { get_param: key_name } image: { get_param: image } flavor: { get_param: instance_type } networks: - port: { get_resource: my_port } user_data: str_replace: template: | #!/bin/sh echo 'File initialized from Heat template' > /etc/motd echo '$motd_from_param' >> /etc/motd params: $motd_from_param: { get_param: motd } my_port: type: OS::Neutron::Port properties: network_id: 00bcfcc4-236e-40bd-ba54-74c85ae0d05e fixed_ips: - subnet_id: efab7729-96ca-4b04-9ab7-3fd6d7c1d22b security_groups: [ 9aa64316-fb7b-4449-8d75-f3246e15bcb9, 8dab352c-55c9-4a34-a482-5cdab5bdb743 ] my_floating_ip: type: OS::Neutron::FloatingIP properties: floating_network_id: 8cce6638-d41f-4b58-8549-2a10f3bf7b06 port_id: { get_resource: my_port }
On peut maintenant lancer la stack en passant les paramètres à Heat.
[root@hostnamedab ~(keystone_admin)]# heat stack-create my_stack1 --template-file=heat_example.hot --parameters="key_name=my_keypair;instance_type=m1.small;image=fedora20;motd=Patapouf" +--------------------------------------+------------+--------------------+----------------------+ | id | stack_name | stack_status | creation_time | +--------------------------------------+------------+--------------------+----------------------+ | 10ade449-82e1-4074-ba29-01dcb09dbf2b | my_stack2 | CREATE_IN_PROGRESS | 2014-04-03T15:43:45Z | +--------------------------------------+------------+--------------------+----------------------+
Leave a Reply