作者简介

Openstack迭代很快,半年一次的更新往往会引入新的特性,及原有功能的完善。版本升级成为了一个不可避免的问题。由于openstack升级的复杂性许多公司和团队采用直接迁移至新版本云的方案,这是不失为一种可行的方案。本篇文章将重点阐述如何将K版openstck更平滑,可靠,快速的升级至Pike版本。

升级方案概述

为了保证快速平滑的升级,我们利用OpenStack控制节点和计算节点分离这一特性。整体思路上采用控制器节点替换升级,计算节点容器化升级的方式。控制节点:需要额外三台物理机部署P版本控制集群,将K版数据库导入新控制节点,并进行数据库schema升级 。计算节点:在计算节点关闭原有K版服务,通过容器启动新版本openstack服务,修改配置将计算节点指向新的控制集群。

升级方案架构图

升级目标

  • 平滑升级,业务无影响
  • 最短服务暂停时间
  • 升级失败可回退

升级步骤

1. 升级前准备

  • 停止平台层服务
echo "停止Openstack nova-api服务"
systemctl stop openstack-nova-api.service
echo "停止Openstack glance服务"
systemctl stop openstack-glance-api.service
systemctl stop openstack-glance-registry.service
echo "停止Openstack cinder服务"
systemctl stop openstack-cinder-api.service
systemctl stop openstack-cinder-scheduler.service
systemctl stop openstack-cinder-volume.service
echo "停止Openstack neutron服务"
systemctl stop neutron-server.service
systemctl stop neutron-openvswitch-agent.service
systemctl stop neutron-metadata-agent.service
systemctl stop neutron-l3-agent.service
echo "停止Openstack keystone服务"
systemctl stop httpd
  • 数据库备份
mysqldump -u keystone -pxxxx keystone > kilo-keytone-db-backup.sql
mysqldump -u glance -pxxxx glance > kilo-glance-db-backup.sql
mysqldump -u cinder -pxxxx cinder > kilo-cinder-db-backup.sql
mysqldump -u neutron -pxxxx neutron > kilo-neutron-db-backup.sql
mysqldump -u nova -pxxxx nova > kilo-nova-db-backup.sql
  • 配置文件备份
