Введение
oVirt — свободная, кроссплатформенная система управления виртуализацией. Была разработана компанией Red Hat как проект сообщества на котором основан продукт Red Hat Virtualization.
oVirt состоит из двух основных компонент - oVirt engine и oVirt node.
oVirt engine управляет всеми хостами виртуализации, общими дисковыми ресурсами и виртуальными сетями. Может быть размещён как на отдельном сервере (standalone), так и на виртуальной машине внутри гипервизоров, которыми управляет (self-hosted engine).
oVirt node - физический сервер с RHEL, Centos, Scientific Linux с KVM гипервизором и службой VDSM (Virtual Desktop and Server Manager), которая управляет всеми ресурсами, доступными серверу (вычисления, ОЗУ, хранилище, сеть), а также управляет запуском виртуальных машин. Несколько узлов могут быть объединены в кластер.
В примерах ниже будут один oVirt engine и три oVirt node:
- oVirt engine - virt-he.example.test
- oVirt node - virt-host1.example.test, virt-host2.example.test, virt-host3.example.test
Обмен данными между oVirt engine и oVirt node осуществляется с использованием SSL сертификатов.
Автоматическое обновление сертификатов не производится, поэтому очень важно обновлять сертификаты вручную до истечения сроков их действия.
Стандартными средствами обновить сертификаты можно, если до окончания срока действия осталось менее 60 дней (для версии 4.5).
В oVirt необходимо обновлять вручную два типа сертификатов:
- сертификаты oVirt Engine - службы, которая предоставляет графический интерфейс и REST API для управления ресурсами виртуальных машин
- сертификаты для обмена данным между гипервизорами oVirt node и центром управления виртуальными машинами oVirt Engine
Определить дату окончания действия сертификатов oVirt Engine можно в свойствах сертификата сайта.
Определить дату окончания действия сертификатов гипервизоров можно с помощью openssl:
- Подключаемся через SSH на физический сервер oVirt node
- Определяем дату:
openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem
В версиях oVirt до 4.5, у всех сертификатов время жизни составляет 398 дней.
Начиная с версии 4.5, у самоподписных сертификатов для обмена данным между гипервизорами oVirt node и центром управления виртуальными машинами oVirt engine установлено время действия 5 лет.
У сертификатов, которые видят браузеры, срок действия установлен в 398 дней, их необходимо обновлять раз в год.
Процедура обновления действующих сертификатов описана в официальной документации https://www.ovirt.org/documentation/administration_guide/index.html#chap-Renewing_certificates_RHV_backup_restore
Если вы допустите истечение срока действия сертификатов, то гипервизоры и центр управления Engine перестанут взаимодействовать.
В Web-консоль невозможно будет войти, виртуальные машины продолжать работать, но с ними ничего нельзя будет сделать: нельзя изменить параметры виртуального железа, нельзя мигрировать на другой узел, после выключения ВМ её будет невозможно включить снова.
На странице web-консоли будет сообщение: "PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed"
Восстановление займёт много времени.
Процедура восстановления просроченных сертификатов описана в руководстве https://access.redhat.com/solutions/3532921. Для доступа к нему необходима действующая платная подписка Red Hat Virtualization (RHV) 4.x
Решение для восстановления без подписки я обнаружил на GitHub https://github.com/natman/ovirt_renew_certs
Автор подготовил решения для Ansible в соответствии с рекомендациями от Red hat. Если вы знакомы с Ansible и у вас много гипервизоров с просроченными сертификатами, то можно использовать решение от natman.
Решение ниже подходит для небольшого числа гипервизоров, но при условии, что центр управления Engine у вас запущен и вы можете получить к нему доступ через ssh. Предполагается, что в качестве центра управления используется HostedEngine - центр управления гипервизорами запускается внутри самого гипервизора.
Если центр управления Engine выключен и не запускается, а в журнале journalctl на гипервизоре появляются записи
libvirtd[2101]: The server certificate /etc/pki/vdsm/certs/vdsmcert.pem has expired
...
systemd[1]: Failed to start Virtualization daemon
то единственным вариантом восстановления будет изменение времени на гипервизоре на более ранее (в пределах срока действия сертификатов) и обновление сертификатов стандартным образом.
Итак, ниже будет рассмотрено три ситуации:
- Обновление сертификатов до истечения сроков действия - все сертификаты действуют, до окончания осталось менее 60 дней
- Обновление сертификатов после истечения сроков действия - у части сертификатов или у всех истек срок действия, все виртуальные машины продолжают работать, нет доступа к web-консоли, есть доступ по ssh к oVirt Engine и oVirt Node
- Обновление сертификатов после истечения сроков действия при недоступном HostedEngine - у части сертификатов или у всех истек срок действия, oVirt Engine был выключен, но есть доступ по ssh к oVirt Node
Во всех случаях необходимо обновить сертификаты на серверах oVirt Node, oVirt Engine, а так же служб ovirt-provider-ovn.service и ovsdb-server.service на сервере с oVirt Engine, т.к. для указанных служб скрипт не производит обновление сертификатов.
Обновление сертификатов до истечения сроков действия
Обновление сертификатов oVirt node
Переводим узел (гипервизор) в режим обслуживания (Managament -> Maintenance) - все машины на узле будут мигрированы, привязаные (pinned) машины будут выключены.
Выбираем Installation -> Enroll Certificate
Выводим узел из режима обслуживания
Повторяем операции для всех оставшихся узлов в кластере
Обновление сертификатов oVirt Engine
Подключаемся к физическому серверу гипервизору oVirt node через SSH
Переводим центр управления ВМ в режим обслуживания (для Self-hosted типа развёртывания)
[root@virt-host1 ~]# hosted-engine --set-maintenance --mode=global
Подключаемся к виртуальной машине с центром управления oVirt engine через SSH, запускаем настройку engine (web-консоль будет остановлена)
[root@virt-he ~]# engine-setup --offline
Отвечаем на вопросы
Если до истечения срока действия сертификата осталось менее 60 дней, то скрипт предложит обновить сертификаты:
Renew certificates? (Yes, No) [No]: Yes
Дожидаемся окончания работы скрипта.
Выводим центр управления ВМ из режима обслуживания:
[root@virt-host1 ~]# hosted-engine --set-maintenance --mode=none
Перезапускаем службу загрузки файлов на oVirt Node и oVirt Engine:
[root@virt-he ~]# systemctl restart ovirt-imageio.service
[root@virt-host1 ~]# systemctl restart ovirt-imageio.service
[root@virt-host2 ~]# systemctl restart ovirt-imageio.service
[root@virt-host3 ~]# systemctl restart ovirt-imageio.service
Утилита engine-setup не обновляет сертификаты у служб ovirt-provider-ovn.service и ovsdb-server.service, поэтому заменяем сертификаты и ключи служб на обновлённые от web-сервера, т.к. имя субъекта и subject alternative name у них совпадает, отличаются только приватные ключи:
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.key.nopass /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.key.nopass.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.key.nopass /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.key.nopass
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.p12 /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.p12.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.p12 /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.p12
[root@virt-he ~]# mv /etc/pki/ovirt-engine/certs/ovirt-provider-ovn.cer /etc/pki/ovirt-engine/certs/ovirt-provider-ovn.cer.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/certs/apache.cer /etc/pki/ovirt-engine/certs/ovirt-provider-ovn.cer
Перезапускаем службу ovirt-provider-ovn.service на oVirt Engine
[root@virt-he ~]# systemctl restart ovirt-provider-ovn.service
Версия oVirt, что я использовал, не обновляла сертификаты службы ovsdb (ovn-sdb.cer, ovn-ndb.cer). При истечении срока действия сертификатов в журналах появились ошибки. Поэтому заменяем ключи и сертификаты службы ovsdb-server.service на обновлённые от web-сервера (других обновлённых сертификатов я не обнаружил). Если ваша версия oVirt корректно обновляет сертификаты для службы ovsdb-server.service, то заменять их не нужно.
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-ndb.key.nopass /etc/pki/ovirt-engine/keys/ovn-ndb.key.nopass.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.key.nopass /etc/pki/ovirt-engine/keys/ovn-ndb.key.nopass
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-ndb.p12 /etc/pki/ovirt-engine/keys/ovn-ndb.p12.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.p12 /etc/pki/ovirt-engine/keys/ovn-ndb.p12
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-sdb.key.nopass /etc/pki/ovirt-engine/keys/ovn-sdb.key.nopass.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.key.nopass /etc/pki/ovirt-engine/keys/ovn-sdb.key.nopass
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-sdb.p12 /etc/pki/ovirt-engine/keys/ovn-sdb.p12.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.p12 /etc/pki/ovirt-engine/keys/ovn-sdb.p12
[root@virt-he ~]# mv /etc/pki/ovirt-engine/certs/ovn-ndb.cer /etc/pki/ovirt-engine/certs/ovn-ndb.cer.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/certs/apache.cer /etc/pki/ovirt-engine/certs/ovn-ndb.cer
[root@virt-he ~]# mv /etc/pki/ovirt-engine/certs/ovn-sdb.cer /etc/pki/ovirt-engine/certs/ovn-sdb.cer.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/certs/apache.cer /etc/pki/ovirt-engine/certs/ovn-sdb.cer
Служба ovsdb-server.service запускается от пользователя openvswitch, группа hugetlbfs. Чтобы она смогла прочитать файл с приватным ключом Apache, я добавляю права чтения для группы на файл.
Добавляем права на чтение ключа для службы ovsdb-server.service:
[root@virt-he keys]# chgrp hugetlbfs /etc/pki/ovirt-engine/keys/apache.key.nopass
[root@virt-he keys]# chmod g+r /etc/pki/ovirt-engine/keys/apache.key.nopass
Можно вместо создания символических ссылок скопировать сертификаты, ключи и выставить права на копии, а права на apache.key.nopass не менять, но тогда это нужно повторять каждый раз после обновления сертификатов.
Перезапускаем службу ovsdb-server.service на oVirt Engine и oVirt Node (сертификатов на Node у службы нет, но её необходимо перезапустить)
[root@virt-he ~]# systemctl restart ovsdb-server.service
[root@virt-host1 ~]# systemctl restart ovsdb-server.service
[root@virt-host2 ~]# systemctl restart ovsdb-server.service
[root@virt-host3 ~]# systemctl restart ovsdb-server.service
Подключаемся к web-консоли и проверяем дату окончания действия сертификата.
Обновление сертификатов после истечения сроков действия
Если вы допустите истечение срока действия сертификатов, то в web-консоль невозможно будет войти:
PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
Гипервизоры и центр управления Engine перестанут взаимодействовать.
Чтобы восстановить сертификаты выполняем следующие шаги.
Подключаемся через SSH на узел гипервизора oVirt node (в примере имя узла virt-host1).
Создаем запрос сертификата на основании ключа службы VDSM /etc/pki/vdsm/keys/vdsmkey.pem
[root@virt-host1 ~]# openssl req -new \
-key /etc/pki/vdsm/keys/vdsmkey.pem \
-out /tmp/test_virt-host1_vdsm.csr \
-batch \
-subj "/"
Подписываем запрос с помощью корневого сертификата oVirt engine, для этого подключаемся через SSH на ВМ с oVirt engine, копируем запрос с oVirt node (virt-host1) на oVirt engine в /tmp и выполняем команды
[root@virt-he ~]# cd /etc/pki/ovirt-engine/
[root@virt-he ~]# openssl ca -batch \
-policy policy_match \
-config openssl.conf \
-cert ca.pem \
-keyfile private/ca.pem \
-days +"365" \
-in /tmp/test_virt-host1_vdsm.csr \
-out /tmp/test_virt-host1_vdsm.cer \
-startdate `(date --utc --date "now -1 days" +"%y%m%d%H%M%SZ")` \
-subj "/O=example.test/CN=virt-host1.example.test" \
-utf8
Имя субъекта в сертификате должно быть в формате "/O=example.test/CN=virt-host1.example.test", укажите ваши значения.
Копируем новый сертификат с oVirt engine на oVirt node (virt-host1) в /tmp.
Копируем новый сертификат в каталоги служб предварительно создав копию существующих сертификатов
[root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/vdsm/certs/vdsmcert.pem.bak
[root@virt-host1 ~]# cp /tmp/test_virt-host1_vdsm.cer /etc/pki/vdsm/certs/vdsmcert.pem
[root@virt-host1 ~]# cp /etc/pki/vdsm/libvirt-spice/server-cert.pem /etc/pki/vdsm/libvirt-spice/server-cert.pem.bak
[root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/vdsm/libvirt-spice/server-cert.pem
[root@virt-host1 ~]# cp /etc/pki/libvirt/clientcert.pem /etc/pki/libvirt/clientcert.pem.bak
[root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/libvirt/clientcert.pem
Перезапускаем службы:
[root@virt-host1 ~]# systemctl restart libvirtd
[root@virt-host1 ~]# systemctl restart vdsmd
Проверяем срок действия сертификата
[root@virt-host1 ~]# openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem
Повторяем процедуру на остальных узлах с истёкшим сроком действия сертификатов.
Выполняем обновления сертификатов центра управления, как описано в "Обновление сертификатов oVirt Engine"
Заходим на web-консоль и проверяем работу кластера.
У созданных таким образом сертификатов будет отсутствовать subject alternative name, о чём будет выдано предупреждение (через несколько часов):
Certificate of host virt-host1.example.test is invalid. The certificate doesn't contain valid subject alternative name, please enroll new certificate for the host.
Поэтому после восстановления доступа к web-консоли необходимо выполнить обновление сертификатов согласно официальной документации https://www.ovirt.org/documentation/administration_guide/index.html#chap-Renewing_certificates_RHV_backup_restore
Обновление сертификатов после истечения сроков действия при недоступном HostedEngine
На практике данное решение не проверялось, но теоретически оно должно сработать.
Если центр управления Engine выключен и не запускается, а в журнале journalctl на гипервизоре появляются записи
libvirtd[2101]: The server certificate /etc/pki/vdsm/certs/vdsmcert.pem has expired
...
systemd[1]: Failed to start Virtualization daemon
Оставляем включенным один гипервизор.
Определяем время окончания действия сертификата гипервизора:
[root@virt-host1 ~]# openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem
Устанавливаем дату и время до окончания действия сертификата
[root@virt-host1 ~]# systemctl stop chronyd
[root@virt-host1 ~]# timedatectl set-time "2023-01-01 12:00:00"
Перезапускаем службы
[root@virt-host1 ~]# systemctl restart libvirtd
[root@virt-host1 ~]# systemctl restart vdsmd
Подключаемся к libvirtd через virsh и ждём когда запустится HostedEngine
[root@virt-host1 ~]# virsh -c qemu:///system?authfile=/etc/ovirt-hosted-engine/virsh_auth.conf
virsh # list --all
Id Name State
------------------------------
1 HostedEngine running
Выполняем обновление сертификатов по процедуре "Обновление сертификатов до истечения сроков действия"