# Install manual

## Install manual

<https://habr.com/ru/articles/262049/>

В прошлой [статье](http://habrahabr.ru/post/261715/), я рассказывал о том, как можно быстро развернуть тестовую среду при помощи DevStack. В этой публикации я расскажу как развернуть своё «облако» OpenStack на двух машинах (Controller, Compute) в комплектации:

* Keystone
* Glance
* Nova
* Neutron
* Cinder
* Horizon

В общем-то эта система позволит нам запускать множество виртуальных машин (сколько позволит памяти и CPU на *compute*), создавать виртуальные сети, создавать виртуальные диски и подключать их к VM, ну и конечно управлять всем этим через удобный дашборд.

Осторожно! Много «портянок» со списком команд и конфигами!

Сразу скажу:

* Теоретически, я мог забыть что-то дописать или недоправить в конфигах, забыть, что нужно перезапустить какой-то сервис или ещё что-то.
* Публикация не клонирует, но берёт свои корни из официальной документации, которая есть [здесь](http://docs.openstack.org/kilo/install-guide/install/apt/content/) (*англ.*)
* Цель написания всего этого, чтобы был какой-то более-менее читабельный ман по OpenStack на русском языке. Не претендую, что получилось это у меня, но надеюсь это побудит кого-то сделать лучше. Так же, готов принять во внимание комментарии о необходимых правках публикации, дабы она стала более удобочитабельной.

Не надо бездумно «копипастить». Это, конечно, поможет установить OpenStack-среду по данному руководству, но не научит использовать это знание в полевых условиях.

#### **Что будем использовать?**

* Controller *i3-540/8Gb/2x120Gb + 2x500Gb/2NIC*
* Compute *i7-2600/32Gb/2x500Gb/1NIC*

ОС:

*Ubuntu 14.04*

(Можно использовать CentOS, но руководство будет основано на Ubuntu).

Редакция OpenStack:

*Kilo*

#### **Подготовка**

#### **Сеть**

В оригинальном руководстве используется 4 сети:

Management — 10.0.0.0/24 — VLAN 10

Tunnel — 10.0.1.0/24 — VLAN 11

Storage — 10.0.2.0/24 — VLAN 12

External — 192.168.1.0/24

External-сеть в нашем случае смотрит куда-нибудь в домашнюю сеть, но по большому счёту этот интерфейс может смотреть и во «всемирную паутину» — всё зависит от того, для чего разворачиваете облако.

Будет очень неплохо иметь работоспособный dns-server. Я использовал dnsmasq.

```bash
# cat /etc/hosts
10.0.0.11        controller
10.0.0.31        compute1

```

Настраиваем интерфейсы

**на контроллере:**

**на вычислительном узле:**

Проверяем, чтобы обе машины видели друг друга и ходили в сеть.

#### **NTP**

На контроллере:

```bash
# apt-get install ntp -y
# cat /etc/ntp.conf
server ntp.oceantelecom.ru iburst
restrict -4 default kod notrap nomodify
restrict -6 default kod notrap nomodify
# service ntp stop
# ntpdate ntp.oceantelecom.ru
# service ntp start

```

На вычислительной ноде:

```bash
# apt-get install ntp -y
# cat /etc/ntp.conf
server controller iburst
# service ntp stop
# ntpdate controller
# service ntp start

```

#### **Репозиторий Kilo**

```bash
# apt-get install ubuntu-cloud-keyring
# echo "deb http://ubuntu-cloud.archive.canonical.com/ubuntu" "trusty-updates/kilo main" > /etc/apt/sources.list.d/cloudarchive-kilo.list

```

Kilo довольно молодой выпуск — апрель 2015 года. Больше всего в этом релизе мне понравился русский язык в интерфейсе Horizon.

Более подробно можно почитать

[тут](https://wiki.openstack.org/wiki/ReleaseNotes/Kilo)

.

Обновляемся:

```bash
# apt-get update && apt-get dist-upgrade -y

```

#### **SQL + RabbitMQ**

В роли SQL сервера может быть MySQL, PostgreSQL, Oracle или любой другой, который поддерживается SQLAlchemy. Мы будем устанавливать MariaDB как и в официальном мануале.

```bash
# apt-get install mariadb-server python-mysqldb -y
# cat /etc/mysql/conf.d/mysqld_openstack.cnf
[mysqld]
bind-address = 10.0.0.11
default-storage-engine = innodb
innodb_file_per_table
collation-server = utf8_general_ci
init-connect = 'SET NAMES utf8'
character-set-server = utf8

# service mysql restart
# mysql_secure_installation

```

Если есть лишние HDD с хорошей производительностью, то файлы БД можно положить на него и это не будет лишним, если вы планируете развивать стенд вычислительными нодами.

Ну и конечно же RabbitMQ:

```bash
# apt-get install rabbitmq-server
# rabbitmq-plugins enable rabbitmq_management
# service rabbitmq-server restart

```

Мы устанавливаем рээбита и запускаем административную WebGUI, для удобства слежения за очередями.

Создаём пользователя и устанавливаем права ему:

```bash
rabbitmqctl add_user openstack RABBIT_PASS
rabbitmqctl set_permissions openstack ".*" ".*" ".*"

```

#### **Keystone**

Keystone — центр авторизации для OpenStack. Все авторизации проходят через него. Данные Keystone хранит в SQL-БД, но использует так же и memcache.

Подготовим БД:

```bash
# mysql -u root -p
CREATE DATABASE keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'KEYSTONE_DBPASS';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'KEYSTONE_DBPASS';

```

Естественно, не забудьте подставить свой пароль, как и везде.

Отключаем автозагрузку keystone сервиса и устанавливаем все необходимые компоненты:

```bash
# echo "manual" > /etc/init/keystone.override
# apt-get install keystone python-openstackclient apache2 libapache2-mod-wsgi memcached python-memcache

```

В конфиге

*/etc/keystone/keystone.conf*

прописываем следующие строки:

```bash
[DEFAULT]
admin_token = ADMIN_TOKEN

[database]
connection = mysql://keystone:KEYSTONE_DBPASS@controller/keystone

[memcache]
servers = localhost:11211

[token]
provider = keystone.token.providers.uuid.Provider
driver = keystone.token.persistence.backends.memcache.Token

[revoke]
driver = keystone.contrib.revoke.backends.sql.Revoke

```

*ADMIN\_TOKEN*

генерим при помощи "*openssl rand -hex 16*".

Синхронизируем локальную БД с SQL сервером

```bash
# su -s /bin/sh -c "keystone-manage db_sync" keystone

```

Настраиваем апач:

**портянка**

\# cat /etc/apache2/apache2.conf ... ServerName controller ...

```
cat /etc/apache2/sites-available/wsgi-keystone.conf
Listen 5000 Listen 35357
<VirtualHost *:5000> WSGIDaemonProcess keystone-public processes=5 threads=1 user=keystone display-name=%{GROUP} WSGIProcessGroup keystone-public WSGIScriptAlias / /var/www/cgi-bin/keystone/main WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On = 2.4> ErrorLogFormat "%{cu}t %M" LogLevel info ErrorLog /var/log/apache2/keystone-error.log CustomLog /var/log/apache2/keystone-access.log combined
<VirtualHost *:35357> WSGIDaemonProcess keystone-admin processes=5 threads=1 user=keystone display-name=%{GROUP} WSGIProcessGroup keystone-admin WSGIScriptAlias / /var/www/cgi-bin/keystone/admin WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On = 2.4> ErrorLogFormat "%{cu}t %M" LogLevel info ErrorLog /var/log/apache2/keystone-error.log CustomLog /var/log/apache2/keystone-access.log combined
ln -s /etc/apache2/sites-available/wsgi-keystone.conf /etc/apache2/sites-enabled
mkdir -p /var/www/cgi-bin/keystone
curl http://git.openstack.org/cgit/openstack/keystone/plain/httpd/keystone.py?h=stable/kilo | tee /var/www/cgi-bin/keystone/main /var/www/cgi-bin/keystone/admin
chown -R keystone:keystone /var/www/cgi-bin/keystone
chmod 755 /var/www/cgi-bin/keystone/*
service apache2 restart
rm -f /var/lib/keystone/keystone.db`
```

Мы меняем

*ServerName*

на имя нашего контроллера.

Рабочие скрипты мы берём с репозитория openstack.

Настроим endpoint`ы. Вообщем-то именно благодаря endpoint`ам openstack будет знать где и какой сервис работает.

Добавим переменные окружения, для того чтобы не указывать их каждый раз в параметрах keystone:

```bash
# export OS_TOKEN=ADMIN_TOKEN
# export OS_URL=http://controller:35357/v2.0

```

Теперь создаём сервис:

```bash
# openstack service create  --name keystone --description "OpenStack Identity" identity

```

Ну и создаём API endpoint:

```bash
# openstack endpoint create  --publicurl http://controller:5000/v2.0 --internalurl http://controller:5000/v2.0 --adminurl http://controller:35357/v2.0 --region RegionOne  identity

```

*RegionOne*

можно поменять на любое удобочитаемое имя. Я буду использовать его, чтобы не «заморачиваться».

Создаём проекты, пользователей и роли.

Будем продолжать делать по официальному ману, так что всё так же: админ и демо

```bash
# openstack project create --description "Admin Project" admin
# openstack user create --password-prompt admin
# openstack role create admin
# openstack role add --project admin --user admin admin

```

Пароль для админа придумайте сами. По порядку: создали проект «Admin Project», пользователя и роль admin, и соединяем проект и пользователя с ролью.

Теперь создаём проект

*service*:

```bash
# openstack project create --description "Service Project" service

```

По аналогии с admin\`ом создаём demo:

```bash
# openstack project create --description "Demo Project" demo
# openstack user create --password-prompt demo
# openstack role create user
# openstack role add --project demo --user demo user

```

Создадим скрипты окружения:

**скрипты**

```
# cat admin-openrc.sh 
export OS_PROJECT_DOMAIN_ID=default 
export OS_USER_DOMAIN_ID=default 
export OS_PROJECT_NAME=admin 
export OS_TENANT_NAME=admin 
export OS_USERNAME=admin 
export OS_PASSWORD=ADMIN_PASS 
export OS_AUTH_URL=http://controller:35357/v3 
export OS_IMAGE_API_VERSION=2 
export OS_VOLUME_API_VERSION=2
```

```
#cat demo-openrc.sh
export OS_PROJECT_DOMAIN_ID=default 
export OS_USER_DOMAIN_ID=default 
export OS_PROJECT_NAME=demo 
export OS_TENANT_NAME=demo 
export OS_USERNAME=demo 
export OS_PASSWORD=DEMO_PASS 
export OS_AUTH_URL=http://controller:5000/v3 
export OS_IMAGE_API_VERSION=2 
export OS_VOLUME_API_VERSION=2`
```

Собственно:

```bash
# source admin-openrc.sh

```

На этом настройка сервиса

*keystone*

закончена.

#### **Glance**

Glance — это инструмент OpenStack для хранения шаблонов (образов) виртуальных машин. Образы могут храниться в Swift, в собственном хранилище Glance\`а, но и где-то ещё — главное чтобы этот образ можно было получить по http.

Начнём как всегда с *mysql*:

```bash
# mysql -u root -p
CREATE DATABASE glance;
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'GLANCE_DBPASS';
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'GLANCE_DBPASS';

```

Создадим в *keystone* информацию о будущем сервисе:

```bash
# openstack user create --password-prompt glance
# openstack role add --project service --user glance admin
# openstack service create --name glance  --description "OpenStack Image service" image
# openstack endpoint create --publicurl http://controller:9292 --internalurl http://controller:9292 --adminurl http://controller:9292 --region RegionOne image

```

Мы создаём пользователя *glance* и подключаем его к роли *admin*, т.к. все сервисы будут работать именно от этой роли, мы создаём сервис *glance*, задаём endpoint.

Теперь приступим к установке:

```bash
# apt-get install glance python-glanceclient

```

и настройке:

**настройка**

\`# cat /etc/glance/glance-api.conf \[DEFAULT] ... notification\_driver = noop

\[database] connection = mysql://glance:GLANCE\_DBPASS\@controller/glance

\[keystone\_authtoken] auth\_uri = <http://controller:5000> auth\_url = <http://controller:35357> auth\_plugin = password project\_domain\_id = default user\_domain\_id = default project\_name = service username = glance password = GLANCE\_PASS

\[paste\_deploy] flavor = keystone

\[glance\_store] default\_store = file filesystem\_store\_datadir = /var/lib/glance/images/\`

Что бы ни было в секции

*\[keystone\_authtoken]*

— это нужно удалить. GLANCE\_PASS — пароль от пользователя glance в keystone.

*filesystem\_store\_datadir*

это путь к хранилищу, где будут лежать наши образы. Рекомендую подмонтировать к этой директории или рейд-массив или надёжное сетевое хранилище, чтобы случайно не потерять все наши образы из-за отказа диска.

В

*/etc/glance/glance-registry.conf*

дублируем ту же информацию из секций

*database, keystone\_authtoken, paste\_deploy, DEFAULT*

.

Синхронизируем БД:

```bash
# su -s /bin/sh -c "glance-manage db_sync" glance

```

Перезапускаем сервисы и удаляем локальную БД:

```bash
# service glance-registry restart
# service glance-api restart
# rm -f /var/lib/glance/glance.sqlite

```

В официальном мануале загружается

*cirros*

, который в общем-то нам не нужен, так что мы загрузим образ Ubuntu:

```bash
# mkdir /tmp/images
# wget -P /tmp/images http://cloud-images.ubuntu.com/releases/14.04.2/release/ubuntu-14.04-server-cloudimg-amd64-disk1.img
# glance image-create --name "Ubuntu-Server-14.04.02-x86_64" --file /tmp/images/ubuntu-14.04-server-cloudimg-amd64-disk1.img  --disk-format qcow2 --container-format bare --visibility public --progress
# rm -r /tmp/images

```

Можно сразу залить все нужные нам образы, но думаю дождёмся момента, когда у нас появится Dashboard.

Целом — наш сервис Glance готов.

#### **Nova**

Nova — основная часть IaaS в OpenStack. Собственно благодаря Nova создаются виртуальные машины автоматически. Nova может взаимодействовать с KVM, Xen, Hyper-V, VMware и кажется Ironic (честно говоря не совсем понимаю как это работает). Мы будем использовать KVM, для других гипервизоров конфиги будут отличаться.

#### **Контроллер**

Опять начинаем с БД:

```bash
# mysql -u root -p
CREATE DATABASE nova;
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS';
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS';

```

Добавляем информацию в keystone:

```bash
# openstack user create --password-prompt nova
# openstack role add --project service --user nova admin
# openstack service create --name nova --description "OpenStack Compute" compute
# openstack endpoint create --publicurl http://controller:8774/v2/%\(tenant_id\)s --internalurl http://controller:8774/v2/%\(tenant_id\)s --adminurl http://controller:8774/v2/%\(tenant_id\)s --region RegionOne compute

```

Устанавливаем необходимые пакеты:

```bash
# apt-get install nova-api nova-cert nova-conductor nova-consoleauth nova-novncproxy nova-scheduler python-novaclient

```

**/etc/nova/nova.conf**

\`\[DEFAULT] ... rpc\_backend = rabbit auth\_strategy = keystone my\_ip = 10.0.0.11 vncserver\_listen = 10.0.0.11 vncserver\_proxyclient\_address = 10.0.0.11

\[database] connection = mysql://nova:NOVA\_DBPASS\@controller/nova

\[oslo\_messaging\_rabbit] rabbit\_host = controller rabbit\_userid = openstack rabbit\_password = RABBIT\_PASS

\[keystone\_authtoken] auth\_uri = <http://controller:5000> auth\_url = <http://controller:35357> auth\_plugin = password project\_domain\_id = default user\_domain\_id = default project\_name = service username = nova password = NOVA\_PASS

\[glance] host = controller

\[oslo\_concurrency] lock\_path = /var/lib/nova/tmp\`

Синхронизируем БД, перезапускаем сервисы и удаляем локальную БД.

```bash
# su -s /bin/sh -c "nova-manage db sync" nova
# service nova-api restart
# service nova-cert restart
# service nova-consoleauth restart
# service nova-scheduler restart
# service nova-conductor restart
# service nova-novncproxy restart
# rm -f /var/lib/nova/nova.sqlite

```

#### **Вычислительный узел**

Теперь мы наконец начнём работать с вычислительным узлом. Все описанные действия справедливы для каждого вычислительного узла в нашей системе.

```bash
# apt-get install nova-compute sysfsutils

```

**/etc/nova/nova.conf**

\`\[DEFAULT] ... verbose = True rpc\_backend = rabbit auth\_strategy = keystone my\_ip = 10.0.0.31 #MANAGEMENT\_INTERFACE\_IP\_ADDRESS vnc\_enabled = True vncserver\_listen = 0.0.0.0 vncserver\_proxyclient\_address = 10.0.0.31 #MANAGEMENT\_INTERFACE\_IP\_ADDRESS novncproxy\_base\_url = <http://controller:6080/vnc\\_auto.html>

\[oslo\_messaging\_rabbit] rabbit\_host = controller rabbit\_userid = openstack rabbit\_password = RABBIT\_PASS

\[keystone\_authtoken] auth\_uri = <http://controller:5000> auth\_url = <http://controller:35357> auth\_plugin = password project\_domain\_id = default user\_domain\_id = default project\_name = service username = nova password = NOVA\_PASS

\[glance] host = controller

\[oslo\_concurrency] lock\_path = /var/lib/nova/tmp

\[libvirt] virt\_type = kvm\`

*MANAGEMENT\_INTERFACE\_IP\_ADDRESS*

это адрес вычислительного узла из VLAN 10.

В

*novncproxy\_base\_url*

controller должен соответствовать тому адресу, через который будет возможность обратиться через Web-browser. Иначе вы не сможете воспользоваться vnc-консолью из Horizon.

Перезапускаем сервис и удаляем локальную копию БД:

```bash
# service nova-compute restart
# rm -f /var/lib/nova/nova.sqlite

```

Проверяем всё ли правильно работает:

```bash
# nova service-list
+----+------------------+------------+----------+---------+-------+----------------------------+-----------------+
| Id | Binary           | Host       | Zone     | Status  | State | Updated_at                 | Disabled Reason |
+----+------------------+------------+----------+---------+-------+----------------------------+-----------------+
| 1  | nova-conductor   | controller | internal | enabled | up    | 2014-09-16T23:54:02.000000 | -               |
| 2  | nova-consoleauth | controller | internal | enabled | up    | 2014-09-16T23:54:04.000000 | -               |
| 3  | nova-scheduler   | controller | internal | enabled | up    | 2014-09-16T23:54:07.000000 | -               |
| 4  | nova-cert        | controller | internal | enabled | up    | 2014-09-16T23:54:00.000000 | -               |
| 5  | nova-compute     | compute1   | nova     | enabled | up    | 2014-09-16T23:54:06.000000 | -               |
+----+------------------+------------+----------+---------+-------+----------------------------+-----------------+

```

5ая строчка говорит о том, что мы всё правильно сделали.

Мы сделали самое главное — теперь у нас есть IaaS.

#### **Neutron**

Neutron это сервис предоставляющий сеть как услуга (NaaS). Вообще официальная документация немного другое определение даёт, но так думаю будет понятнее. Nova-networking объявлен как устаревший в новых версиях OpenStack, поэтому его мы использовать не будем. Да и функционал у neutron значительно шире.

#### **Контроллер**

Мы устанавливаем ядро сети на контроллере, хотя в мануале используется 3я нода. Если вычислительных нод будет достаточно много (>10) и/или сетевая нагрузка будет достаточно высокая, то лучше вынести Network-сервер на отдельную ноду.

Как всегда начнём с БД

```bash
# mysql -u root -p
CREATE DATABASE neutron;
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'NEUTRON_DBPASS';
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'NEUTRON_DBPASS';

```

Keystone:

```bash
# openstack user create --password-prompt neutron
# openstack role add --project service --user neutron admin
# openstack service create --name neutron --description "OpenStack Networking" network
# openstack endpoint create --publicurl http://controller:9696 --adminurl http://controller:9696 --internalurl http://controller:9696 --region RegionOne network

```

Устанавливаем необходимые компоненты:

```bash
# apt-get install neutron-server neutron-plugin-ml2 python-neutronclient neutron-plugin-openvswitch-agent neutron-l3-agent neutron-dhcp-agent neutron-metadata-agent

```

Так же необходимо подправить

*/etc/sysctl.conf*

```bash
# cat /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0

# sysctl -p

```

**/etc/neutron/neutron.conf**

\`\[DEFAULT] ... rpc\_backend = rabbit auth\_strategy = keystone core\_plugin = ml2 service\_plugins = router allow\_overlapping\_ips = True notify\_nova\_on\_port\_status\_changes = True notify\_nova\_on\_port\_data\_changes = True nova\_url = <http://controller:8774/v2>

\[oslo\_messaging\_rabbit] rabbit\_host = controller rabbit\_userid = openstack rabbit\_password = RABBIT\_PASS

\[database] connection = mysql://neutron:NEUTRON\_DBPASS\@controller/neutron

\[keystone\_authtoken] auth\_uri = <http://controller:5000> auth\_url = <http://controller:35357> auth\_plugin = password project\_domain\_id = default user\_domain\_id = default project\_name = service username = neutron password = NEUTRON\_PASS

\[nova] auth\_url = <http://controller:35357> auth\_plugin = password project\_domain\_id = default user\_domain\_id = default region\_name = RegionOne project\_name = service username = nova password = NOVA\_PASS\`

Редактируя конфиг не следует ничего оттуда удалять, кроме закомментированных строк.

**/etc/neutron/plugins/ml2/ml2\_conf.ini**

\`\[ml2] type\_drivers = flat,vlan,gre,vxlan tenant\_network\_types = gre mechanism\_drivers = openvswitch

\[ml2\_type\_gre] tunnel\_id\_ranges = 1000:2000

\[ml2\_type\_flat] flat\_networks = external

\[securitygroup] enable\_security\_group = True enable\_ipset = True firewall\_driver = neutron.agent.linux.iptables\_firewall.OVSHybridIptablesFirewallDriver

\[ovs] local\_ip = 10.0.1.11 #INSTANCE\_TUNNELS\_INTERFACE\_IP\_ADDRESS bridge\_mappings = external:br-ex

\[agent] tunnel\_types = gre\`

**/etc/neutron/l3\_agent.ini**

`[DEFAULT] interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver external_network_bridge = router_delete_namespaces = True`

**/etc/neutron/dhcp\_agent.ini**

`[DEFAULT] interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq dhcp_delete_namespaces = True dnsmasq_config_file = /etc/neutron/dnsmasq-neutron.conf`

**/etc/neutron/dnsmasq-neutron.conf**

`dhcp-option-force=26,1454` В официальной документации эта настройка использовалась для сетевых устройств без поддержки jumbo frames, но в целом там можно прописать практически любые настройки для dnsmasq.

Убиваем все процессы dnsmasq

```bash
# pkill dnsmasq

```

**/etc/neutron/metadata\_agent.ini**

`[DEFAULT] auth_uri = http://controller:5000 auth_url = http://controller:35357 auth_region = RegionOne auth_plugin = password project_domain_id = default user_domain_id = default project_name = service username = neutron password = NEUTRON_PASS nova_metadata_ip = controller metadata_proxy_shared_secret = METADATA_SECRET`

**/etc/nova/nova.conf**

\`\[DEFAULT] ... network\_api\_class = nova.network.neutronv2.api.API security\_group\_api = neutron linuxnet\_interface\_driver = nova.network.linux\_net.LinuxOVSInterfaceDriver firewall\_driver = nova.virt.firewall.NoopFirewallDriver

\[neutron] url = <http://controller:9696> auth\_strategy = keystone admin\_auth\_url = <http://controller:35357/v2.0> admin\_tenant\_name = service admin\_username = neutron admin\_password = NEUTRON\_PASS service\_metadata\_proxy = True metadata\_proxy\_shared\_secret = METADATA\_SECRET\` *METADATA\_SECRET* это так же набор символов от 10 до 16 символов

Из

*nova.conf*

не удаляем ничего, только добавляем.

Синхронизируем БД и перезапускаем сервисы:

```bash
# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
# service nova-api restart
# service neutron-server restart
# service openvswitch-switch restart

```

Создаём мост и связываем его с external-интерфейсом

```bash
# ovs-vsctl add-br br-ex
# ovs-vsctl add-port br-ex p3p1

```

Перезапускаем интерфейсы

```bash
# service neutron-plugin-openvswitch-agent restart
# service neutron-l3-agent restart
# service neutron-dhcp-agent restart
# service neutron-metadata-agent restart

```

#### **Вычислительный узел**

Без комментариев.

```bash
# cat /etc/sysctl.conf
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1

# sysctl -p

```

```bash
# apt-get install neutron-plugin-ml2 neutron-plugin-openvswitch-agent

```

**/etc/neutron/neutron.conf**

\`\[DEFAULT] ... rpc\_backend = rabbit auth\_strategy = keystone core\_plugin = ml2 service\_plugins = router allow\_overlapping\_ips = True

\[oslo\_messaging\_rabbit] rabbit\_host = controller rabbit\_userid = openstack rabbit\_password = RABBIT\_PASS

\[keystone\_authtoken] auth\_uri = <http://controller:5000> auth\_url = <http://controller:35357> auth\_plugin = password project\_domain\_id = default user\_domain\_id = default project\_name = service username = neutron password = NEUTRON\_PASS\`

**/etc/neutron/plugins/ml2/ml2\_conf.ini**

\`\[ml2] type\_drivers = flat,vlan,gre,vxlan tenant\_network\_types = gre mechanism\_drivers = openvswitch

\[ml2\_type\_gre] tunnel\_id\_ranges = 1000:2000

\[ml2\_type\_flat] flat\_networks = external

\[securitygroup] enable\_security\_group = True enable\_ipset = True firewall\_driver = neutron.agent.linux.iptables\_firewall.OVSHybridIptablesFirewallDriver

\[ovs] local\_ip = 10.0.1.31 #INSTANCE\_TUNNELS\_INTERFACE\_IP\_ADDRESS bridge\_mappings = external:br-ex

\[agent] tunnel\_types = gre\`

Перезапускаем openvswitch

```bash
# service openvswitch-switch restart

```

Добавляем строчки в

*/etc/nova/nova.conf*

```bash
[DEFAULT]
...
network_api_class = nova.network.neutronv2.api.API
security_group_api = neutron
linuxnet_interface_driver = nova.network.linux_net.LinuxOVSInterfaceDriver
firewall_driver = nova.virt.firewall.NoopFirewallDriver

[neutron]
url = http://controller:9696
auth_strategy = keystone
admin_auth_url = http://controller:35357/v2.0
admin_tenant_name = service
admin_username = neutron
admin_password = NEUTRON_PASS

```

Перезапускаем сервисы:

```bash
# service nova-compute restart
# service neutron-plugin-openvswitch-agent restart

```

Если я ничего не забыл упомянуть, то должно получиться так:

```bash
# neutron agent-list
+--------------------------------------+--------------------+----------+-------+----------------+---------------------------+
| id                                   | agent_type         | host     | alive | admin_state_up | binary                    |
+--------------------------------------+--------------------+----------+-------+----------------+---------------------------+
| 30275801-e17a-41e4-8f53-9db63544f689 | Metadata agent     | network  | :-)   | True           | neutron-metadata-agent    |
| 4bd8c50e-7bad-4f3b-955d-67658a491a15 | Open vSwitch agent | network  | :-)   | True           | neutron-openvswitch-agent |
| 756e5bba-b70f-4715-b80e-e37f59803d20 | L3 agent           | network  | :-)   | True           | neutron-l3-agent          |
| 9c45473c-6d6d-4f94-8df1-ebd0b6838d5f | DHCP agent         | network  | :-)   | True           | neutron-dhcp-agent        |
| a5a49051-05eb-4b4f-bfc7-d36235fe9131 | Open vSwitch agent | compute1 | :-)   | True           | neutron-openvswitch-agent |
+--------------------------------------+--------------------+----------+-------+----------------+---------------------------+

