Переход сервисов nova с pike на queen

Важный момент - исходная версия ОС - Debian 9

Входим в контейнер CMPT-0001 и архивируем текущие сервисы и pip пакеты:

mkdir /home/backup
tar cvfj /home/backup/nova-pike-$(date +%y%m%d).tbz /usr/local/bin/nova-* /usr/local/lib/python2.7/dist-packages/ /etv/nova

Ставим новую версию nova queens:

cd /opt
mv nova nova.pike
git clone https://opendev.org/openstack/nova.git -b stable/queens
pip install -r requirements.txt 

Successfully installed alembic-1.6.4 castellan-1.4.0 cursive-0.2.2 extras-1.0.0 fixtures-3.0.0 keystoneauth1-4.0.1 linecache2-1.0.0 monotonic-1.6 msgpack-1.0.2 networkx-2.2 os-brick-3.0.6 os-service-types-1.7.0 os-traits-2.2.0 os-win-5.0.2 os-xenapi-0.3.4 oslo.cache-1.38.1 oslo.concurrency-3.31.0 oslo.config-7.0.0 oslo.context-2.23.1 oslo.db-6.0.0 oslo.log-3.45.2 oslo.middleware-3.38.1 oslo.policy-2.4.1 oslo.privsep-1.34.0 oslo.utils-3.42.1 oslo.versionedobjects-1.37.0 pydot-1.4.2 pypowervm-1.1.26 python-cinderclient-6.0.0 python-dateutil-2.8.1 python-mimeparse-1.6.0 taskflow-3.8.0 testresources-2.0.1 testscenarios-0.5.0 testtools-2.4.0 traceback2-1.4.0 unittest2-1.1.0

python setup.py install

Смотрим текущую версию БД nova:

su -s /bin/sh -c 'nova-manage db version' nova

В ответ получаем ошибку:

alembic.util.exc.CommandError: SQLAlchemy 1.3.0 or greater is require

Смотрим, какая версия установлена и обновляем:

pip list | grep SQL
..
PyMySQL (0.7.10)
SQLAlchemy (1.1.12)
..
pip uninstall SQLAlchemy
pip install SQLAlchemy==1.3.0

Вновь смотрим текущую версию БД nova:

su -s /bin/sh -c 'nova-manage db version' nova
362
su -s /bin/sh -c 'nova-manage api_db version' nova

nova-manage cell_v2 list_cells
+-------+--------------------------------------+---------------------------------------+---------------------------------------------------+
|  Name |                 UUID                 |             Transport URL             |                Database Connection                |
+-------+--------------------------------------+---------------------------------------+---------------------------------------------------+
| cell0 | 00000000-0000-0000-0000-000000000000 |                 none:/                | mysql+pymysql://nova:****@192.168.30.2/nova_cell0 |
| cell1 | a3e1d215-ac6e-4f0d-8a5b-c76997955d23 | rabbit://openstack:****@192.168.30.15 |    mysql+pymysql://nova:****@192.168.30.2/nova    |
+-------+--------------------------------------+---------------------------------------+---------------------------------------------------+

Обновляем версию БД nova, nova_cells

su -s /bin/sh -c 'nova-manage db sync' nova
su -s /bin/sh -c 'nova-manage api_db sync' nova
su -s /bin/sh -c 'nova-manage api_db version' nova
su -s /bin/sh -c 'nova-manage cell_v2 map_cell0' nova
su -s /bin/sh -c 'nova-manage db sync' nova
nova-manage cell_v2 list_cells

Вновь проверяем версию БД:

su -s /bin/sh -c 'nova-manage db version' nova
373

Видим, что перешли с версии 362 на 373

При обновлении БД api_db произошла такая ошибка:

ScriptError: You can only have one Python script per version, but you have: /usr/local/lib/python2.7/dist-packages/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/045_placeholder.py and /usr/local/lib/python2.7/dist-packages/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/045_request_specs_spec_mediumtext.py

Исправляем и запускаем вновь:

mv /usr/local/lib/python2.7/dist-packages/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/045_request_specs_spec_mediumtext.py /home/backup
su -s /bin/sh -c 'nova-manage api_db sync' nova

