不要尝试在家里部署 OpenStack

前言

我买了台服务器,16年的 CPU E5-2680 V4,一共14核28线程,现在想尝试学习一大堆框架,像 openstack、cloudstack、K8S、nextcloud 等等等。但我就这一台机器,这么多服务都部署上去不得神仙打架了。所以,我打算用虚拟机来跑这些测试环境,每个环境间相互不影响,是不是挺美好的。那不如就安装一套私有云系统~

事情就是这么开始的,起初我以为安装个私有云就像安装个 vim 一样简单,sudo apt install vim就能搞定,但事情远比我想的复杂。

目标

在阅读本文前,先阐述下我安装私有云的目标。

  1. 环境隔离: 单个 linux 系统无法隔离我的操作,不适合直接用作测试机器,最好是分为宿主机+虚拟机的形式,可以作为测试环境的同时,承担一定的家庭服务器工作。
  2. 网络互通: 家里有个路由器,我需要虚拟机的的网络能够和路由器下的其他设备位于同一子网,这样方便测试,也方便路由器做端口映射工作。
  3. 稳定运行: 私有云作为基础软件,配置好了后,我大概率不会随便升级,也不会随便对宿主机进行调整,除非有部分服务更适合配置在宿主机上。
  4. 外部访问: 我家有动态的公网 IP,虽然不是强需求,但能够从外部访问也是极好的。

OpenStack

哦,对了,我打算安装的私有云是开源的 OpenStack,它是开源的云服务框架,甚至一些大公司的云平台也是基于它搭建的,架构图如下,我就不过多的介绍了。

image.png

安装历程

在工作之余,我的痛苦历程就开始了,从买服务器开始,到我把 OpenStack run 起来,花了一个多月。因为程序员的工作时间很长,只能晚上回到家折腾一会会,所以经常碰到 bug,要等到第二天、第三天才有时间去解决。

第一步,安装方法的选择

搭建 OpenStack,首先要选择合适的搭建方法,目前基本就两种方式:

  1. 手动安装: 手动安装非常复杂,参照官方文档安装。 docs.openstack.org/install-gui…
  2. Devstack 脚本安装: Devstack 基本是一键安装,运行脚本后,能够将必要服务配置好,官方说明文档 docs.openstack.org/devstack/la…

作为一个懒人,而且自己仅有一台服务器,不需要整的很夸张,构建一个 devstack all-in-one架构就可以,我果断选择了 DevStack 方式,但 DevStack 也有很深的坑,主要是文档不全。。 DevStack 方式似乎仅支持 centos 和 ubuntu,出于方便的因素,我安装的是 ubuntu 20.04 LTS 桌面版,勉强符合了要求。

第二步,运行安装脚本

参考官方安装方法,分为如下几个主要的步骤,但没有完全搞清楚 local.conf 的配置文件的含义,所以我也没办法和大家说什么样的配置文件更好。。。docs.openstack.org/devstack/la…

第一步,创建一个新账户

sudo useradd -s /bin/bash -d /opt/stack -m stack
echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack
sudo -u stack -i
复制代码

第二步,下载 devstack 的脚本。

这里实际有个问题,默认下载的是 master 的分支,不是发行的大版本,可能会出现过去未知的错误。但我下载了最近两个大版本,运行时也是会有七七八八的问题,最后还是用 master 分支应付了。

git clone https://opendev.org/openstack/devstack
cd devstack
复制代码

第三步,编辑配置文件 local.conf。最小的配置文件如下:

 [[local|localrc]]
ADMIN_PASSWORD=secret
DATABASE_PASSWORD=$ADMIN_PASSWORD
RABBIT_PASSWORD=$ADMIN_PASSWORD
SERVICE_PASSWORD=$ADMIN_PASSWORD



# 使用国内镜像
GIT_BASE=http://git.trystack.cn
NOVNC_REPO=http://git.trystack.cn/kanaka/noVNC.git
SPICE_REPO=http://git.trystack.cn/git/spice/spice-html5.git
复制代码

第四步,运行安装脚本:

./stack.sh
复制代码

如果运气够好,你可以一次安装成功。

第三步,开始解决 bug

以下所述的问题,是我在安装过程中碰到的问题及我的解决方案,具有特例,并且不一定是标准解决方案,只是能使 OpenStack 冒烟运行而已。

bug 0 安装速度极慢

这个没办法, OpenStack 服务器在国外,就是会出现很慢的问题,可以通过以下两步缓解以下:

bug 1 安装过程中提示有个 python 库冲突