```

#### **Сети**

Сейчас мы сделаем начальную заготовку наших сетей. Мы создадим одну внешнюю сеть и одну внутреннюю.

Создаём виртуальную сеть:

```bash
# neutron net-create ext-net --router:external --provider:physical_network external --provider:network_type flat

```

Настраиваем нашу внешнюю подсеть:

```bash
# neutron subnet-create ext-net 192.168.1.0/24 --name ext-subnet \
  --allocation-pool start=192.168.1.100,end=192.168.1.200 \
  --disable-dhcp --gateway 192.168.1.1

```

Наша внешняя сеть 192.168.1.0/24 и маршрутизатор выпускающий в интернет 192.168.1.1. Внешние адреса для нашего облака будут выдаваться из диапазона 192.168.1.101-200.

Далее мы будем создавать внутреннюю сеть для проекта

*demo*

, поэтому следует загрузить переменные для demo-юзера:

```bash
# source demo-openrc.sh

```

Теперь создаём виртуальную внутреннюю сеть:

```bash
# neutron net-create demo-net
# neutron subnet-create demo-net 172.16.1.0/24 --name demo-subnet --gateway 172.16.1.1

```

Понятно, что наша виртуальная сеть будет 172.16.1.0/24 и все инстансы из неё будут получать в качестве маршрутизатора 172.16.1.1.

Вопрос: что это за маршрутизатор?

Ответ: это виртуальный маршрутизатор.

«Фишка» в том, что в Neutron можно строить виртуальные сети с достаточно большим количеством подсетей, а значит для них необходим виртуальный маршрутизатор. Каждый виртуальный маршрутизатор можно добавлять порты в любую из доступных виртуальных и внешних сетей. И это действительно «сильно»! Мы назначаем маршрутизаторам только только доступ к сетям, а всеми правилами firewall мы управляем из групп безопасности. Более того! Мы можем создать виртуальную машину с программным маршрутизатором, настроить интерфейсы во все необходимые сети и управлять доступом через него (я пробовал использовать Mikrotik).

В общем, Neutron даёт простор фантазии.

Создаём виртуальный маршрутизатор, назначаем ему интерфейс в demo-subnet и присоединяем его к внешней сети:

```bash
# neutron router-create demo-router
# neutron router-interface-add demo-router demo-subnet
# neutron router-gateway-set demo-router ext-net

