使用 devstack 部署 openstack zed

前言

最近我老师投资了一个教育平台的项目,我需要负责具体的实施,其中包含了线上实训模块,简单来说就是为每个学生开设一台云电脑来完成实训任务并收集成果来评分。这就要求平台具有开设“云电脑”的能力,也就是说需要有一个云计算集群作为支撑。考虑到这个项目后续大概率会封装成可私有化部署的产品卖给各个学校,所以这个云计算集群也得能本地化部署才行,不能依赖阿里云这样的公有云服务,于是我只能闷头研究下和我的专业相差略远的 openstack 了。

老实说,像 devstack 这种一键安装脚本是不需要专门写一篇文章来记录如何使用的,但奈何天朝的网络环境各种的墙,导致这个脚本我跑了好几天,那种每走一步就碰见一个报错的痛苦可能没人会懂。

硬件准备

一台空的 PC、一台 x86 服务器或者一台 VMware 虚拟机都可以。

如果是VMware虚拟机的话记得开启虚拟机处理器的“虚拟化Intel VT-x/EPT 或 AMD-V/RVI(V)”功能。

操作系统

我使用的是 Ubuntu 22.04,这也是截至目前 zed 版官方推荐的操作系统。

添加 opentsack 用户

需要创建一个专门的账号来安装和运行 openstak 服务

sudo useradd -s /bin/bash -d /opt/stack -m stack
sudo chmod +x /opt/stack
echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack
sudo -u stack -i # 切换到刚创建的用户身份上以执行后续操作Code language: PHP (php)

前期准备

网上一些教程会让换掉 Ubuntu 的软件源和 Python 的 PIP 源,但是我并不建议这么搞。第一是官方源目前在国内访问速度非常不错,第二是第三方源会出现各种莫名其妙的错误,比如说之前用华为的 PIP 源就会报各种依赖错误。

需要真正解决的网络访问问题主要集中在以下两块:

  1. 从 GitHub 拉取仓库
  2. 使用 wget 下载 GitHub 及其他被墙资源

我尝试过很多解决方案,这里就不罗列了,只说一下最根本的方案:为 git 和 wget 分别配置代理。

我采用的是在 PC 机上先使用 ShadowsocksR 配置 SSR 代理(这一块不会配的就百度搜吧),然后在 ShadowsocksR 的“选项设置”中勾选“允许来自局域网的连接”。

之后在服务器上执行以下四条命令让 git 和 wget 命令可以使用 pc 机上配置的代理服务:

git config --global http.proxy 'socks5://192.168.0.197:1080' 
git config --global https.proxy 'socks5//192.168.0.197:1080'
export http_proxy=http://192.168.0.197:1080
export https_proxy=http://192.168.0.197:1080Code language: JavaScript (javascript)

之后分别进行测试:

wget https://google.com
git clone https://github.com/litepress/wp-china-yesCode language: PHP (php)

这两条命令必须都成功执行才行,否则 devstack 的执行 100% 会报错的,所以说如果测试不通过就回去研究为什么出错吧。

运行 devstack

解决网络问题后事情就很简单了,这里我直接把 openstack 官方的文档大段贴上来。

下载 devstack

git clone https://opendev.org/openstack/devstack
cd devstack
git checkout stable/zed  # 切换为 zed 版Code language: PHP (php)

创建配置文件

在 devstack 目录中创建名为 local.conf 的文件,内容为:

[[local|localrc]]
ADMIN_PASSWORD=管理页面的 admin 密码
DATABASE_PASSWORD=$ADMIN_PASSWORD
RABBIT_PASSWORD=$ADMIN_PASSWORD
SERVICE_PASSWORD=$ADMIN_PASSWORD

