OpenStack CLI
V předchozí části labu jsme se soustředili na ovládání skrze grafické rozhraní. Proč tedy vůbec má smysl znát příkazovou řádku?
-
Příkazová řádka je open source a využívá OpenStack API, takže funguje stejně v různých modifikací OpenStack od různých výrobců – to co se naučíte se vám hodí v mnoha situacích
-
V některých operacích je příkazová řádka rychlejší
-
Ovládat infrastrukturu můžete i z minimálního systému bez grafického prostředí
-
Příkazy můžete skriptovat, tedy vytvářet jednoduché „aplikace“, které dávkovým způsobem budou provádět nějaké operace nebo provádět pravidelné záležitosti (například sestavíte nějaké demo prostředí, které dáte k rozbití a po ukončení takové session skriptem vrátíte demo do původního stavu)
-
Některé funkce jsou dostupné pouze tímto způsobem – běžný vývoj je, že nová funkce je jako první k dispozici v příkazové řádce a později v grafickém interface
Pokročilejší uživatel by tedy měl CLI znát, stojí to za to.
Příkazová řádka OpenStack je implementovaná jako Python aplikace, kterou můžete nainstalovat prakticky kamkoli - v našem případě je pro vás připravena na labServer. Historicky měl každý projekt svou vlastní aplikaci. Pro práci se servery jse volali „nova“, pro storage „cinder“, pro image „glance“ a tak dál. V tuto chvíli HPE a komunita pracuje na novém moderním integrovaném projektu příkazové řádky, pro který nemusíte znát kódové názvy jednotlivých součástek OpenStack. Naprostou většinu operací už můžete provádět tímto novým způsobem (a tomu se budeme v labu věnovat), ale mohou být stále ještě speciality, pro které použijete původní příkazy (například práce s LBaaS v základním lab guide byla přes příkaz „neutron“). Dá se očevat, že tato univerzální příkazová řádka bude i nadále růst svými vlastnostmi a díky konceptu plug-inů je navíc velmi dobře rozšiřitelná. Přesto některé novější projekty a funkce mohou pro některé operace vyžadovat nativní příkazovou řádku (tedu tu vyvíjenou v rámci konkrétního projektu).
Abychom nemuseli neustále dokola zadávat komunikační parametry jako je login do OpenStack, uložíme si je do proměnných prostředí. Ve vašem domovském adresáři na labServer je pro vás připraven soubor stack, který to udělá (klidně si ho prohlédněte). Načtěte ho do prostředí.
tomas@labserver:~$ source stack
Příkazy vždy začínají slovem openstack, pak následuje podstatné jméno (s čím chcete něco dělat) a sloveso (co s tím chcete dělat) a pak případné další detaily. Vypište si seznam možných příkazů.
tomas@labserver:~$ openstack --help
usage: openstack [--version] [-v | -q] [--log-file LOG_FILE] [-h] [--debug]
...
Command-line interface to the OpenStack APIs
optional arguments:
...
Commands:
access token create Create an access token
aggregate add host Add host to aggregate
...
server add security group Add security group to server
server add volume Add volume to server
server create Create a new server
server delete Delete server(s)
server dump create Create a dump file in server(s)
server image create Create a new disk image from a running server
server list List servers
server lock Lock server(s). A non-admin user will not be able to execute actions
server migrate Migrate server to different host
server pause Pause server(s)
server reboot Perform a hard or soft server reboot
server rebuild Rebuild server
server remove security group Remove security group from server
server remove volume Remove volume from server
server rescue Put server in rescue mode
server resize Scale server to a new flavor
server restore Restore server(s)
server resume Resume server(s)
server set Set server properties
server shelve Shelve server(s)
server show Show server details
server ssh SSH to server
server start Start server(s).
server stop Stop server(s).
server suspend Suspend server(s)
server unlock Unlock server(s)
server unpause Unpause server(s)
server unrescue Restore server from rescue mode
server unset Unset server properties
server unshelve Unshelve server(s)
...
zone transfer request show Show Zone Transfer Request Details
Nebo (a to budeme v našem labu preferovat) zadáte příkaz rovnou celý. Takhle si tedy vypíšeme nám dostupné Flavors.
tomas@labserver:~$ openstack flavor list
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
| ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
| 1 | m1.tiny | 512 | 1 | 0 | 1 | True |
| 2 | m1.small | 2048 | 20 | 0 | 1 | True |
| 3 | m1.medium | 4096 | 40 | 0 | 2 | True |
| 3ef6acf8-b0ae-45d0-ae0f-990b956aaa79 | l1.medium | 4096 | 10 | 0 | 2 | True |
| 4 | m1.large | 8192 | 80 | 0 | 4 | True |
| 5 | m1.xlarge | 16384 | 160 | 0 | 8 | True |
| e81cf7b8-0c43-4114-a5ef-f4e56316dc0e | l1.small | 2048 | 5 | 0 | 1 | True |
| fc17693b-ff34-4b23-98a6-acebc7da5ce3 | web.tiny | 512 | 5 | 0 | 1 | True |
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
A pokud nás zajímají detaily některého z nich, použijeme show.
tomas@labserver:~$ openstack flavor show m1.medium
+----------------------------+-----------+
| Field | Value |
+----------------------------+-----------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| disk | 40 |
| id | 3 |
| name | m1.medium |
| os-flavor-access:is_public | True |
| properties | |
| ram | 4096 |
| rxtx_factor | 1.0 |
| swap | |
| vcpus | 2 |
+----------------------------+-----------+
Pokud si chcete nechat poradit, použijte help.
tomas@labserver:~$ openstack help image list
usage: openstack image list [-h] [-f {csv,json,table,value,yaml}] [-c COLUMN]
[--max-width <integer>] [--noindent]
[--quote {all,minimal,none,nonnumeric}]
[--public | --private | --shared]
[--property <key=value>] [--long]
[--sort <key>[:<direction>]] [--limit <limit>]
[--marker <marker>]
List available images
optional arguments:
-h, --help show this help message and exit
--public List only public images
--private List only private images
--shared List only shared images
--property <key=value>
Filter output based on property
--long List additional fields in output
--sort <key>[:<direction>]
Sort output by selected keys and directions(asc or
desc) (default: asc), multiple keys and directions can
be specified separated by comma
--limit <limit> Maximum number of images to display.
--marker <marker> The last image (name or ID) of the previous page.
Display list of images after marker. Display all
images if not specified.
output formatters:
output formatter options
-f {csv,json,table,value,yaml}, --format {csv,json,table,value,yaml}
the output format, defaults to table
-c COLUMN, --column COLUMN
specify the column(s) to include, can be repeated
table formatter:
--max-width <integer>
Maximum display width, 0 to disable
json formatter:
--noindent whether to disable indenting the JSON
CSV Formatter:
--quote {all,minimal,none,nonnumeric}
when to include quotes, defaults to nonnumeric
Můžete volit různé formátování výstupu, zobrazovat jen některé sloupce apod.
tomas@labserver:~$ openstack image list --max-width 40
+--------------------------------------+--------------+--------+
| ID | Name | Status |
+--------------------------------------+--------------+--------+
| acc333be-44f7-48fe-962d-4bcd96c7800e | CentOS 6 | active |
| fe14d439-75af-45d0-9084-08479e4a58c8 | web-server | active |
| 61de0c96-c30b-4207-924a-bb9188448878 | mujImage | active |
| 73fd1e9e-9370-4dc1-ac06-a6a9a598df14 | CoreOS | active |
| 767ec27b-0eed-43ea-9631-9115aaa78f05 | Stackato | active |
| bb0eba2a-6ce1-4393-b89f-4a219add5da7 | Ubutnu_14.04 | active |
| e9664fca-74b0-4a59-95e9-87a1a844d031 | Cirros | active |
| 04d32087-6a66-4d04-8481-cdb3b8b472a3 | Ubuntu_16.04 | active |
+--------------------------------------+--------------+--------+
tomas@labserver:~$ openstack image list -f yaml
- ID: acc333be-44f7-48fe-962d-4bcd96c7800e
Name: CentOS 6
Status: active
- ID: fe14d439-75af-45d0-9084-08479e4a58c8
Name: web-server
Status: active
- ID: 61de0c96-c30b-4207-924a-bb9188448878
Name: mujImage
Status: active
- ID: 73fd1e9e-9370-4dc1-ac06-a6a9a598df14
Name: CoreOS
Status: active
- ID: 767ec27b-0eed-43ea-9631-9115aaa78f05
Name: Stackato
Status: active
- ID: bb0eba2a-6ce1-4393-b89f-4a219add5da7
Name: Ubutnu_14.04
Status: active
- ID: e9664fca-74b0-4a59-95e9-87a1a844d031
Name: Cirros
Status: active
- ID: 04d32087-6a66-4d04-8481-cdb3b8b472a3
Name: Ubuntu_16.04
Status: active
tomas@labserver:~$ openstack image list -f csv
"ID","Name","Status"
"acc333be-44f7-48fe-962d-4bcd96c7800e","CentOS 6","active"
"fe14d439-75af-45d0-9084-08479e4a58c8","web-server","active"
"61de0c96-c30b-4207-924a-bb9188448878","mujImage","active"
"73fd1e9e-9370-4dc1-ac06-a6a9a598df14","CoreOS","active"
"767ec27b-0eed-43ea-9631-9115aaa78f05","Stackato","active"
"bb0eba2a-6ce1-4393-b89f-4a219add5da7","Ubutnu_14.04","active"
"e9664fca-74b0-4a59-95e9-87a1a844d031","Cirros","active"
"04d32087-6a66-4d04-8481-cdb3b8b472a3","Ubuntu_16.04","active"
tomas@labserver:~$ openstack image list -f json
[
{
"Status": "active",
"ID": "acc333be-44f7-48fe-962d-4bcd96c7800e",
"Name": "CentOS 6"
},
{
"Status": "active",
"ID": "fe14d439-75af-45d0-9084-08479e4a58c8",
"Name": "web-server"
},
{
"Status": "active",
"ID": "61de0c96-c30b-4207-924a-bb9188448878",
"Name": "mujImage"
},
{
"Status": "active",
"ID": "73fd1e9e-9370-4dc1-ac06-a6a9a598df14",
"Name": "CoreOS"
},
{
"Status": "active",
"ID": "767ec27b-0eed-43ea-9631-9115aaa78f05",
"Name": "Stackato"
},
{
"Status": "active",
"ID": "bb0eba2a-6ce1-4393-b89f-4a219add5da7",
"Name": "Ubutnu_14.04"
},
{
"Status": "active",
"ID": "e9664fca-74b0-4a59-95e9-87a1a844d031",
"Name": "Cirros"
},
{
"Status": "active",
"ID": "04d32087-6a66-4d04-8481-cdb3b8b472a3",
"Name": "Ubuntu_16.04"
}
]
tomas@labserver:~$ openstack image list -f value -c Name
CentOS 6
web-server
mujImage
CoreOS
Stackato
Ubutnu_14.04
Cirros
Ubuntu_16.04
tomas@labserver:~$ openstack image list --property name=Cirros
+--------------------------------------+--------+--------+
| ID | Name | Status |
+--------------------------------------+--------+--------+
| e9664fca-74b0-4a59-95e9-87a1a844d031 | Cirros | active |
+--------------------------------------+--------+--------+
Zkusme nastartovat instanci. Nejprve si zjistěme názvy sítí, klíčů apod.
tomas@labserver:~$ openstack network list
+--------------------------------------+---------+--------------------------------------+
| ID | Name | Subnets |
+--------------------------------------+---------+--------------------------------------+
| d4712d32-e929-4c20-9b9c-fe9fe66b85f6 | ext-net | 46c758ce-febc-413d-b2cf-72f45e9df8b0 |
| e99ab504-8e64-47c7-b33c-3f056a1c6844 | Web-sit | a5f5b1d2-8d0f-4edf-ab07-0717d1277378 |
| 5431eac3-92cb-4464-8cd2-51ceb6804ed4 | mojeSit | 231efe61-4aa3-45ba-8904-4fdd3b1baabd |
+--------------------------------------+---------+--------------------------------------+
tomas@labserver:~$ openstack keypair list
+---------+-------------------------------------------------+
| Name | Fingerprint |
+---------+-------------------------------------------------+
| mujKlic | 02:67:48:85:e2:bc:d1:05:f7:35:10:55:57:6d:d4:90 |
+---------+-------------------------------------------------+
tomas@labserver:~$ openstack image list --max-width 50
+--------------------------------------+--------------+--------+
| ID | Name | Status |
+--------------------------------------+--------------+--------+
| acc333be-44f7-48fe-962d-4bcd96c7800e | CentOS 6 | active |
| fe14d439-75af-45d0-9084-08479e4a58c8 | web-server | active |
| 61de0c96-c30b-4207-924a-bb9188448878 | mujImage | active |
| 73fd1e9e-9370-4dc1-ac06-a6a9a598df14 | CoreOS | active |
| 767ec27b-0eed-43ea-9631-9115aaa78f05 | Stackato | active |
| bb0eba2a-6ce1-4393-b89f-4a219add5da7 | Ubutnu_14.04 | active |
| e9664fca-74b0-4a59-95e9-87a1a844d031 | Cirros | active |
| 04d32087-6a66-4d04-8481-cdb3b8b472a3 | Ubuntu_16.04 | active |
+--------------------------------------+--------------+--------+
tomas@labserver:~$ openstack flavor list
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
| ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
| 1 | m1.tiny | 512 | 1 | 0 | 1 | True |
| 2 | m1.small | 2048 | 20 | 0 | 1 | True |
| 3 | m1.medium | 4096 | 40 | 0 | 2 | True |
| 3ef6acf8-b0ae-45d0-ae0f-990b956aaa79 | l1.medium | 4096 | 10 | 0 | 2 | True |
| 4 | m1.large | 8192 | 80 | 0 | 4 | True |
| 5 | m1.xlarge | 16384 | 160 | 0 | 8 | True |
| e81cf7b8-0c43-4114-a5ef-f4e56316dc0e | l1.small | 2048 | 5 | 0 | 1 | True |
| fc17693b-ff34-4b23-98a6-acebc7da5ce3 | web.tiny | 512 | 5 | 0 | 1 | True |
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
tomas@labserver:~$ openstack security group list
+---------------------------+--------------+---------------------------+---------------------------+
| ID | Name | Description | Project |
+---------------------------+--------------+---------------------------+---------------------------+
| 42fa6ec7-86b2-4ca0-92f8-6 | default | Default security group | d2811986367044f9a5d9efa18 |
| a2c70f2a3a7 | | | 0e746cd |
| 616f4f6f-ba2a-4768-b1f9-3 | WebServery | Webova farma pro moji | d2811986367044f9a5d9efa18 |
| 011e49a7d19 | | aplikaci | 0e746cd |
| 73ead103-f579-4681-9b0a- | WebFrontend | Povoleni portu 80 a 443 | d2811986367044f9a5d9efa18 |
| 652623b49b44 | | | 0e746cd |
| 95e4e1e7-966b- | SSH+ICMP | Povoluje SSH přístup a | d2811986367044f9a5d9efa18 |
| 4a10-8512-a985a2791229 | | ICMP | 0e746cd |
| b4720c8e-66a6-4964-9ec1-a | MojeAplikace | Skupina aplikacnich | d2811986367044f9a5d9efa18 |
| 4c58565b02b | | serveru | 0e746cd |
+---------------------------+--------------+---------------------------+---------------------------+
Nastartujme dvě instance.
tomas@labserver:~$ openstack server create serverCLI --image Cirros --flavor m1.tiny --security-group default --key-name mujKlic --nic net-id=5431eac3-92cb-4464-8cd2-51ceb6804ed4 --min 2 --max 2 --max-width 40
+--------------------------------------+------------------------------------------+
| Field | Value |
+--------------------------------------+------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | |
| OS-EXT-STS:power_state | 0 |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | None |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | |
| adminPass | Wzo6Pvv68bke |
| config_drive | |
| created | 2016-07-13T07:34:15Z |
| flavor | m1.tiny (1) |
| hostId | |
| id | a6900235-c5f8-4acd-afc1-a37c62b08c6f |
| image | Cirros (e9664fca- |
| | 74b0-4a59-95e9-87a1a844d031) |
| key_name | mujKlic |
| name | serverCLI-1 |
| os-extended-volumes:volumes_attached | [] |
| progress | 0 |
| project_id | d2811986367044f9a5d9efa180e746cd |
| properties | |
| security_groups | [{u'name': u'default'}] |
| status | BUILD |
| updated | 2016-07-13T07:34:15Z |
| user_id | d64afca221d64d5cab4592d4dbb3736f |
+--------------------------------------+------------------------------------------+
Vypište si servery - zatím se teprve budují.
tomas@labserver:~$ openstack server list
+--------------------------------------+-------------+--------+----------------------------------+
| ID | Name | Status | Networks |
+--------------------------------------+-------------+--------+----------------------------------+
| c0736530-0bd1-40b0-952b-c421ab086384 | serverCLI-2 | BUILD | |
| a6900235-c5f8-4acd-afc1-a37c62b08c6f | serverCLI-1 | BUILD | |
| f5b52c8b-4c0e-4840-b1d5-ff2a42edec7d | mujWEB-2 | ACTIVE | Web-sit=192.168.2.7 |
| 30640cc6-5494-4d7e-a95a-2afb621929cb | mujWEB-1 | ACTIVE | Web-sit=192.168.2.6, 10.201.0.12 |
| 0a5b959f-1e6e-4e82-b5dc-c3c74aaa9722 | mojeVM-2 | ACTIVE | mojeSit=192.168.1.3 |
| 133fbcb2-7e6e-43c9-9b89-00777d823116 | mojeVM-1 | ACTIVE | mojeSit=192.168.1.4 |
+--------------------------------------+-------------+--------+----------------------------------+
Po chvilce budou nahoře.
tomas@labserver:~$ openstack server list
+--------------------------------------+-------------+--------+----------------------------------+
| ID | Name | Status | Networks |
+--------------------------------------+-------------+--------+----------------------------------+
| c0736530-0bd1-40b0-952b-c421ab086384 | serverCLI-2 | ACTIVE | mojeSit=192.168.1.25 |
| a6900235-c5f8-4acd-afc1-a37c62b08c6f | serverCLI-1 | ACTIVE | mojeSit=192.168.1.24 |
| f5b52c8b-4c0e-4840-b1d5-ff2a42edec7d | mujWEB-2 | ACTIVE | Web-sit=192.168.2.7 |
| 30640cc6-5494-4d7e-a95a-2afb621929cb | mujWEB-1 | ACTIVE | Web-sit=192.168.2.6, 10.201.0.12 |
| 0a5b959f-1e6e-4e82-b5dc-c3c74aaa9722 | mojeVM-2 | ACTIVE | mojeSit=192.168.1.3 |
| 133fbcb2-7e6e-43c9-9b89-00777d823116 | mojeVM-1 | ACTIVE | mojeSit=192.168.1.4 |
+--------------------------------------+-------------+--------+----------------------------------+
Vytvořme teď dva volumy ve storage.
tomas@labserver:~$ openstack volume create volCLI_1 --size 1
+---------------------+--------------------------------------+
| Field | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| consistencygroup_id | None |
| created_at | 2016-07-13T07:39:05.764205 |
| description | None |
| encrypted | False |
| id | 703db71c-704e-45c1-9232-370f66d9c2b6 |
| multiattach | False |
| name | volCLI_1 |
| properties | |
| replication_status | disabled |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| type | None |
| user_id | d64afca221d64d5cab4592d4dbb3736f |
+---------------------+--------------------------------------+
tomas@labserver:~$ openstack volume create volCLI_2 --size 1
+---------------------+--------------------------------------+
| Field | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| consistencygroup_id | None |
| created_at | 2016-07-13T07:39:12.881373 |
| description | None |
| encrypted | False |
| id | 23f8e7f6-d20c-4ee4-af91-8926a6ed54f2 |
| multiattach | False |
| name | volCLI_2 |
| properties | |
| replication_status | disabled |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| type | None |
| user_id | d64afca221d64d5cab4592d4dbb3736f |
+---------------------+--------------------------------------+
tomas@labserver:~$ openstack volume list
+--------------------------------------+--------------+-----------+------+-------------+
| ID | Display Name | Status | Size | Attached to |
+--------------------------------------+--------------+-----------+------+-------------+
| 23f8e7f6-d20c-4ee4-af91-8926a6ed54f2 | volCLI_2 | available | 1 | |
| 703db71c-704e-45c1-9232-370f66d9c2b6 | volCLI_1 | available | 1 | |
+--------------------------------------+--------------+-----------+------+-------------+
A napojme je k serverům.
tomas@labserver:~$ openstack server add volume serverCLI-1 volCLI_1
tomas@labserver:~$ openstack server add volume serverCLI-2 volCLI_2
tomas@labserver:~$ openstack volume list -c 'Display Name' -c 'Attached to'
+--------------+--------------------------------------+
| Display Name | Attached to |
+--------------+--------------------------------------+
| volCLI_2 | Attached to serverCLI-2 on /dev/vdb |
| volCLI_1 | Attached to serverCLI-1 on /dev/vdb |
+--------------+--------------------------------------+
Teď můžeme třeba přidat pravidlo do Security Group
tomas@labserver:~$ openstack security group rule list default
+-----------------------------+-------------+----------+------------+------------------------------+
| ID | IP Protocol | IP Range | Port Range | Remote Security Group |
+-----------------------------+-------------+----------+------------+------------------------------+
| 078835cb- | None | None | | 42fa6ec7-86b2-4ca0-92f8-6a2c |
| 0a46-4d14-bd78-75df9959262f | | | | 70f2a3a7 |
| 6799a98d-107c- | None | None | | None |
| 4c13-bd00-80450acaf4f2 | | | | |
| 9ce1d475-e9d4-4a01-8294-882 | None | None | | None |
| 168bbaab3 | | | | |
| cfa37ecc-a6ff-48ea-977a- | None | None | | 42fa6ec7-86b2-4ca0-92f8-6a2c |
| 137086076f49 | | | | 70f2a3a7 |
+-----------------------------+-------------+----------+------------+------------------------------+
tomas@labserver:~$ openstack security group rule create default --dst-port 22:22
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| direction | ingress |
| ethertype | IPv4 |
| headers | |
| id | 2b01ea61-a9eb-41e1-b3a2-23e4cd16f1ea |
| port_range_max | 22 |
| port_range_min | 22 |
| project_id | d2811986367044f9a5d9efa180e746cd |
| protocol | tcp |
| remote_group_id | None |
| remote_ip_prefix | 0.0.0.0/0 |
| security_group_id | 42fa6ec7-86b2-4ca0-92f8-6a2c70f2a3a7 |
+-------------------+--------------------------------------+
tomas@labserver:~$ openstack security group rule list default
+-----------------------------+-------------+-----------+------------+-----------------------------+
| ID | IP Protocol | IP Range | Port Range | Remote Security Group |
+-----------------------------+-------------+-----------+------------+-----------------------------+
| 078835cb- | None | None | | 42fa6ec7-86b2-4ca0-92f8-6a2 |
| 0a46-4d14-bd78-75df9959262f | | | | c70f2a3a7 |
| 2b01ea61-a9eb- | tcp | 0.0.0.0/0 | 22:22 | None |
| 41e1-b3a2-23e4cd16f1ea | | | | |
| 6799a98d-107c- | None | None | | None |
| 4c13-bd00-80450acaf4f2 | | | | |
| 9ce1d475-e9d4-4a01-8294-882 | None | None | | None |
| 168bbaab3 | | | | |
| cfa37ecc-a6ff-48ea-977a- | None | None | | 42fa6ec7-86b2-4ca0-92f8-6a2 |
| 137086076f49 | | | | c70f2a3a7 |
+-----------------------------+-------------+-----------+------------+-----------------------------+
A na závěr pojďme instance i volume smazat a abychom nemuseli vždy obě vypisovat, zkusíme si propojit dva příkazy dohromady přes pipu. Takhle si vypíšeme instance, které obsahují znaky „CLI“.
tomas@labserver:~$ openstack server list -f value -c Name | grep CLI
serverCLI-2
serverCLI-1
Využijme tohoto příkazu uvnitř příkazu na mazání.
tomas@labserver:~$ openstack server delete $(openstack server list -f value -c Name | grep CLI)
Podobně to můžeme dělat s volume.
tomas@labserver:~$ openstack volume delete $(openstack volume list -f value -c 'Display Name' | grep CLI)
Shell skriptování
Pokud pracujete s klientem v Linux prostředí můžete vytvářet jednoduché skripty pro bash shell. Na labServeru najdete dva triviální příklady.
První skript vezme slova, která mu předáte a podle toho založí příslušný počet volumů tohoto názvu.
tomas@labserver:~/bash-cli$ cat vytvorVolume.sh
for vol in "$@"
do
openstack volume create $vol --size 1
done
Druhý skript si vypíše všechny (! opatrně, ať tam nemáte něco, co chcete zachovat) volumy vašeho tenantu a pak je promaže.
tomas@labserver:~/bash-cli$ cat smazVsechnyVolume.sh
for vol in $(openstack volume list -f value -c ID)
do
openstack volume delete $vol
done
echo Smazano!
Jednoduché ... takhle to vypadá.
tomas@labserver:~$ cd bash-cli/
tomas@labserver:~/bash-cli$ chmod +x *
tomas@labserver:~/bash-cli$ ./vytvorVolume.sh volA volB volC
+---------------------+--------------------------------------+
| Field | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| created_at | 2015-12-11T11:14:14.281163 |
| display_description | None |
| display_name | volA |
| encrypted | False |
| id | 2288b737-f03b-4671-981a-0b5773caa857 |
| multiattach | false |
| properties | |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| type | vsa_thin |
+---------------------+--------------------------------------+
+---------------------+--------------------------------------+
| Field | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| created_at | 2015-12-11T11:14:15.896893 |
| display_description | None |
| display_name | volB |
| encrypted | False |
| id | c62c8f11-d475-4ee7-a349-343cff111f84 |
| multiattach | false |
| properties | |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| type | vsa_thin |
+---------------------+--------------------------------------+
+---------------------+--------------------------------------+
| Field | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| created_at | 2015-12-11T11:14:17.541467 |
| display_description | None |
| display_name | volC |
| encrypted | False |
| id | 3baa5b53-54de-46c9-b94c-dbb00930292c |
| multiattach | false |
| properties | |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| type | vsa_thin |
+---------------------+--------------------------------------+
+--------------------------------------+--------------+-----------+------+-------------+
| ID | Display Name | Status | Size | Attached to |
+--------------------------------------+--------------+-----------+------+-------------+
| 3baa5b53-54de-46c9-b94c-dbb00930292c | volC | available | 1 | |
| c62c8f11-d475-4ee7-a349-343cff111f84 | volB | available | 1 | |
| 2288b737-f03b-4671-981a-0b5773caa857 | volA | available | 1 | |
+--------------------------------------+--------------+-----------+------+-------------+
tomas@labserver:~/bash-cli$ ./smazVsechnyVolume.sh
Smazano!
tomas@labserver:~/bash-cli$ openstack volume list
tomas@labserver:~/bash-cli$
SDK a Python
OpenStack přichází se sadou RESTful API, které můžete využít v jakékoli aplikaci. Toto velmi jednoduché rozhraní využívá principů známých z webové komunikace a nevyžaduje tak žádné speciální binární klienty či knihovny. Aby to bylo ještě jednodušší, existuje řada knihoven přímo pro různé programovací jazyky, která přinese vyšší abstrakce. Protože OpenStack je napsaný v Python, tak knihovna právě pro tento jazyk je velmi dobře zpracována. Pojďme si ji v labu vyzkoušet. Pokud nejste programátoři, nevadí - alespoň nahlédněte do kódu. I na pár řádkách se da udělat něco celkem užitečného a vytvoříte si představu, jak mohou vaši vývojaři jednoduše zakomponovat OpenStack do svých aplikací či webových portálů.
Načtěte si komunikační proměnné, skočte do adresáře python-stack (tam jsou hotové „aplikace“) a učiňte je spustitelnými.
tomas@labserver:~$ source stack
tomas@labserver:~$ cd python-stack/
tomas@labserver:~/python-stack$ chmod +x *
První náš příklad bude jednoduché vypsání serverů, imagů a flavorů do konzole. Prohledněte si obsah souboru vypsat.py. Nejprve si načteme přihlašovací údaje z prostředí a pak provedeme jednoduchý cyklus. Pro každý server, který získáme z kolece všech serverů, vypíšeme jeho jméno. Totéž pro image a flavory. Nic složitého.
Takhle vypadá kód.
#!/usr/bin/python
from openstack import connection
import os
auth_args = {
'auth_url': os.environ['OS_AUTH_URL'],
'project_name': os.environ['OS_PROJECT_NAME'],
'username': os.environ['OS_USERNAME'],
'password': os.environ['OS_PASSWORD'],
'user_domain_id': os.environ['OS_USER_DOMAIN_ID'],
'project_domain_id': os.environ['OS_PROJECT_DOMAIN_ID'],
}
conn = connection.Connection(**auth_args)
print "Servery:"
print "--------"
for server in conn.compute.servers():
print server.name
print
print "Image:"
print "------"
for image in conn.compute.images():
print image.name
print
print "Flavor:"
print "-------"
for flavor in conn.compute.flavors():
print flavor.name
A tohle dělá po spuštění.
tomas@labserver:~/python-stack$ python vypsat.py
Servery:
--------
mujWEB-2
mujWEB-1
mojeVM-2
mojeVM-1
Image:
------
CentOS 6
web-server
mujImage
CoreOS
Stackato
Ubutnu_14.04
Cirros
Ubuntu_16.04
Flavor:
-------
m1.tiny
m1.small
m1.medium
l1.medium
m1.large
m1.xlarge
l1.small
web.tiny
V druhém příkladě uděláme něco podobného, ale tentokrát chceme, aby to byla webová aplikace (volíme primitivní, jen na ukázku). Chceme aplikaci se zabudovaným webovým serverem, na který se připojíme a dostaneme seznam flavorů. V rámci labu je pro něj vyhrazen port 7123 - v jeden okamžik ho může spustit jen jeden z vás (prostřídejte se).
Toto je kód v souboru web_list.py. Jediný rozdíl oproti předchozímu je, že vypisujee údaje v HTML tabulce zabudovaného Python Bottle web serveru.
#!/usr/bin/python
from openstack import connection
import os
from bottle import route, run
auth_args = {
'auth_url': os.environ['OS_AUTH_URL'],
'project_name': os.environ['OS_PROJECT_NAME'],
'username': os.environ['OS_USERNAME'],
'password': os.environ['OS_PASSWORD'],
'user_domain_id': os.environ['OS_USER_DOMAIN_ID'],
'project_domain_id': os.environ['OS_PROJECT_DOMAIN_ID'],
}
conn = connection.Connection(**auth_args)
@route('/')
def app():
vystup = "<table><TR><TD>Flavors</TD></TR>"
for flavor in conn.compute.flavors():
vystup = vystup + "<TR><TD>" + flavor.name + "</TD></TR>"
vystup = vystup + "</table>"
return vystup
run(host='0.0.0.0', port=7123)
Spusťte aplikaci. V rámci labu jsme za NAT a tento port je sdílený, tento test tedy budeme zkoušet pojednom.
tomas@labserver:~/python-stack$ python web_list.py
Bottle v0.12.9 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:7123/
Hit Ctrl-C to quit.
Ze svého notebooku se připojte na 16.21.188.201:7123
Výborně, webová aplikace nám funguje. Vraťte se do konzole labServer a aplikaci ukončete (CTRL+C).
Na závěr naznačíme už něco, co by mohlo být pro někoho užitečné. Nabídneme spuštění instance z našeho vlastního webového formuláře. Prohlédněme si obsah soubor web_vm.py. V hlavní části webu neděláme nic moc nového. Načítáme si flavory, image a sítě, ale všechno balíme do HTML formuláře. Uživatel si tak vybere co by chtěl a také svůj server nějak pojmenuje. Jakmile klikne na tlačítko Vytvor zavolá se funkce vytvor(). Ta převezme vyplněné údaje a na základě nich zavolá OpenStack pro vytvoření příslušného serveru.
#!/usr/bin/python
from openstack import connection
import os
from bottle import route, run, request
auth_args = {
'auth_url': os.environ['OS_AUTH_URL'],
'project_name': os.environ['OS_PROJECT_NAME'],
'username': os.environ['OS_USERNAME'],
'password': os.environ['OS_PASSWORD'],
'user_domain_id': os.environ['OS_USER_DOMAIN_ID'],
'project_domain_id': os.environ['OS_PROJECT_DOMAIN_ID'],
}
conn = connection.Connection(**auth_args)
@route('/')
def app():
vystup = """<!DOCTYPE html>
<html>
<body>
<form action="vytvor">
Nazev VM:<br>
<input type="text" name="nazev" value="nejakejmeno">
<br><br>
Flavor:<br>
<select name="flavor">"""
for flavor in conn.compute.flavors():
vystup = vystup + '<option value="{}">{}</option>'.format(flavor.name, flavor.name)
vystup = vystup + """
</select>
<br><br>
Image:<br>
<select name="image">"""
for image in conn.compute.images():
vystup = vystup + '<option value="{}">{}</option>'.format(image.name, image.name)
vystup = vystup + """
</select>
<br><br>
Sit:<br>
<select name="sit">"""
for sit in conn.network.networks():
vystup = vystup + '<option value="{}">{}</option>'.format(sit.name, sit.name)
vystup = vystup + """
</select>
<br><br>
<input type="submit" value="Vytvor">
</form>
</body>
</html>"""
return vystup
@route('/vytvor')
def vytvor():
nazev = request.query.nazev
image = conn.compute.find_image(request.query.image)
flavor = conn.compute.find_flavor(request.query.flavor)
network = conn.network.find_network(request.query.sit)
server = conn.compute.create_server(
name=nazev, image_id=image.id, flavor_id=flavor.id,
networks=[{"uuid": network.id}])
return "<h1>Pozadavek zadan</h1>"
run(host='0.0.0.0', port=7123)
Spusťte aplikaci a připojte se na web. Vyberte si a klikněte na vytvoř.
tomas@labserver:~/python-stack$ python web_vm.py
Bottle v0.12.9 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:7123/
Hit Ctrl-C to quit.
Přesvěčte se, že všechno dopadlo dle očekávání.
tomas@labserver:~/python-stack$ openstack server list
+--------------------------------------+-------------+--------+----------------------------------+
| ID | Name | Status | Networks |
+--------------------------------------+-------------+--------+----------------------------------+
| 80793528-7a5f-43ca-975c-668e3fc4c47d | nejakejmeno | ACTIVE | mojeSit=192.168.1.28 |
| f5b52c8b-4c0e-4840-b1d5-ff2a42edec7d | mujWEB-2 | ACTIVE | Web-sit=192.168.2.7 |
| 30640cc6-5494-4d7e-a95a-2afb621929cb | mujWEB-1 | ACTIVE | Web-sit=192.168.2.6, 10.201.0.12 |
| 0a5b959f-1e6e-4e82-b5dc-c3c74aaa9722 | mojeVM-2 | ACTIVE | mojeSit=192.168.1.3 |
| 133fbcb2-7e6e-43c9-9b89-00777d823116 | mojeVM-1 | ACTIVE | mojeSit=192.168.1.4 |
+--------------------------------------+-------------+--------+----------------------------------+
V této části bylo cílem představit možnosti API a SDK, nikoli ukázat jak kvalitně programovat. Příklady berte jako demonstraci možností a ne něco, co v této podobě chcete provozovat. Pokud je vaším cílem příjemný česky mluvící portál pro koncové uživatele, podívejte se také na hotové a velmi mocné komerční řešení HPE Cloud Service Automation.
Ansible pro OpenStack
Dlouho jsem rozmýšlel kam použití Ansible pro ovládání OpenStack zařadit. Má blíže k této kapitole, která je o skriptování a programování nad OpenStack API nebo spíše k orchestraci s prostředky jako je OpenStack Heat, Terraform nebo HPE Cloud Service Automation?
Podobně jako orchestrační nástroje přináší Ansible příjemnou abstrakci a například zda se má zdroj vytvořit nebo odstranit je stejné volání, jen se state označí za present nebo absent. To je fajn - ve skriptech to takhle jednoduché mít nebudete. Dále Ansible přináší idempotenci, tedy playbook (sadu úloh) můžete spustit několikrát po sobě a nerozbije se to. Ansible nejde a tupě nevytvoří zdroj (třeba instanci serveru nebo volume), ale nejprve si zjistí, jestli tam už je a jestli jeho stav odpovídá požadovanému. Tohle dostanete „zadarmo“, nemusíte kolem toho psát potřebné zjišťovací příkazy, jako byste museli ve skriptu. Ansible je tedy rozhodně mnohem víc, než pouhé skriptování. A navíc je lidsky čitelný bez znalosti programovacího jazyka.
Na druhou stranu Ansible cloud moduly nefungují plně deklarativním způsobem (já ti řeknu jakou infrastrukturu chci a ty to nějak zařiď), jsou spíše imperativní (já ti řeknu krok za krokem co máš dělat). Například tedy záleží na pořadí. Když chcete vytvořit server a síť, musíte nejdřív udělat síť a pak v ní spustit server. Když to chcete smazat, musíte nejdřív smazat server a pak síť (tedy opačně). Ansible vás od tohoto neodstínil, tedy není deklarativní. Pokud v desired state své infrastruktury chcete například vymazat jeden server, nestačí ho vymazat z předpisu - musíte spustit celou sekvenci a u tohoto serveru dát stav absent. Nenaplňuje to tedy představu, že předpis je verzovatelným obrazem infrastruktury. Pokud si pro Ansible napíšete vlastní role, můžete se k těmto stavům přiblížit, ale nic z toho pro vás není připraveno. Z těchto důvodů myslím zatím Ansible nepatří mezi deklarativní orchestrátory jako je OpenStack Heat, Terraform nebo HPE CSA. Přesto má smysl se jím zabývat - svoje „skriptování“ posunete o pár úrovní výš a nemusíte být programátoři !
Začněme tím, že si načteme komunikační proměnné a skočíme do adresáře s příklady.
tomas@labserver:~$ source stack
tomas@labserver:~$ cd ansible-openstack/
Prohlédněme si první nejjednodušší playbook.
tomas@labserver:~/ansible-openstack$ cat instance.yml
---
- hosts: localhost
tasks:
- name: Nacti vsechny instance
os_server_facts:
- name: Vypis co vis o instancich
debug:
var: openstack_servers
Tento se připojí do našeho OpenStack a stáhne si informace o instancích, které nám vnitřně uloží. Pracovat s nimi teď nebudeme, jen si vypíšeme, co všechno Ansible našel (výpis zkrátím, je toho hodně).
tomas@labserver:~/ansible-openstack$ ansible-playbook instance.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Nacti vsechny instance] **************************************************
ok: [localhost]
TASK [Vypis co vis o instancich] ***********************************************
ok: [localhost] => {
"openstack_servers": [
{
"HUMAN_ID": true,
"NAME_ATTR": "name",
"OS-DCF:diskConfig": "MANUAL",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"OS-SRV-USG:launched_at": "2016-07-13T09:13:08.000000",
"OS-SRV-USG:terminated_at": null,
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"mojeSit": [
{
"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:e0:f5:16",
"OS-EXT-IPS:type": "fixed",
"addr": "192.168.1.28",
"version": 4
}
]
},
"az": "nova",
"cloud": "envvars",
"config_drive": "",
"created": "2016-07-13T09:12:48Z",
"flavor": {
"id": "1"
},
"hostId": "68ff6a39dcf97a8a393687602a5c590725b49be174727d2e972b4508",
"human_id": "nejakejmeno",
"id": "80793528-7a5f-43ca-975c-668e3fc4c47d",
"image": {
"id": "e9664fca-74b0-4a59-95e9-87a1a844d031"
},
"interface_ip": "",
"key_name": null,
"metadata": {},
"name": "nejakejmeno",
"networks": {
"mojeSit": [
"192.168.1.28"
]
},
"os-extended-volumes:volumes_attached": [],
"private_v4": "192.168.1.28",
"progress": 0,
"public_v4": "",
"public_v6": "",
"region": "",
"request_ids": [],
"security_groups": [
{
"name": "default"
}
],
"status": "ACTIVE",
"tenant_id": "d2811986367044f9a5d9efa180e746cd",
"updated": "2016-07-13T09:13:08Z",
"user_id": "d64afca221d64d5cab4592d4dbb3736f",
"volumes": [],
"x_openstack_request_ids": []
},
{
...
"human_id": "mujweb-2",
},
{
...
"human_id": "mujweb-1",
...
},
{
...
"human_id": "mojevm-1",
...
}
]
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
Uvedené parametry můžeme dál použít v našem předpisu, ale my se pustíme do něčeho jiného. Pojďme si prohlédnout extrémně jednoduchý playbook na vytváření volume ve storage.
tomas@labserver:~/ansible-openstack$ cat storage.yml
---
- hosts: localhost
vars:
stav: present
disky:
- AnsibleVol1
- AnsibleVol2
tasks:
- name: Ujisti se, ze volume je v pozadovanem stavu
os_volume:
state: "{{ stav }}"
size: 1
display_name: "{{ item }}"
with_items: "{{ disky }}"
Co tady děláme? Na začátku jsme definovali dvě proměnné - stav a disky. Ve stavu máme napsáno present, tedy chceme disky vytvořit (pokud už neexistují). V disky máme výčet jmen disků. V playbook máme jedinou úlohu a tou je právě vytvoření disku. Jako parametr mu zadáváme state, velikost disku a také jeho jméno. To ovšem nahrazujeme proměnnou „item“. O co jde? Na konci tasku máme with_items, tedy že tento krok chceme opakovat pro všechny členy výčtu „disky“. Ansible tedy projde tento seznam a disky postupně vytvoří. To co byste při programování řešili nějakou smyčkou můžete v Ansible udělat takhle - lidsky přívětivě, čitelně a přístupně i pro neprogramátory.
Spusťte playbook a ověřte, že disky skutečně existují.
tomas@labserver:~/ansible-openstack$ ansible-playbook storage.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Ujisti se, ze volume je v pozadovanem stavu] *****************************
changed: [localhost] => (item=AnsibleVol1)
changed: [localhost] => (item=AnsibleVol2)
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
tomas@labserver:~/ansible-openstack$ openstack volume list
+--------------------------------------+--------------+-----------+------+-------------+
| ID | Display Name | Status | Size | Attached to |
+--------------------------------------+--------------+-----------+------+-------------+
| 9f472e2f-2add-4ab8-9cb6-572edc9312d0 | AnsibleVol2 | available | 1 | |
| 8beca9c0-fb9d-4519-b62f-5a7674ec782f | AnsibleVol1 | available | 1 | |
+--------------------------------------+--------------+-----------+------+-------------+
Všimněte si, že u tasku máme slovo „changed“. Ansible tím říká, že požadovaný stav neodpovídal skutečnému (tedy, že disk neexistoval) a proto provedl změnu. Pojďme teď jeden disk ručně vymazat a spustit playbook znova.
tomas@labserver:~/ansible-openstack$ openstack volume delete AnsibleVol1
tomas@labserver:~/ansible-openstack$ ansible-playbook storage.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Ujisti se, ze volume je v pozadovanem stavu] *****************************
changed: [localhost] => (item=AnsibleVol1)
ok: [localhost] => (item=AnsibleVol2)
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
Vidíte? Ansible znovu vytvořil chybějící volume, ale s existujícím nic nedělal, jen ověřil, že existuje.
Při spouštění playbooku můžeme modifikovat proměnnou stav a tím požadovat, že disky nesmí existovat. Zkusme si to.
tomas@labserver:~/ansible-openstack$ ansible-playbook storage.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Ujisti se, ze volume je v pozadovanem stavu] *****************************
changed: [localhost] => (item=AnsibleVol1)
ok: [localhost] => (item=AnsibleVol2)
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
tomas@labserver:~/ansible-openstack$ ansible-playbook storage.yml -e stav=absent
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Ujisti se, ze volume je v pozadovanem stavu] *****************************
changed: [localhost] => (item=AnsibleVol1)
changed: [localhost] => (item=AnsibleVol2)
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
tomas@labserver:~/ansible-openstack$ openstack volume list
tomas@labserver:~/ansible-openstack$
Základy jsme si vyzkoušeli a pojďme k něčemu trošku komplexnějšímu a také užitečnějšímu. Využijeme Ansible k poskládání ucelenější infrastruktury. Prohlédněte si playbook.
tomas@labserver:~/ansible-openstack$ cat infra.yml
---
- hosts: localhost
vars:
stav: present
porty:
- 22
- 80
- 443
- 8080
servery:
- AnsibleIns1
- AnsibleIns2
tasks:
- name: Pokud je to pozadovano, smaz server
os_server:
state: "{{ stav }}"
name: "{{ item }}"
image: Cirros
flavor: m1.tiny
network: AnsibleNet
with_items: "{{ servery }}"
when: stav == "absent"
- name: Ujisti se, ze Security Group je v pozadovanem stavu
os_security_group:
state: "{{ stav }}"
name: AnsibleSG
- name: Ujisti se, ze Security Group povoluje potrebne porty
os_security_group_rule:
security_group: AnsibleSG
protocol: tcp
port_range_min: "{{ item }}"
port_range_max: "{{ item }}"
with_items: "{{ porty }}"
when: stav == "present"
- name: Pokud je to pozadovano, smaz router
os_router:
state: "{{ stav }}"
name: AnsibleRouter
network: ext-net
interfaces:
- AnsibleSub
when: stav == "absent"
- name: Ujisti se, ze mame vytvorenou sit
os_network:
state: "{{ stav }}"
name: AnsibleNet
- name: Ujisti se, ze v siti je potrebny subnet
os_subnet:
network_name: AnsibleNet
name: AnsibleSub
cidr: 192.168.77.1/24
when: stav == "present"
- name: Pokud je to pozadovano, vytvor router a pripoj sit
os_router:
state: "{{ stav }}"
name: AnsibleRouter
network: ext-net
interfaces:
- AnsibleSub
when: stav == "present"
- name: Ujisti se, ze servery jsou vytvoreny
os_server:
name: "{{ item }}"
image: Cirros
flavor: m1.tiny
network: AnsibleNet
with_items: "{{ servery }}"
when: stav == "present"
Pracujeme vlastně stále stejným konceptem, jen jsme přidali víc zdrojů. Na začátku si definujeme výčet TCP portů, které naše servery používají (pro nastavení security group firewallu, tedy mikrosegmentace) a definujeme výčet s názvy serverů. Všimněte si, že aby fungovala i varianta s mazáním (stav „absent“) už nestačí jen poslat tento stav ve stejném pořadí, ale něco musíme dělat jinak (například server vytvářet jako poslední, ale mazat jako první). Proto někdy používáme „when“, což znamená, že krok se provede pouze za určitých okolností. Náš playbook tedy vytvoří síť, router s připojenou sítí a s napojením ven, security group včetně pravidel a dva servery. V praxi bychom to jistě rozšířili třeba o load-balancer a k instancím vytvořili a napojili volume.
Spusťme playbook.
tomas@labserver:~/ansible-openstack$ ansible-playbook infra.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Pokud je to pozadovano, smaz server] *************************************
skipping: [localhost] => (item=AnsibleIns1)
skipping: [localhost] => (item=AnsibleIns2)
TASK [Ujisti se, ze Security Group je v pozadovanem stavu] *********************
changed: [localhost]
TASK [Ujisti se, ze Security Group povoluje potrebne porty] ********************
changed: [localhost] => (item=22)
changed: [localhost] => (item=80)
changed: [localhost] => (item=443)
changed: [localhost] => (item=8080)
TASK [Pokud je to pozadovano, smaz router] *************************************
skipping: [localhost]
TASK [Ujisti se, ze mame vytvorenou sit] ***************************************
changed: [localhost]
TASK [Ujisti se, ze v siti je potrebny subnet] *********************************
changed: [localhost]
TASK [Pokud je to pozadovano, vytvor router a pripoj sit] **********************
changed: [localhost]
TASK [Ujisti se, ze servery jsou vytvoreny] ************************************
changed: [localhost] => (item=AnsibleIns1)
changed: [localhost] => (item=AnsibleIns2)
PLAY RECAP *********************************************************************
localhost : ok=7 changed=6 unreachable=0 failed=0
Podívejte se, jakou infrastrukturu jsme vytvořili.
Co když se rozhodneme třeba ještě jeden server přidat a také přidat ještě port 8443? Pokud bychom měli předpis v nějakém version control systému (třeba v Gitu), můžeme ho změnit a commitovat. V našem případě to uděláme tak, že si vytvoříme kopii souboru s názvem v2:
tomas@labserver:~/ansible-openstack$ cp infra.yml infra-v2.yml
V definici proměnných přidejme jeden port jeden server.
---
- hosts: localhost
vars:
stav: present
porty:
- 22
- 80
- 443
- 8080
- 8443
servery:
- AnsibleIns1
- AnsibleIns2
- AnsibleIns3
Spusťte playbook a všimněte si, že Ansible přidal jen to, co bylo skutečně potřeba (sledujte „changed“ vs. „ok“).
tomas@labserver:~/ansible-openstack$ ansible-playbook infra-v2.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Pokud je to pozadovano, smaz server] *************************************
skipping: [localhost] => (item=AnsibleIns1)
skipping: [localhost] => (item=AnsibleIns2)
skipping: [localhost] => (item=AnsibleIns3)
TASK [Ujisti se, ze Security Group je v pozadovanem stavu] *********************
ok: [localhost]
TASK [Ujisti se, ze Security Group povoluje potrebne porty] ********************
ok: [localhost] => (item=22)
ok: [localhost] => (item=80)
ok: [localhost] => (item=443)
ok: [localhost] => (item=8080)
changed: [localhost] => (item=8443)
TASK [Pokud je to pozadovano, smaz router] *************************************
skipping: [localhost]
TASK [Ujisti se, ze mame vytvorenou sit] ***************************************
ok: [localhost]
TASK [Ujisti se, ze v siti je potrebny subnet] *********************************
ok: [localhost]
TASK [Pokud je to pozadovano, vytvor router a pripoj sit] **********************
ok: [localhost]
TASK [Ujisti se, ze servery jsou vytvoreny] ************************************
ok: [localhost] => (item=AnsibleIns1)
ok: [localhost] => (item=AnsibleIns2)
changed: [localhost] => (item=AnsibleIns3)
PLAY RECAP *********************************************************************
localhost : ok=7 changed=2 unreachable=0 failed=0
Na závěr spustíme playbook s příznakem pro vymazání infrastruktury.
tomas@labserver:~/ansible-openstack$ ansible-playbook infra-v2.yml -e stav=absent
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Pokud je to pozadovano, smaz server] *************************************
changed: [localhost] => (item=AnsibleIns1)
changed: [localhost] => (item=AnsibleIns2)
changed: [localhost] => (item=AnsibleIns3)
TASK [Ujisti se, ze Security Group je v pozadovanem stavu] *********************
changed: [localhost]
TASK [Ujisti se, ze Security Group povoluje potrebne porty] ********************
skipping: [localhost] => (item=22)
skipping: [localhost] => (item=80)
skipping: [localhost] => (item=443)
skipping: [localhost] => (item=8080)
skipping: [localhost] => (item=8443)
TASK [Pokud je to pozadovano, smaz router] *************************************
changed: [localhost]
TASK [Ujisti se, ze mame vytvorenou sit] ***************************************
changed: [localhost]
TASK [Ujisti se, ze v siti je potrebny subnet] *********************************
skipping: [localhost]
TASK [Pokud je to pozadovano, vytvor router a pripoj sit] **********************
skipping: [localhost]
TASK [Ujisti se, ze servery jsou vytvoreny] ************************************
skipping: [localhost] => (item=AnsibleIns1)
skipping: [localhost] => (item=AnsibleIns2)
skipping: [localhost] => (item=AnsibleIns3)
PLAY RECAP *********************************************************************
localhost : ok=5 changed=4 unreachable=0 failed=0