for i in keystone glance nova cinder neutron openstack-dashboard;do mkdir $i-kilo; done
for I in keystone glance nova cinder neutron openstack-dashboard;do cp -r /etc/$i/* $i-kilo;done

2. 控制节点升级

控制节点升级包括软件/程序包升级、配置升级、数据库升级三部分。

软件/程序包升级

程序包升级采用新版控制集群替换老版本的方式。需要额外三台物理机部署P版控制节点集群。

部署时请注意:- 保持Region name、数据库连接密码、网络模式(vlan/vxlan)配置与K版集群相同 若Nova、Cinder、Neutron与Ceph对接,需要下发Ceph客户端认证密钥到新的控制集群

配置升级

阅读Openstack官方配置参考确认配置文件变化,删除已经废除的配置,修改发生变化的配置。并将老版本曾做过的配置优化同步至新版本中。如:超分比、api workers、修改token为fernet模式等。

rabbit_hosts Replaced by DEFAULT;transport_url
Removal of live_migration_flag and block_migration_flag config options
identity_uri Replaced by keystone_authtoken;auth_url
... 

数据库升级

  • Keystone 升级

删除P版本keystone数据库,导入K版数据库,通过“keystone-manage db_sync”进行数据库升级。

cat > /root/upgrade/keystone.sql << EOF
DROP DATABASE IF EXISTS keystone;
CREATE DATABASE IF NOT EXISTS keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY "$PASS";
flush privileges;
EOF
mysql -uroot  < /root/upgrade/keystone.sql
mysql -uroot keystone < kilo-keytone-db-backup.sql
su -s /bin/sh -c "keystone-manage db_sync" keystone
DBversion=`keystone-manage db_version`
if [ $DBversion == 109 ];then
    echo "Keystone database upgrade successful"
fi

注意 :- 由于P版增加了Placement等服务,需要新增对应的用户、服务及Endpoint更新数据库中Endpoint的url为新集群的vip

  • Glacne 升级

删除P版本Glance数据库,导入K版数据库,通过“glance-manage db_sync”进行数据库升级。

在升级过程中我们会发现,OpenStack Glance组件已不支持从k版将数据库直接升级至P版,需要替换Glance为L版本代码,先升级数据库版本至42,再替换回p版代码,同步数据库版本至pike01。

cat > /root/upgrade/glance.sql << EOF
DROP DATABASE IF EXISTS glance;
CREATE DATABASE IF NOT EXISTS glance;
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY "$PASS";
flush privileges;
EOF
mysql -uroot  < /root/upgrade/glance.sql
mysql -uroot glance  < kilo-glance-db-backup.sql
#替换代码为L版
su -s /bin/sh -c "glance-manage db_sync" glance
#替换代码为P版
su -s /bin/sh -c "glance-manage db_sync" glance
DBversion=`glance-manage db_version`
if [ $DBversion == pike01 ];then
    echo "glance database upgrade successful"
fi
  • Cinder 升级

删除P版本Cinder数据库,导入K版数据库,通过“cinder-manage db sync”进行数据库升级。

在升级过程中我们会发现,OpenStack Cinder组件已不支持从k版将数据库直接升级至P版,从N版开始仅支持从n至n+1跨一个版本的升级。由于Cinder数据库采用顺序升级方式,数据库由db/sqlalchemy/migrate_repo/versions目录下依版本顺序排列的升级脚本进行升级,我们只需将缺失的升级script补充至对应目录下即可成功升级。

cat > /root/upgrade/cinder.sql << EOF
DROP DATABASE IF EXISTS cinder;
CREATE DATABASE IF NOT EXISTS cinder;
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY "$PASS";
flush privileges;
EOF
mysql -uroot  < /root/upgrade/cinder.sql
mysql -uroot cinder  < kilo-cinder-db-backup.sql
#更新db/sqlalchemy/migrate_repo/versions下数据库升级脚本
su -s /bin/sh -c "cinder-manage db sync" cinder
DBversion=`cinder-manage db version`
if [ $DBversion = 105 ];then
    echo "cinder database upgrade successful"
fi

注意:- 需要通过cinder-manage service remove 去除老版本的cinder-volume和cinder-scheduler服务由于替换了控制集群,需对已经创建的云硬盘通过cinder-manage volume update_host替换host名称

  • Neutron 升级

删除P版本Neutron数据库,导入K版数据库,通过“neutron-db-manage upgrade --expand”“neutron-db-manage upgrade --contract”进行数据库升级。

Neutron使用alembic进行数据库管理,采用链式升级方式,每个脚本的revison 当前指针和down_revision后继指针,形成一个有序的单链表,这样db在升级的时候就能有序的进行。

cat > /root/upgrade/neutron.sql << EOF
DROP DATABASE IF EXISTS neutron;
CREATE DATABASE IF NOT EXISTS neutron;
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY "$PASS";
flush privileges;
EOF
mysql -uroot  < /root/upgrade/neutron.sql
mysql -uroot neutron  < kilo-neutron-db-backup.sql
neutron-db-manage upgrade --expand
neutron-db-manage upgrade --contract
DBversion=`neutron-db-manage  current`
Dversion1=5c85685d616d
Dversion2=7d32f979895f
if [[ $DBversion =~ $Dversion1 && $DBversion =~ $Dversion2 ]];then
echo "neutron database upgrade successful"
fi
  • Nova 升级

删除P版本nova、nova_api、nova_cell0数据库,导入K版数据库,通过“nova-manage db sync”"nova-manage api_db sync""nova-manage db online_data_migrations"进行数据库升级。

在升级过程中我们会发现,OpenStack Nova组件已不支持从k版将数据库直接升级至P版,在P版升级脚本中要求必须先在N版执行db数据在线迁移,然而在N版升级脚本中也明确指出需要先在M版本执行db数据在线迁移。所有Nova的升级顺序为K->M->N->P。

cat > /root/upgrade/nova.sql << EOF
DROP DATABASE IF EXISTS nova;
CREATE DATABASE IF NOT EXISTS nova;
DROP DATABASE IF EXISTS nova_api;
CREATE DATABASE IF NOT EXISTS nova_api;
DROP DATABASE IF EXISTS nova_cell0;
CREATE DATABASE IF NOT EXISTS nova_cell0;
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY "$PASS";
GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY "$PASS";
flush privileges;
EOF
mysql -uroot  < /root/upgrade/nova.sql
mysql -uroot nova  < kilo-nova-db-backup.sql
#替换M版本Nova代码
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 db  online_data_migrations" nova
#替换N版本Nova代码
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 db  online_data_migrations" nova
#替换P版本Nova代码
su -s /bin/sh -c "nova-manage db sync" nova
su -s /bin/sh -c "nova-manage cell_v2 simple_cell_setup" nova
su -s /bin/sh -c "nova-manage api_db sync" nova
su -s /bin/sh -c "nova-manage db  online_data_migrations" nova
DBversion=`nova-manage db version`
if [[ $DBversion == 362 ]];then
    echo "All nova database upgrade successful"
fi

3. 计算节点升级

计算节点的升级主要包括运行在计算节点Openstack服务代码及配置的升级。另外,由于P版nova要求Qemu版本大于2.10,所以如何在不影响业务正常运行的前提下,对libvirt和qemu平滑升级,也成为一大难点。

Libvirt 和 qemu升级

Qemu升级后存量虚拟机还运行在老版本上,为了保证存量虚拟机的正常运行,我们重新编译了Qemu,改变新版本安装目录,保留了旧版本动态加载库。另外我们重编了libvirt使其可以识别到新版本Qemu。

由于OpenStack Nova-compute服务运行在容器中,Libvirt需要开启tcp远程连接

OpenStack服务升级

计算节点采用容器化升级方案,首先利用kolla build构建 openstack-nova-compute、 neutron-openvswitch-agent容器镜像,(无定制化需求可在官方镜像库拉取镜像)。私有环境无法访问外网镜像库,需要我们自己部署私有镜像库并上传镜像,保证所有计算节点可以拉取所需的容器镜像。

停止物理机上运行的老版本Openstack服务。

systemctl stop openstack-nova-compute.service
systemctl disable openstack-nova-compute.service
systemctl stop neutron-openvswitch-agent.service
systemctl disable neutron-openvswitch-agent.service

利用docker-compose启动容器,启动时挂载相关目录及新的配置文件。

nova-compute:
  container_name: "nova_compute"
  image: "$NovaDockerName"
  environment:
    - LIBGUESTFS_BACKEND=direct
    - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS
  privileged: true
  net: "host"
  volumes:
    - "/root/upgrade/docker/volume/nova-compute/:/var/lib/kolla/config_files/:ro"
    - "/lib/modules:/lib/modules:ro"
    - "/run:/run:shared"
    - "/dev:/dev"
    - "/var/log/openstack/:/var/log/kolla/:rw"
    - "iscsi_info:/etc/iscsi"
    - "/var/lib/libvirt/:/var/lib/libvirt"
    - "/var/lib/nova/:/var/lib/nova/:rw"

升级后验证

  • 升级完成后确认各组件所有服务正常运行
  • 升级验证时,对升级后的集群进行tempest测试,确保所有Api工作正常
  • 升级失败,需快速回退

回退方案

若升级失败,我们需快速回退到老版本。计算节点停止容器服务,回退qemu版本。停止新版本控制集群服务,重启老版本控制集群服务,重启计算节点老版本Openstack服务,检查服务状态,保证各组件服务正常运行。

注意:运行nova-compute服务容器时会改变/var/lib/nova权限,回退时需重置目录权限。chown -R nova:nova /var/lib/nova

文章来源于腾讯云开发者社区,点击查看原文