```

Теперь из внешней сети должен пинговаться наш виртуальный маршрутизатор:

```bash
# ping 192.168.1.100
PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data.
64 bytes from 192.168.1.100: icmp_req=1 ttl=64 time=0.619 ms
64 bytes from 192.168.1.100: icmp_req=2 ttl=64 time=0.189 ms
64 bytes from 192.168.1.100: icmp_req=3 ttl=64 time=0.165 ms
64 bytes from 192.168.1.100: icmp_req=4 ttl=64 time=0.216 ms
...

```

В целом, у нас уже есть работоспособное облако с сетью.

#### **Cinder (Блочное хранилище)**

Cinder — сервис предоставляющий возможность управлять блочными устройствами (виртуальными дисками), присоединять их к виртуальным инстансам. Виртуальные диски могут быть и загрузочными. Это может быть очень удобно для переноса VM на другой вычислительный инстанс.

БД:

```bash
# mysql -u root -p
CREATE DATABASE cinder;
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'CINDER_DBPASS';
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'CINDER_DBPASS';

```

Keystone:

```bash
# openstack user create --password-prompt cinder
# openstack role add --project service --user cinder admin
# openstack service create --name cinder --description "OpenStack Block Storage" volume
# openstack service create --name cinderv2 --description "OpenStack Block Storage" volumev2
# openstack endpoint create --publicurl http://controller:8776/v2/%\(tenant_id\)s --internalurl http://controller:8776/v2/%\(tenant_id\)s --adminurl http://controller:8776/v2/%\(tenant_id\)s --region RegionOne volume
# openstack endpoint create --publicurl http://controller:8776/v2/%\(tenant_id\)s --internalurl http://controller:8776/v2/%\(tenant_id\)s --adminurl http://controller:8776/v2/%\(tenant_id\)s --region RegionOne volumev2