Проверим версию api_db:

su -s /bin/sh -c 'nova-manage api_db version' nova
52

Если все хорошо - идем дальше.

nova-ctl restart
nova-ctl status

Видим, что nova-api останавливается спустя некоторое время после запуска.

Привожу ошибку из лога:

CRITICAL nova [req-2d7e1fec-0e00-4d8f-9d18-ec9bec8574d8 - - - - -] Unhandled error: ContextualVersionConflict: (six 1.10.0 (/usr/lib/python2.7/dist-packages), Requirement.parse('six>=1.11.0'), set(['oslo.log']))

Прежним методом, как SQLAlchemy исправить не получится, т.к. six установлен по-другому - а именно, через пакетный менеджер apt.

pip uninstall six
Not uninstalling six at /usr/lib/python2.7/dist-packages, outside environment /usr
...
find /usr/lib/python2.7/dist-packages -name "six*"
/usr/lib/python2.7/dist-packages/django/utils/six.pyc
/usr/lib/python2.7/dist-packages/django/utils/six.py
/usr/lib/python2.7/dist-packages/pkg_resources/_vendor/six.pyc
/usr/lib/python2.7/dist-packages/pkg_resources/_vendor/six.py
/usr/lib/python2.7/dist-packages/six.py
/usr/lib/python2.7/dist-packages/six.pyc
/usr/lib/python2.7/dist-packages/six-1.10.0.egg-info
...
dpkg -l | grep six
ii  python-six                    1.10.0-3                              all          Python 2 and 3 compatibility library (Python 2 interface)

Поэтому, действуем так:

apt purge python-six

The following packages were automatically installed and are no longer required:
  docutils-common ieee-data libblas-common libblas3 libdbus-glib-1-2 libgfortran3 libglib2.0-0 libjs-swfobject liblapack3 libxslt1.1 python-appdirs python-babel python-babel-localedata python-blinker
  python-cffi-backend python-chardet python-cmd2 python-dbus python-docutils python-enum34 python-funcsigs python-functools32 python-idna python-ipaddress python-iso8601 python-json-pointer
  python-jsonpatch python-jwt python-lxml python-monotonic python-msgpack python-netaddr python-netifaces python-numpy python-prettytable python-pyasn1 python-pyparsing python-rfc3986 python-roman
  python-simplejson python-unicodecsv python-websockify websockify websockify-common wget
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
  novnc* python-cinderclient* python-cliff* python-cryptography* python-debtcollector* python-glanceclient* python-jsonschema* python-keyring* python-keystoneauth1* python-keystoneclient*
  python-memcache* python-mock* python-neutronclient* python-novaclient* python-novnc* python-oauthlib* python-openstackclient* python-openstacksdk* python-os-client-config* python-osc-lib*
  python-oslo.config* python-oslo.i18n* python-oslo.serialization* python-oslo.utils* python-pbr* python-positional* python-requests* python-requestsexceptions* python-secretstorage* python-six*
  python-stevedore* python-urllib3* python-warlock* python-wrapt*
0 upgraded, 0 newly installed, 34 to remove and 71 not upgraded.

Не соглашаемся, т.к. эта операция затрагивает слишком много пакетов.

Дело в том, что на ОС Debian 9 штатная версия python-six именно 1.10.0 и обновить ее можно только обновив ОС.

Проверить можно на сайте https://pkgs.org/download/python-six

Там-же видим, что необходимая нам верcия пакета python-six 1.12.0 штатно присутствует в ОС Debian 10.

Или версия 1.11.0 в Ubuntu 18 LTS.

Т.о. делаем вывод о неизбежности смены версии ОС.

Обновление ОС

Сменить версию Debian с 9 на 10-ую командой ‘apt dist-upgrade’ не получится, поэтому сделаем новый контейнер с нужной нам версией ОС и переносим все конфигурационные файлы и исходники в него.

Я выбрал Ubuntu 18.04 LTS, т.к.

  • она содержит минимально необходимую нам версию python-six
  • штатно поддерживается в документации openstack

Создаем:

apt install dirmngr
gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 0xE7FB0CAEC8173D669066514CBAEFF88C22F6E216
lxc-create -n CMPT-0101 -t download

