简介:这份文档面向云计算初学者与运维人员,系统讲解如何从零搭建一套 OpenStack 私有云平台,解决环境准备、组件安装与网络配置等实操问题。资源包共 1 个 doc 文件,约 119KB,以图文步骤形式组织内容,便于按目录顺序对照操作。文档从修改主机名、主机名与地址映射、清除防火墙规则、设置 SELinux 为 permissive 等基础准备讲起,逐步推进到上传镜像、创建目录、挂载镜像文件、配置 YUM 源、安装 iaas-xiandian 软件包与 OpenStack 组件,并覆盖创建镜像、磁盘、外网、内网及子网、外网与内网连接、创建虚拟机并绑定浮动 IP、创建卷类型与挂载云硬盘等完整流程。目前已有 618 人学习,适合需要快速掌握私有云部署步骤、对照实验环境查漏补缺的读者参考。
1. OpenStack 私有云搭建:从一台裸机到能跑虚拟机的控制面
手里有一批闲置服务器,领导让你搭一套内部私有云,要求能创建虚拟机、能分配 IP、能挂载卷,最好还能有个 Web 界面让开发自助申请。你搜到 OpenStack,打开官方文档发现组件有十几个,光安装方式就有 Packstack、DevStack、Kolla-Ansible、手动部署好几条路,瞬间不知道从哪下手。这篇笔记就按一线落地的顺序,把 OpenStack 私有云搭建这件事拆开讲清楚:选哪条路、每步做什么、参数怎么改、哪里最容易翻车。适合有 Linux 基础、想在自己机房或几台物理机上跑通一套可用私有云的运维和开发。读完你应该能独立完成一套最小可用集群的部署,并知道后续扩容和排障往哪看。
2. 部署路线怎么选:Kolla-Ansible 和手动装到底差在哪
OpenStack 私有云搭建的第一道坎不是技术,是路线选择。选错了,后面每一步都在还债。目前主流就三条路:DevStack 适合开发调试,装完重启就散架;手动逐个组件装适合学习原理,但生产环境没人这么干;Kolla-Ansible 用容器化方式编排所有服务,是目前私有云落地最稳的常见做法。下面把选型逻辑和 Kolla-Ansible 的落地步骤讲透。
2.1 三条路线的适用边界与选型理由
DevStack 本质是一个 shell 脚本集合,从 git 拉最新代码直接跑在宿主机上,装完能体验功能,但它默认用最新开发分支,组件间版本兼容性靠运气,重启后服务状态经常不一致。它解决的是“我想快速看一眼 OpenStack 长什么样”,不是“我要一套能长期跑的云”。
手动部署(跟着官方 Install Guide 走)会逼你理解每个组件的配置文件和数据库关系,比如 Keystone 的 endpoint 怎么注册、Nova 怎么通过 RabbitMQ 和 Neutron 通信。学原理值得走一遍,但一套最小集群手动装下来至少两三天,且升级时配置文件要逐个比对,维护成本极高。
Kolla-Ansible 的思路是把每个 OpenStack 服务打成 Docker 镜像,用 Ansible 编排容器在哪些节点、用什么配置启动。它的优势是版本锁定清晰、升级路径明确、配置集中在 globals.yml 一个文件里。代价是需要理解容器网络和 Ansible 的 inventory 结构。对于“搭一套能用的私有云”这个目标,Kolla-Ansible 是投入产出比最高的选择,也是目前社区和商业落地里最常见的方案。
选型时还要看硬件规模。三节点以下(1 控制 + 2 计算)用 Kolla-Ansible 的 all-in-one 或最小多节点都行;超过十节点就要考虑 Ceph 做统一存储、Neutron 用 OVS 还是 Linuxbridge、是否上 DPDK。这些决策在 globals.yml 里都有对应开关,后面会讲。
2.2 基础环境准备:主机名、时间同步、内核参数
Kolla-Ansible 对基础环境有硬性要求,这些没做好后面会出各种玄学问题。假设你有三台机器:node1(控制+网络)、node2(计算)、node3(计算),每台至少 8 核 16G、两块网卡(一块管理、一块业务)。
第一步,所有节点设置主机名并写 hosts:
# 在每台机器上执行,以 node1 为例 hostnamectl set-hostname node1 # 三台机器的 /etc/hosts 都要包含以下内容 cat >> /etc/hosts <<EOF 192.168.10.11 node1 192.168.10.12 node2 192.168.10.13 node3 EOF主机名必须能互相解析,Kolla-Ansible 的 Ansible 连接和 API endpoint 注册都依赖这个。主机名带下划线或大写会导致 RabbitMQ 启动失败,这是血泪经验。
第二步,时间同步。OpenStack 各组件用消息队列通信,时间偏差超过 5 秒会导致 token 校验失败、服务注册异常:
# 所有节点安装 chrony 并指向同一时间源 yum install -y chrony # 控制节点作为内网时间源,计算节点指向控制节点 # node1 的 /etc/chrony.conf 保留默认外部源并加 allow 192.168.10.0/24 # node2、node3 的 /etc/chrony.conf 改为 server node1 iburst systemctl enable --now chronyd chronyc sources -v # 确认同步状态,^* 表示已同步第三步,内核参数和防火墙。Kolla-Ansible 会自己管理 iptables,所以部署前要停掉 firewalld 和 NetworkManager 对网桥的干扰:
systemctl disable --now firewalld systemctl disable --now NetworkManager systemctl enable --now network # 加载 br_netfilter 并开启网桥转发 modprobe br_netfilter cat > /etc/sysctl.d/kolla.conf <<EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl -p /etc/sysctl.d/kolla.confnet.ipv4.ip_forward不开,虚拟机出不了网;bridge-nf-call-iptables不开,Neutron 的安全组规则不生效。这两个参数是私有云网络能不能通的关键。
2.3 安装 Kolla-Ansible 并生成 inventory
控制节点上装 Kolla-Ansible。用虚拟环境隔离,避免污染系统 Python:
yum install -y python3-devel python3-libs libffi-devel gcc openssl-devel git python3 -m venv /opt/kolla-venv source /opt/kolla-venv/bin/activate pip install -U pip # 安装与目标 OpenStack 版本对应的 kolla-ansible,这里以常见稳定版为例 pip install kolla-ansible==15.4.1 # 复制配置模板 mkdir -p /etc/kolla cp -r /opt/kolla-venv/share/kolla-ansible/etc_examples/kolla/* /etc/kolla/ cp /opt/kolla-venv/share/kolla-ansible/ansible/inventory/multinode /etc/kolla/inventorykolla-ansible版本要和 OpenStack 版本对应,装错版本会在 prechecks 阶段报镜像 tag 找不到。/etc/kolla/inventory是 Ansible 的主机清单,需要按你的节点角色编辑:
[control] node1 [network] node1 [compute] node2 node3 [monitoring] node1 [storage] node1控制节点同时承担 network 和 storage 角色在最小集群里很常见,但生产环境建议 network 独立,因为 Neutron 的 L3 agent 和 DHCP agent 对网络延迟敏感。编辑完用ansible -i /etc/kolla/inventory all -m ping验证连通性,全部返回 pong 才能继续。
2.4 globals.yml 里必须改的六个参数
/etc/kolla/globals.yml是整套私有云的配置中心,几百个参数里真正必须改的就几个:
# 管理网网卡,用于 API 通信和 Ansible 连接 api_interface: "eth0" # 业务网网卡,虚拟机流量走这里 neutron_external_interface: "eth1" # 虚拟化类型,物理机用 kvm,嵌套虚拟机里用 qemu nova_compute_virt_type: "kvm" # 内部 VIP,Keepalived 用,必须是一个未占用的管理网 IP kolla_internal_vip_address: "192.168.10.100" # 网络类型,flat 最简单,vxlan 支持多租户隔离 neutron_plugin_agent: "openvswitch" # 启用哪些服务,最小集如下 enable_cinder: "yes" enable_haproxy: "yes" enable_neutron_provider_networks: "yes"api_interface和neutron_external_interface不能是同一块网卡,否则虚拟机流量和 API 流量互相干扰。nova_compute_virt_type如果在 VMware 里嵌套部署,必须改成 qemu,否则 Nova 启动虚拟机会报 KVM 不可用。kolla_internal_vip_address要提前 ping 一下确认没人用,VIP 冲突会导致 HAProxy 起不来,整个 API 入口就断了。
改完执行密码生成和预检查:
kolla-genpwd kolla-ansible -i /etc/kolla/inventory precheckskolla-genpwd会把所有服务的密码写进/etc/kolla/passwords.yml,这个文件要备份好,丢了就得重装。prechecks 会检查端口占用、磁盘空间、Docker 版本、Python 依赖,报错就按提示修,不要跳过。
2.5 执行部署与验证控制面
预检查通过后正式部署:
kolla-ansible -i /etc/kolla/inventory deploy这一步会拉取镜像、启动容器、初始化数据库、注册 endpoint,三节点大概 15 到 30 分钟。中途失败不要慌,看/var/log/kolla/下对应服务的日志,常见的是镜像拉取超时或某个容器反复重启。
部署完成后生成 admin 凭证并验证:
kolla-ansible -i /etc/kolla/inventory post-deploy source /etc/kolla/admin-openrc.sh openstack token issue # 能返回 token 说明 Keystone 正常 openstack compute service list # 能看到 nova-compute 的 state 为 up openstack network agent list # 能看到 L3、DHCP、OVS agent 为 aliveopenstack compute service list里 nova-compute 的 State 必须是 up,如果是 down 就去计算节点看/var/log/kolla/nova/nova-compute.log,多半是消息队列连不上或虚拟化不支持。network agent list里所有 agent 的 Alive 为 True 才算网络就绪。到这一步,控制面就搭好了,可以创建虚拟机了。
3. 用 OpenStack 命令行走通第一台虚拟机
控制面起来只是开始,真正验证私有云可用的是从镜像上传到虚拟机拿到 IP 能 ping 通的完整链路。这一章按顺序走一遍,每个命令都解释参数,新手照着敲就能复现。
3.1 上传镜像与创建 flavor
先准备一个 qcow2 格式的镜像,比如 CirrOS 或 Ubuntu cloud image。OpenStack 的 Glance 支持 qcow2、raw、vmdk 等格式,qcow2 最省空间:
# 下载一个测试用的小镜像 wget http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img # 上传到 Glance,--disk-format 指定格式,--container-format 裸镜像用 bare openstack image create "cirros" \ --file cirros-0.6.2-x86_64-disk.img \ --disk-format qcow2 \ --container-format bare \ --public openstack image list # 确认状态为 active--public表示所有租户可见,私有镜像不加这个参数。镜像状态从 queued 变 active 需要几秒到几十秒,如果一直卡在 saving 就看 glance-api 日志,多半是存储后端权限问题。
Flavor 定义虚拟机的 CPU、内存、磁盘规格:
openstack flavor create --vcpus 1 --ram 512 --disk 5 m1.tiny openstack flavor create --vcpus 2 --ram 2048 --disk 20 m1.small openstack flavor list--disk 5是根磁盘大小,单位 GB。注意这个磁盘是从镜像克隆出来的,实际占用取决于镜像大小和后端存储类型(Ceph 是精简置备,本地盘是厚置备)。
3.2 创建网络、子网和路由
没有网络虚拟机起不来。最小网络拓扑是:一个租户内网 + 一个外部网络 + 一个路由把两者连通。
# 创建外部网络,对应物理业务网卡所在的网段 openstack network create --external --provider-physical-network physnet1 \ --provider-network-type flat public openstack subnet create --network public --subnet-range 192.168.20.0/24 \ --gateway 192.168.20.1 --no-dhcp public-subnet # 创建租户内网,用 vxlan 隔离 openstack network create private openstack subnet create --network private --subnet-range 10.0.0.0/24 \ --gateway 10.0.0.1 --dns-nameserver 114.114.114.114 private-subnet # 创建路由并连接内外网 openstack router create router1 openstack router set router1 --external-gateway public openstack router add subnet router1 private-subnet--provider-physical-network physnet1要和 globals.yml 里neutron_bridge_name或 OVS 的 bridge mapping 对应,对不上虚拟机就出不了外网。--no-dhcp是因为外部网络通常由物理网关提供 DHCP,OpenStack 不再插手。租户内网的--dns-nameserver建议改成你环境里可用的 DNS,否则虚拟机解析不了域名。
3.3 安全组、密钥对与启动虚拟机
启动前要放行 SSH 和 ICMP,否则虚拟机起来了也连不上:
openstack security group rule create --proto icmp default openstack security group rule create --proto tcp --dst-port 22 default # 生成密钥对,私钥保存到本地 openstack keypair create mykey > mykey.pem chmod 600 mykey.pem # 启动虚拟机 openstack server create --flavor m1.tiny --image cirros \ --nic net-id=$(openstack network show private -f value -c id) \ --security-group default --key-name mykey test-vm openstack server list # 等待状态变为 ACTIVE--nic net-id指定虚拟机接入哪个网络,多网卡就写多个--nic。openstack server list里能看到虚拟机的 IP,但这个 IP 是租户内网的 10.0.0.x,要从外部访问需要绑定浮动 IP:
openstack floating ip create public openstack floating ip list # 拿到浮动 IP 地址 openstack server add floating ip test-vm <浮动IP> # 从外部网络能 ping 通后 ssh 登录 ssh -i mykey.pem cirros@<浮动IP>浮动 IP 是从外部网络的 subnet 里分配的,如果openstack floating ip create报没有可用 IP,检查外部 subnet 的 allocation pool 是否耗尽。登录进去后ip a能看到内网 IP,ping 114.114.114.114能通说明 NAT 和路由都正常。
3.4 挂载卷与快照验证存储链路
Cinder 提供块存储,虚拟机可以挂载额外卷:
openstack volume create --size 2>openstack server image create --name test-vm-snapshot test-vm openstack image list # 能看到新快照快照本质是把虚拟机的根磁盘导出成镜像,对运行中的虚拟机做快照需要 qemu-guest-agent 配合,否则可能不一致。生产环境建议先关机再快照,或者用 Cinder 的卷快照。
4. 私有云搭建避坑:五个让部署翻车的典型问题
Kolla-Ansible 虽然稳,但环境差异会导致各种意外。这一章记录五个我实际踩过的坑,按现象、原因、解决三段写,遇到类似报错可以对照排查。
4.1 prechecks 报 Docker 版本不兼容
现象:执行kolla-ansible prechecks时提示Docker version is not supported,部署直接中断。
原因:Kolla-Ansible 对 Docker 版本有最低要求,CentOS 默认源里的 Docker 往往太旧,或者装的是 podman-docker 这个兼容层,它不提供完整的 Docker API。
解决:卸载旧版本,用 Docker 官方源装指定版本。先yum remove docker docker-client podman-docker,然后添加官方仓库安装。装完docker info确认 Server Version 满足要求,并且systemctl enable --now docker。注意不要用 podman 替代,Kolla-Ansible 的很多操作依赖 Docker SDK,podman 的 socket 兼容性不够。
4.2 部署卡在 pull image 或镜像拉取超时
现象:deploy阶段长时间停在TASK [common : Pulling image],最后报 timeout。
原因:默认镜像仓库在境外,网络不稳定时拉取大镜像(如 nova-compute 超过 1G)容易超时。或者本地磁盘空间不足,拉一半失败。
解决:在 globals.yml 里配置镜像加速地址,或者提前在有网机器上docker pull后docker save成 tar 包,拷贝到各节点docker load。检查/var/lib/docker所在分区剩余空间,至少留 50G。如果是拉取超时,可以调大 Docker 的--max-concurrent-downloads和超时时间,在/etc/docker/daemon.json里加"max-concurrent-downloads": 3降低并发反而更稳。
4.3 nova-compute 状态 up 但创建虚拟机报 NoValidHost
现象:openstack compute service list显示 nova-compute up,但openstack server create报NoValidHost: No host was found。
原因:Nova 调度器找不到满足条件的计算节点。常见有三种:计算节点没有启用虚拟化(egrep -c '(vmx|svm)' /proc/cpuinfo返回 0);nova-compute 容器里的virt_type配成了 kvm 但硬件不支持;资源不足,flavor 要的内存超过节点剩余。
解决:先确认 CPU 支持虚拟化并在 BIOS 里开启。嵌套环境把 globals.yml 的nova_compute_virt_type改成 qemu 后重新kolla-ansible deploy。用openstack compute service list --service nova-compute看每个节点的状态,再用openstack resource provider inventory list看资源提供者的库存。如果资源够但还报错,看/var/log/kolla/nova/nova-scheduler.log里的过滤原因,通常是NUMATopologyFilter或AggregateInstanceExtraSpecsFilter把节点过滤掉了。
4.4 虚拟机拿到 IP 但 ping 不通外网
现象:虚拟机内ip a有 10.0.0.x 地址,但ping 114.114.114.114不通,浮动 IP 也连不上。
原因:网络链路某一环断了。可能是安全组没放行 ICMP,可能是路由的 external gateway 没设置,可能是物理交换机的 Trunk 没放行对应 VLAN,也可能是neutron_external_interface配错网卡导致 OVS 流表不对。
解决:按链路逐段排查。先在虚拟机里ping 10.0.0.1(网关),通说明内网正常;再在路由命名空间里ip netns exec qrouter-xxx ping 114.114.114.114,通说明 NAT 正常;不通就检查openstack router show router1的 external_gateway_info 是否有值。安全组用openstack security group rule list default确认 ICMP 规则存在。物理网络侧确认业务网卡接的交换机端口是 Trunk 且允许了外部 VLAN。OVS 流表用ovs-ofctl dump-flows br-int看有没有丢包计数。
4.5 重启后服务起不来或 VIP 漂移
现象:机房断电或维护重启后,部分容器没起来,或者kolla_internal_vip_addressping 不通,API 全部 503。
原因:Kolla-Ansible 的容器默认 restart policy 是 unless-stopped,正常重启应该能起。起不来多半是依赖服务顺序问题,比如 MariaDB 没起来 RabbitMQ 就反复重启。VIP 漂移是 Keepalived 的 VRRP 组播被交换机拦截,或者多节点同时抢占 VIP。
解决:重启后先docker ps -a看哪些容器 Exited,docker logs看退出原因。MariaDB 起不来常见是数据目录权限或磁盘满。VIP 问题检查ip a看 VIP 在哪个节点,journalctl -u keepalived看 VRRP 状态。如果交换机禁了组播,把 keepalived 改成单播模式,在 globals.yml 里配置keepalived_use_unicast相关参数。生产环境建议给控制节点配 UPS,避免非正常断电。
5. 从能跑到好用:私有云扩容与日常巡检的几个习惯
一套最小集群跑通后,真正的工作才刚开始。我自己的习惯是先把监控和日志收起来,再谈扩容。Kolla-Ansible 自带 Prometheus + Grafana + ELK 的开关,在 globals.yml 里把enable_prometheus、enable_grafana、enable_elasticsearch打开,重新 deploy 就能在 VIP 的对应端口看到面板。Grafana 里重点看三个指标:nova-compute 的running_vms数量、Neutron 的openstack_neutron_l3_agent心跳、Cinder 的volume_backend剩余空间。这三个任何一个异常,都意味着用户马上要报障。
扩容计算节点比想象中简单。新机器做好基础环境(主机名、时间同步、内核参数),把主机名加进/etc/kolla/inventory的[compute]组,然后执行kolla-ansible -i /etc/kolla/inventory deploy --limit node4,只对新节点生效。注意新节点的api_interface网段要和控制节点通,neutron_external_interface要接到同一个业务交换机。加完后openstack compute service list能看到新节点,但已有虚拟机的资源提供者不会自动迁移,需要手动openstack server migrate或者等新调度自然均衡。
存储扩容要分情况。如果 Cinder 后端是 LVM,加新磁盘后pvcreate、vgextend到 cinder-volumes 卷组,然后重启 cinder-volume 容器就能识别新空间。如果是 Ceph,加 OSD 节点后 Ceph 自动重平衡,但要注意ceph osd crush reweight的节奏,一次加太多 OSD 会导致数据迁移打满网络。我一般一次加一个 OSD,等ceph -s的 recovery 完成再加下一个。
日常巡检我固定看几个命令。openstack hypervisor list看节点数和状态;openstack server list --all-projects --long看有没有长期 error 的虚拟机;openstack volume list --all-projects看有没有卡在 error 的卷;docker ps --filter health=unhealthy看有没有容器健康检查失败。这些命令写成脚本每天跑一次,输出发到内部群,比等用户报障再查要主动得多。
最后说一个我踩过的坑:不要在生产集群上直接kolla-ansible upgrade。升级前先在测试环境用同样的 inventory 跑一遍,确认镜像 tag、数据库迁移脚本、配置变更都没问题。升级时先升控制节点再升计算节点,计算节点升级前把上面的虚拟机迁移走。升级完立刻验证openstack token issue、openstack server list、创建一台测试虚拟机。这套流程我坚持了两年,没在升级上翻过车。希望帮到你。
本文还有配套的精品资源,点击获取