```

Установка необходимых пакетов:

```bash
# apt-get install cinder-api cinder-scheduler python-cinderclient

```

Поправим конфиг:

**/etc/cinder/cinder.conf**

\`\[DEFAULT] ... rpc\_backend = rabbit auth\_strategy = keystone my\_ip = 10.0.0.11

\[oslo\_messaging\_rabbit] rabbit\_host = controller rabbit\_userid = openstack rabbit\_password = RABBIT\_PASS

\[database] connection = mysql://cinder:CINDER\_DBPASS\@controller/cinder

\[keystone\_authtoken] auth\_uri = <http://controller:5000> auth\_url = <http://controller:35357> auth\_plugin = password project\_domain\_id = default user\_domain\_id = default project\_name = service username = cinder password = CINDER\_PASS

\[oslo\_concurrency] lock\_path = /var/lock/cinder\`

Далее синхронизируем БД и перезапускаем сервисы:

```bash
# su -s /bin/sh -c "cinder-manage db sync" cinder
# service cinder-scheduler restart
# service cinder-api restart

```

Т.к. наш контроллер будет так же и хранилищем, то следующие действия так же проводим на нём.

Устанавливаем необходимые пакеты:

```bash
# apt-get install qemu lvm2

```

Помните я упоминал в конфигурации про два 500Гб диска? Мы из них сделаем RAID 1 (уж это описывать я не буду). Чисто технически, мы могли бы просто создать lvm-раздел из двух физических дисков, но такой вариант плох тем, что у нас не HA-проект и падение одного из дисков может быть критичным. Разбирать как создать RAID-массив я не буду, это легко гуглится. Будем считать, что наш рейд называется

*/dev/md1*

:

```bash
# pvcreate /dev/md1
# vgcreate cinder-volumes /dev/md1