На перспективу выбрал такой индекс с учетом того, что первые два разряда отводим на индекс итерации релиза, а вторые два разряда - на порядковый номер контейнера.

Можно сделать и по-другому - вместо первых двух разрядов использовать букву релиза openstack - в данном случае было бы так: CMTP-Q01

Выбираем, соответственно, ubuntu-bionic-amd64

После установки копируем config контейнера CMPT-0001 и исправляем под новый индекс lxc.rootfs, lxc.utsname, lxc.network.hwaddr

Настраиваем сеть и запускаем новый контейнер с другим IP-адресом

cat /var/lib/lxc/CMPT-0101/rootfs/etc/netplan/10-lxc.yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses: [192.168.30.21/24]
      gateway4: 192.168.30.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
lxc-start -n CMPT-0101

Перенос настроек из старого контейнера

Далее, идут команды, которые надо запускать в новом контейнере.

lxc-attach -n CMPT-0101
export service=nova; useradd --uid 995 --home-dir /var/lib/${service} --create-home --system --shell /bin/false ${service}

apt update
apt install -y git vim netcat sockstat apache2 libapache2-mod-wsgi novnc
apt install -y python python-pip python-six python-memcache python-openstackclient python-zunclient python-pymysql python-novnc

for dd in /var/lib/nova/tmp /var/log/nova /etc/nova; do mkdir $dd; chown nova:nova $dd; done
echo -e "ServerName CMPT-0101" >> /etc/apache2/apache2.conf

Все настройки перенесем с помощью скрипта, который надо запустить из хоста.

#!/bin/bash
OLD_CNT="CMPT-0001"
NEW_CNT="CMPT-0101"
OLD_IP="192.168.30.21"
NEW_IP="192.168.30.22"

NCFL="
/usr/local/bin/nova-ctl
/root/admin-openrc
/root/demo-openrc
/root/.vimrc
/etc/apache2/sites-available/nova-metadata.conf
/etc/apache2/sites-available/nova-placement-api.conf
"
for NCF in $NCFL; do
  cp /var/lib/lxc/$OLD_CNT/rootfs/$NCF /var/lib/lxc/$NEW_CNT/rootfs/$NCF
done

cp -rpv /var/lib/lxc/$OLD_CNT/rootfs/etc/nova/* /var/lib/lxc/$NEW_CNT/rootfs/etc/nova/
cp -rpv /var/lib/lxc/$OLD_CNT/rootfs/etc/systemd/system/nova-*.service /var/lib/lxc/$NEW_CNT/rootfs/etc/systemd/system/
sed -i 's/'${OLD_IP}'/'${NEW_IP}'/g' /var/lib/lxc/$NEW_CNT/rootfs/etc/nova/nova.conf

Переходим к установке новой версии сервисов nova

cd /opt
git clone https://opendev.org/openstack/nova.git -b stable/queens
pip install -r requirements.txt
python setup.py install

a2ensite nova-metadata
a2ensite nova-placement-api
systemctl restart apache2

pip uninstall SQLAlchemy
pip install SQLAlchemy==1.3.0

nova-ctl enable
nova-ctl start
nova-ctl status

Проверяем клиента openstack

openstack
ImportError: No module named queue

Надо исправить импорт queue в двух файлах

sed -i  's/import queue/import Queue as queue/g' /usr/local/lib/python2.7/dist-packages/openstack/cloud/openstackcloud.py
sed -i  's/import queue/import Queue as queue/g' /usr/local/lib/python2.7/dist-packages/openstack/utils.py

После этого openstack client начнет работать

Поставим еще и zunclient:

apt install python-zunclient

Тестирование новых сервисов

Прежде чем переключаться на новую версию контейнера (и всех сервисов nova), надо удостовериться, что они работают.

nova-ctl status

....

Переключаемся на новые версии NOVA

Меняем IP-адрес контейнера CMPT в haproxy-контейнере (HPRX-0001)

cd /etc/haproxy
cp haproxy.cfg haproxy-1.cfg
sed -i 's/192.168.30.21/192.168.30.22/g' haproxy.cfg
systemctl restart haproxy
openstack compute service list