原始日志已经被我清理掉了,这里只能复述一下,大概场景是莫名报错,网上翻一翻,是和一个 python 包有关,那个包貌似不是通过 pip 安装的,我到对应的路径清除了文件就通过了。

bug 2 ERROR Socket /var/run/openvswitch/ovnnb_db.sock not found

安装过程中报错,关键词是上述,我搜到了 stack overflow 上有人碰到过,需要修改 devstack 中的一行配置代码。

在修改代码前,先执行 ./unstack.sh清理一下,防止重复安装时出现 bug。

文件位于/opt/stack/devstack/lib/ovn_agent,修改文件约116行处,将OVS_RUNDIR=$OVS_PREFIX/var/run/openvswitch 替换为OVS_RUNDIR=$OVS_PREFIX/var/run/ovn

参考链接:stackoverflow.com/questions/6…

bug 3 安装后,重启后 devstack 无法运行

经过排查,我发现服务太多,有些服务启动失败,包括:etcd、cinder 等杂七杂八的。对应的服务手动重启一下就好了,cinder 是因为牵扯的 lvm 硬盘没有挂载,需要先将虚拟硬盘挂载,在 shell 中执行如下命令:

sudo losetup -f --show /opt/stack/data/stack-volumes-lvmdriver-1-backing-file
# 理论上只要重启没启动好的几个服务就可以了,实际操作上,我选择全部重启。。。
sudo systemctl restart "devstack@*"
复制代码

Bug 4 创建实例碰到 no valid host was found

这个问题是我碰到的第二吐血的问题,我也尝试解了几天,但解决起来还算顺利。

首先,搜索关键词,知道需要先看服务是否起来openstack compute service list;然后,在看是否发现了相关计算节点:openstack hypervisor list;此时,我发现 openstack 并没有发现计算节点,就得进一步搜索。在 blog.csdn.net/avatar_2009… 得知需要手动触发节点发现:nova-manage cell_v2 discover_hosts --verbose,但一直报另一个错误:

stack@a-PowerEdge-R730:~$ nova-manage cell_v2 discover_hosts --verbose
/usr/lib/python3/dist-packages/secretstorage/dhcrypto.py:15: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
  from cryptography.utils import int_from_bytes
/usr/lib/python3/dist-packages/secretstorage/util.py:19: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
  from cryptography.utils import int_from_bytes
Found 2 cell mappings.
Skipping cell0 since it does not contain hosts.
Getting computes from cell 'cell1': 6812b249-6941-47e6-a3c7-8ab2d809543e
Found 0 unmapped computes in cell: 6812b249-6941-47e6-a3c7-8ab2d809543e
复制代码

devstack 上安装的程序不是很好看错误日志,便先通过 systemctl status "devstack@n-*" 判断是哪个程序发生了错误,最终定位到是 "devstack@n-cpu"

image.png

通过 sudo journalctl -u devstack@n-cpu 查看具体的错误日志,发现是我自己之前安装的虚拟机。。。root 以外的用户没有读写权限,虽然我也不知道为什么 openstack 需要这个文件的读写权限,但是我给加上了之后就可以正常运行了。这说明了,最好在完全干净的环境下配置 devstack。

image.png

Bug 5 虚拟机分配不到 IP

这个问题是我碰到最恶心的问题,一直花了几个星期才算冒烟跑通。

第一次诊断:是否是 neutron 配置错误

网络不通,首先怀疑是网络服务配置不正确导致的,经过自己的摸索,发现这部分超出了自己的知识范围,于是看书、上网搜索,最后有了一点点浅薄的理解。

我的需求是虚拟机与宿主机位于同一子网,不需要 VLAN、VXLAN 等花里胡哨的配置,所以我的配置应该很简单。参考书介绍了 linux bridge 和 open vswitch 两种方案,于是我开始尝试调整配置文件重新安装。遗憾的是,我尝试了调整 local.conf 很多次,只要选择 linux bridge 和 open vswitch,连完整的部署都很难做到。。。

经过我在网络上的进一步调研,我发现 OpenStack 的网络虚拟化主要分为三种方案:

  • Linux Bridge
  • Open vSwitch
  • Open Virtual Network

其中 OVN 是 devstack 中默认配置的虚拟化方案,所以另外两种无法成功部署,我只能怀疑是 devstack 的脚本不正确,故放弃当前思路。

第二次诊断:考虑如何使用 OVN 配置

目前我能配置配置 openstack 成功的只有基于 ovn 的 neutron,可能是网络的资料不够新,ovn 和 ovs 不是同样的概念,并且网络上 OVN 的信息极少,仅有官网少量提及。docs.ovn.org/en/latest/i…