```

Мы создали физическое LVM-устройство и создали lvm-группу

*cinder-volumes*

.

Далее правим

*/etc/lvm/lvm.conf*

.

Находим (или добавляем) туда такую строку:

```bash
devices {
...
filter = [ "a/md1/", "r/.*/"]

```

Будем считать, что кроме как на рейд-разделе у нас ничего связанного с lvm нет. Если рабочий раздел так же развёрнут на lvm, то следует его добавить. Например, если наша система развёрнута на

*/dev/md0*

и поверх неё развёрнут lvm, то наш конфиг будет выглядеть так:

```bash
devices {
...
filter = [ "a/md0/", "a/md1/", "r/.*/"]

```

В целом, думаю для тех, кто сталкивался с lvm это не должно быть сложно.

Устанавливаем необходимые пакеты:

```bash
# apt-get install cinder-volume python-mysqldb

```

добавляем в конфиг:

**/etc/cinder/cinder.conf**

\`\[DEFAULT] ... enabled\_backends = lvm glance\_host = controller

\[lvm] volume\_driver = cinder.volume.drivers.lvm.LVMVolumeDriver volume\_group = cinder-volumes iscsi\_protocol = iscsi iscsi\_helper = tgtadm\`

И перезапускаем сервисы:

```bash
# service tgt restart
# service cinder-scheduler restart
# service cinder-api restart
# service cinder-volume restart

```

#### **Horizon (dashboard)**

Horizon — дашбоард для OpenStack, написан на Python 2.7, движком является Django. Из него ведётся полное управление всей средой OpenStack: управление пользователями/проектами/ролями, управление образами, виртуальными дисками, инстансами, сетями и т.д.

#### **Установка**

```bash
# apt-get install openstack-dashboard

```

Установку можно производить на отдельном сервере с доступом к Controller-ноде, но мы установим на контроллере.

Поправим конфиг

*/etc/openstack-dashboard/local\_settings.py*

:

```bash
...
OPENSTACK_HOST = "controller"
...
ALLOWED_HOSTS = '*'
...
CACHES = {
   'default': {
       'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
       'LOCATION': '127.0.0.1:11211',
   }
}
...
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"
...
TIME_ZONE = "Asia/Vladivostok"
...

```

*TIME\_ZONE*

— ваш часовой пояс может быть (и скорее всего будет) другой.

[Тут](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) найдёте свой.

Перезапускаем Апач:

```bash
# service apache2 reload

```

Теперь можно заходить на

[*controller/horizon*](http://controller/horizon)

. В предыдущей моей публикации можно посмотреть скрины дашборда. В ubuntu дополнительно устанавливается пакет

*openstack-dashboard-ubuntu-theme*

, который добавляет некоторые ссылки с намёком на Juju. Если захочется вернуть оригинальную версию, то можно просто удалить пакет.

Так же можно в профиле пользователя выбрать язык интерфейса

*Русский*, то изрядно облегчит работу Developer\`ам.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.konstantinsecurity.com/readme/architect/openstack/install-manual.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