# 这里使将来 openstack 的虚拟路由器桥接服务器物理网卡,这样安装后云服务器就可以上网了,并且只需要物理机有一个网卡即可。
PUBLIC_INTERFACE=ens6f0 # 要桥接到的物理机网卡
HOST_IP=192.168.0.242 # 物理的 IP
FLOATING_RANGE=192.168.0.0/24 # 物理机网卡的网段
PUBLIC_NETWORK_GATEWAY=192.168.0.254 # 物理机网卡的网关
Q_FLOATING_ALLOCATION_POOL=start=192.168.0.100,end=192.168.0.200 # 要为云主机分配的地址范围(之所以不全分配是因为网络里还会存在其他设备,为了防止冲突才专门规划出一部分给云主机用)
Code language: PHP (php)

开始安装

./stack.sh

安装完成

安装脚本应当一次性执行成功,成功后会在终端输出类似如下内容:

This is your host IP address: 192.168.0.242
This is your host IPv6 address: ::1
Horizon is now available at http://192.168.0.242/dashboard
Keystone is serving at http://192.168.0.242/identity/
The default users are: admin and demo
The password: 你设置的管理页面的 admin 密码

Services are running under systemd unit files.
For more information see: 
https://docs.openstack.org/devstack/latest/systemd.html

DevStack Version: zed
Change: 211cc4c036b6cb13598b87e6e3bbc3c74538a902 Pin tox<4.0.0 for <=stable/zed branch testing 2022-12-09 02:54:44 +0000
OS Version: Ubuntu 22.04 jammy

2022-12-20 20:28:27.268 | stack.sh completed in 1738 seconds.
Code language: JavaScript (javascript)

切换存储盘

很多服务器系统盘是和磁盘阵列在操作系统内是两块设备,openstack 默认会将系统盘作为存储盘。

想切换存储盘首先需要在新磁盘上创建 LVM 卷组,参见:CentOS 6中创建及管理LVM逻辑卷 – 坏蛋的博客 (ibadboy.net)

之后编辑文件:/etc/cinder/cinder.conf 文件(openstack 卷服务的配置文件)。

将存储后端 lvmdriver-1(默认存储后端)的卷组修改为刚创建的新卷组即可。修改完类似如下:

[lvmdriver-1]
image_volume_cache_enabled = True
volume_clear = zero
lvm_type = auto
target_prefix = iqn.2010-10.org.openstack:
target_port = 3260
target_protocol = iscsi
target_helper = lioadm
volume_group = data # data 就是新创建的卷组,只需要改这一行即可。
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = lvmdriver-1

Code language: PHP (php)

之后重启服务器即可生效。

常见问题

物理机重启后无法创建云服务器,一直显示“正在调度中”

该问题是由于 nova(openstack 中负责计算的组件)的部分服务没设置开机自启动导致的。执行以下命令即可:

sudo systemctl start devstack@n-sch.service
sudo systemctl start devstack@n-cpu.service
sudo systemctl enable devstack@n-sch.service
sudo systemctl enable devstack@n-cpu.serviceCode language: CSS (css)

物理机重启后无法连接网络(仅能 ping 通自己,无法 ping 通网关)

这是由于 devstack 在安装时会创建一个桥接网卡 br-ex,但该网卡的 IP 配置信息并未写到网卡配置文件中,所以重启后 IP 丢失,自然网就不通了。

这里以 ubuntu 22.04 为例,编辑文件:/etc/netplan/00-installer-config.yaml,最后效果如下:

# This is the network config written by 'subiquity'
network:
  ethernets:
    eno1:
      dhcp4: false
    eno2:
      dhcp4: false
    ens6f0: # 被桥接的物理网卡,一定要在配置文件中写出来,否则会被禁用。
      dhcp4: false
    ens6f1:
      dhcp4: false
    br-ex:  # 这里是 devstack 创建的桥接网卡,按正常网卡那样配置地址信息即可。
      addresses:
      - 192.168.0.242/24
      routes:
      - to: default
        via: 192.168.0.254
      nameservers:
        addresses:
        - 114.114.114.114
        search: []
    
  version: 2
Code language: PHP (php)

应用网络更改:

sudo netplan apply

现在可以上网了。