在探索中,我发现安装好 OVN 后,我的网卡没有被挂载到 OVN 的 bridge 上。按照 Flat 网络模型,我的网卡需要挂载到 br-ex 网桥,虚拟机会被挂载到 br-int 网桥,两个网桥会有 peer port 联通。

image.png

将网卡挂载到 br-ex 网桥,该操作可能导致断网,需要在服务器上直接操作,如果配置后无法访问网络,请及时撤销操作:

首先,禁用网口的 dhcp 功能,各系统的操作不同,ubuntu 20.04 使用 netplan 进行管理,参考官网 example:netplan.io/examples/#c…

我的配置文件如下/etc/netplan/01-network-manager-all.yaml,执行sudo netplan apply 使配置文件生效,生效后可能会断网。

# Let NetworkManager manage all devices on this system                                         
network:                                                                                       
  version: 2                                                                                   
  renderer: NetworkManager                                                                     
  ethernets:                                                                                   
    eno1:                                                                                       
      dhcp4: no                                                                                 
      dhcp6: no                                                                                             
复制代码

然后,将 ip 配置到 bridge,执行完成后,网络应当能够恢复连接。

sudo ip addr flush dev eno1
sudo ip addr add 192.168.128.5/24 dev br-ex
sudo ip link set br-ex up
复制代码

但,虚拟机依旧没办法获得 ip,但此时,我给虚拟机配置了静态 IP,发现虚拟机已经可以联网,网络整体而言是通的,虚拟机内部可以访问外部,但外部还不能防伪虚拟机内部。

第三次诊断:安全组好像也会影响到虚拟机连通性

默认情况下,DevStack 安全组会丢弃传入流量,但为了以合理的方式测试网络,我们需要启用它。您只需要实际编辑一个特定的安全组,但 DevStack 会创建多个,并且很难确定哪一个是重要的,因为它们都被命名为“默认”。因此,以下添加了允许 SSH 和 ICMP 流量****进入每个 安全组的规则:docs.ovn.org/en/latest/t…

for group in $(openstack security group list -f value -c ID); do \
openstack security group rule create --ingress --ethertype IPv4 --dst-port 22 --protocol tcp $group; \
openstack security group rule create --ingress --ethertype IPv4 --protocol ICMP $group; \
done
复制代码

image.png

Bug 6 上传镜像后,一直显示排队中

我查看了服务的日志,发现是因为 devstack 给配置的默认 limit 太小了,glance 服务不允许继续。

docs.openstack.org/glance/late…

openstack --os-cloud devstack-system-admin registered limit update \
  --service glance --default-limit 5000 --region RegionOne image_size_total

openstack --os-cloud devstack-system-admin registered limit create \
        --service glance --default-limit 1000000 \
        --region RegionOne image_size_total
复制代码

按照文档应该这么设置,但是,我的没能生效,所以我直接在 /etc/glance/glance-api.conf中,把 use_keystone_limits 配置为了 False,效果立竿见影。

[DEFAULT]                                                                                       
use_keystone_limits = False                                                                     
worker_self_reference_url = http://127.0.0.1:60999                                             
logging_exception_prefix = ERROR %(name)s %(instance)s                                         
logging_default_format_string = %(color)s%(levelname)s %(name)s [-%(color)s] %(instance)s%(color)s%(message)s                                                                             
logging_context_format_string = %(color)s%(levelname)s %(name)s [%(global_request_id)s %(request_id)s %(project_name)s %(user_name)s%(color)s] %(instance)s%(color)s%(message)s         
logging_debug_format_suffix = {{(pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d}}       
public_endpoint = http://192.168.31.11/image                                                   
复制代码

Bug 7:ubuntu、debian 镜像无法登陆

从网上找了些云服务专用的系统镜像,像 ubuntu、debian 等,结果,安装上虚拟机后无法登陆,必须配置 key 才可以登录,我参考下面的一些文章,修改了镜像文件,给 root 账号配置了默认密码。

www.cxyzjd.com/article/lil… www.chenshake.com/openstack-m… blog.csdn.net/hehj3699869…

Bug 8:创建虚拟机时,报创建 volume 失败

在日志文件中,发现 cinder 服务的可用空间不够了。当时我就纳闷了,我买了个 8T 的硬盘,那么大的硬盘空间那去了呢?

11月 30 21:18:18 a-PowerEdge-R730 cinder-scheduler[25077]: DEBUG cinder.scheduler.host_manager [None req-22e02855-3c36-4691-8c1f-efe11eb2f19f admin None] Updating capabilities for a-PowerEdge-R730@lvmdriver-1  {'pool_name': 'lvmdriver-1', 'total_capacity_gb': 28.5, 'free_capacity_gb': 1.82, 'reserved_percentage': 0, 'location_info': 'LVMVolumeDriver:a-PowerEdge-R730:stack-volumes-lvmdriver-1:thin:0' 'QoS_support': False, 'provisioned_capacity_gb': 212.0, 'max_over_subscription_ratio': '20.0', 'thin_provisioning_support': True, 'thick_provisioning_support': False, 'total_volumes': 5, 'filter_function':  None, 'goodness_function': None, 'multiattach': True, 'backend_state': 'up', 'allocated_capacity_gb': 212, 'cacheable': True, 'volume_backend_name': 'lvmdriver-1', 'storage_protocol': 'iSCSI', 'vendor_name':'Open Source', 'driver_version': '3.0.0', 'timestamp': datetime.datetime(2021, 11, 30, 13, 17, 27, 581924)} {{(pid=25077) update_from_volume_capability /disk1/stack/cinder/cinder/scheduler/host_manager.py:392}} 
复制代码

然后,又是一番上下求索,发现 devstack 创建了个文件,将文件挂载到了/dev/loopxx然后将这个回环文件创建了个 vg 当做虚拟硬盘使用,但默认配置文件中只给创建了 30G。

# 30Gb default volume backing file size
VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-30G}
复制代码

我立马想到了四种解决方案,但奈何系统已经搞得差不多了,就先测试了新建一个 lvm backend,然后将旧的 lvm 硬盘删除,新建了个更大空间的 lvm。

  1. unstack.sh 重新修改 stackrc 配置文件,重新执行 stack.sh,创建 私有云;
  2. 删除旧的 lvm 磁盘,创建一个同名的,更大空间的;
  3. 新建一个 loop 文件,合并容量到 stack-volumes-lvmdriver-1
  4. 新建一个 lvm backend,后续虚拟机使用新的 backend,www.cnblogs.com/sammyliu/p/…

涉及到了如下必要命令。

# 查看虚拟硬盘
stack@a-PowerEdge-R730:~/data$ sudo lvs -a                                                     

# sudo lsblk 用来查看 loop
 ➜  ~ lsblk

#      truncate 创建指定大小的文件
truncate -s 100G stack-volumes-lvmdriver-1-blocking-file

# 挂载 loop 文件
sudo losetup -f --show --direct-io=on stack-volumes-lvmdriver-1-blocking-file
// 返回 /dev/loopxx

# 创建 vg
sudo vgcreate stack-volumes-lvmdriver-1 /dev/loop13

# 使 lvm 生效
sudo vgchange -ay stack-volumes-lvmdriver-1

# 取消 vg
sudo vgremove stack-volumes-lvmdriver-1 

# 卸载 loop 文件
sudo losetup -d /dev/loop13
sudo losetup -d /dev/loop14
复制代码

Bug 9 外网无法访问

我在路由器上配置了端口映射,但外部打不开 OpenStack 的网址。上网一搜,需要配置 ServerAlias,参考别人的文档简单的配置一下就好了。 花生壳内网穿透访问OpenStack的Dashboard界面

Bug 10 外网访问不了 noVNC

发现 OpenStack 中的 vnc 是通过内网地址暴露出去的,是另一个端口 6080,需要将该端口一并暴露出去才行。

解 bug 过程中的一些 tips

Tip 0 每次想修改 local.conf 前先卸载

# 停止 devstack 的服务,从操作系统中卸载掉,但 mysql 等一些基础服务还在
./unstack.sh

# 卸载的更彻底,连 mysql 都一并卸载了
./clean.sh

# 有时候有些文件可能清除不干净,手动执行
sudo rm -rf /etc/libvirt/qemu/inst*
sudo virsh list | grep inst | awk '{print $1}'| xargs -n1 virsh destroy
复制代码

Tip 1 私有云是虚拟化技术的组合体,没那么简单

私有云涉及到了 cpu 的虚拟化、内存的虚拟化、网络的虚拟化等等,并可以有对象存储、容器编排等更多的内容,超级复杂,需要很多的知识积累。

能不亲自动手配置私有云,就别动手配置,其他公司配置云服务,都是有团队的,单兵作战,累死自己。

尾巴

这里是尾巴,经历了一个多月的调试,我的 OpenStack 已经基本能够运行了,虽然还在冒烟,后面出了问题在继续解 bug 吧。

猜你喜欢

转载自juejin.im/post/7036722660885151751