网络 → 子网 → 路由 → 安全组 → 实例 → 浮动 IP:第一次完整走通云主机诞生全流程,并学会判断“它真的活着”
一、部署概述
| 项目 | 值 |
|---|---|
| 业务网 | private 10.0.0.0/24(geneve,带 DHCP) |
| 外部网 | public 172.24.4.0/24(flat,br-ex 网关 172.24.4.1) |
| 镜像 | cirros(qcow2,约 13MB) |
| 规格 | m1.tiny(1 vCPU / 512MB / 1GB 盘) |
上篇回顾:(三)Packstack 单机一键部署与 10 步验证——部署完成,10 步验证通过到镜像环节。
本篇以 CLI 为主线(每步都对应 Dashboard 里的同名操作,文末给出对照表),从零创建一台真正可登录的云主机。请先source /root/keystonerc_admin。
二、准备镜像(务必先验 size)
Packstack 部署时自动注册了一个 cirros 镜像,但正如坑 2 预告的,它可能是个 273 字节的“假镜像”。稳妥做法是自己传一个:
bash
wget http://download.cirros-cloud.net/0.5.2/cirros-0.5.2-x86_64-disk.img |
openstack image create "cirros" \ |
--file cirros-0.5.2-x86_64-disk.img \ |
--disk-format qcow2 --container-format bare --public |
openstack image show cirros -c size -c disk_format -c status -f value |
✔应该看到:size 为 13M~20M 量级、qcow2、active。
★ 如果 size 是几百字节,立刻停手——302 页面被当成了镜像,先看第(五)篇领解药再回来。
参数解释:
--disk-format qcow2:稀疏磁盘格式,节省存储,OpenStack 默认推荐--container-format bare:镜像外没有再包一层(如 ovf/tar),裸镜像就是 bare--public:所有项目可见;测试镜像设 public 方便,正式环境镜像默认 private
常用云镜像源汇总(都有 qcow2 现成下载):
| 发行版 | 地址 |
|---|---|
| Cirros | http://download.cirros-cloud.net/ |
| CentOS | http://cloud.centos.org/centos/7/images/ |
| Ubuntu | https://cloud-images.ubuntu.com/ |
| Rocky | https://dl.rockylinux.org/pub/rocky/9/images/x86_64/ |
已有 img(raw)想转 qcow2:qemu-img convert -f raw -O qcow2 myserver.img myserver.qcow2
三、创建网络与子网
3.1 外部网络(flat,直接桥到物理网卡)
bash
openstack network create --external \ |
--provider-physical-network extnet \ |
--provider-network-type flat public |
openstack subnet create --network public \ |
--subnet-range 172.24.4.0/24 --gateway 172.24.4.1 \ |
--allocation-pool start=172.24.4.100,end=172.24.4.200 \ |
--no-dhcp public-subnet |
理解要点:
--external:标记为外部网络,路由器的出口--provider-physical-network extnet:对应 Neutron 配置里physical_network映射到br-ex网桥的名字,名字要与 ML2 配置一致,这是 provider 网络最常见的出错点--no-dhcp:外网通常不做 DHCP,浮动 IP 从 allocation-pool 里取
3.2 内部网络(geneve 租户网络,带 DHCP)
bash
openstack network create private |
openstack subnet create --network private \ |
--subnet-range 10.0.0.0/24 --dhcp private-subnet |
应该看到:
openstack network list --long出现 public(flat/External=True)和 private(geneve)两个网络。
两种网络类型的分工:provider 网络(flat)直接映射物理网,性能好但占用真实 IP;租户网络(geneve)用隧道封装,支持任意多租户隔离,是私有云的主力。实例默认挂在租户网络上。
四、路由与安全组
4.1 路由:打通内外网
bash
openstack router create router1 |
openstack router add subnet router1 private-subnet # 内网接口 |
openstack router set router1 --external-gateway public # 外网网关 |
至此三层链路打通:实例(10.0.0.x) → private 子网 → router1 → public → br-ex → 物理网。
图表代码
SNAT 出网
DNAT 入站
云主机 10.0.0.x
private-subnet
geneve
router1
public 172.24.4.0/24
flat
br-ex 物理网
浮动IP 172.24.4.x
4.2 安全组:默认只放行“同组内”流量(坑 4)
bash
openstack security group rule create --proto icmp default |
openstack security group rule create --proto tcp --dst-port 22 default |
不加这两条规则,从外面 ping/SSH 实例的浮动 IP 会全部丢包——这是新手第二大错觉来源(第一大是坑 1),症状和“实例死了”一模一样,实际只是门没开。
五、创建实例与“真活三连”验证
bash
openstack flavor list # 选 m1.tiny |
openstack server create --flavor m1.tiny --image cirros \ |
--network private test-vm |
openstack server list |
# ✔ 状态 ACTIVE,分配到 10.0.0.x |
★ 但 ACTIVE 不代表真的跑起来了(坑 1,全系列最重要的判断标准)。做“真活三连”:
bash
# 1) console.log 有内核引导输出(假的只会有 cloud-init 元数据) |
openstack console log show test-vm | head |
# 2) 到实例所在节点看 CPU time 持续增长(无 KVM 环境增长慢是正常的) |
virsh dominfo instance-00000001 | grep 'CPU time' |
# 3) 实例控制台里应出现 cirros 登录横幅 |
tail -f /var/lib/nova/instances/<实例UUID>/console.log |
无 KVM 环境的预期:cirros 引导约 1~3 分钟,期间 CPU time 缓慢增长、console.log 逐渐出现内核日志。如果几分钟后 console.log 仍无任何内核输出、CPU time 几乎不动,那就是实例根本没引导——回看镜像 size(第(五)篇)。
六、浮动 IP 与登录验证
bash
# 从外网地址池取一个浮动 IP 并绑定 |
openstack floating ip create public # 得到 172.24.4.x |
openstack server add floating ip test-vm 172.24.4.199 |
# 放行过 icmp/22 后,从外部验证 |
ping -c 3 172.24.4.199 # 实测:0% 丢包 |
ssh cirros@172.24.4.199 # 密码 cubswin:) |
✔应该看到:CirrOS 登录横幅,上面打印着实例的内网 IP、网卡、主机名等启动信息。
浮动 IP 的原理一句话:router1 在 public 网络上做 DNAT,把浮动 IP 的流量转发到实例的固定 IP;实例出网则走 SNAT。所以固定 IP(10.0.0.x)是实例的“身份证”,浮动 IP 是它的“门牌号”。
七、CLI 与 Dashboard 操作对照表
| CLI | Dashboard 位置 |
|---|---|
image create | 项目 → 计算 → 镜像 → 创建镜像 |
network create | 项目 → 网络 → 网络 → 创建网络 |
router create / set | 项目 → 网络 → 路由拓扑 |
security group rule create | 项目 → 网络 → 安全组 → 管理规则 |
server create | 项目 → 计算 → 实例 → 创建实例 |
floating ip create / add | 创建实例向导第 4 步“网络”,或 实例 → 绑定浮动 IP |
console log show | 实例 → 动作 → 控制台日志 |
七点五、创建实例的完整姿势(超出最小示例的参数)
第(五)节的命令是最小可用版本,生产中创建实例还要带这些参数:
bash
openstack server create \ |
--flavor m1.small \ |
--image centos7 \ |
--network private \ |
--security-group web-sg \ |
--key-name mykey \ |
--availability-zone nova:compute1 \ |
--property department=ops \ |
--user-data cloud-init.yaml \ |
--wait web-01 |
| 参数 | 作用 | 说明 |
|---|---|---|
| --security-group | 指定安全组 | 不指定则用 default(只放同组内流量) |
| --key-name | 注入 SSH 公钥 | 云镜像没有密码,必须用密钥登录 |
| --availability-zone | 指定调度节点 | nova:compute1 = 调度到 compute1,排障/隔离时常用 |
| --property | 自定义元数据 | 可配合调度过滤器使用 |
| --user-data | 云初始化脚本 | 开机自动装软件/改配置(cloud-init) |
| --wait | 阻塞等状态变化 | 脚本化创建必备,否则要轮询 status |
自定规格(flavor)示例——内置规格不合用时:
bash
openstack flavor create --vcpus 2 --ram 2048 --disk 20 web.medium --public |
openstack flavor list |
密钥对:
bash
openstack keypair create mykey > /root/mykey.pem # 私钥只此一份,务必备份 |
chmod 600 /root/mykey.pem |
ssh -i /root/mykey.pem centos@<浮动IP> # 云镜像用户名:centos/ubuntu/cloud-user |
cirros 用密码登录是特例(教学友好);所有云镜像的标准登录方式都是密钥,--key-name参数从第一次创建正式实例起就该带上。
八、两个网络原理补课(看懂你建的东西)
8.1 geneve 隧道:租户网络为什么能隔离
geneve 是一种隧道封装协议:实例发出的普通以太网帧,在物理网传输时被套上一层 UDP 外壳(外层 IP 是两台宿主机的 IP),外壳里带着一个 24 位的 VNI(网络标识符)。不同租户网络的 VNI 不同,物理网上的流量即使混在一起,解包时也会被正确隔离——这就是为什么 private 网络可以用 10.0.0.0/24 这种“烂大街”的网段而不冲突。
对比:早期方案 VLAN 只有 12 位 ID(4094 个),大环境不够用;geneve 24 位(16M+),且元数据可扩展,这是 Train 默认它的原因。
8.2 浮动 IP 的 SNAT/DNAT 全过程
图表代码
入站 DNAT
目的 172.24.4.199
改写为 10.0.0.5
外部用户
router1
实例
出网 SNAT
源地址改写为 172.24.4.x
实例 10.0.0.5
router1
br-ex 物理网
router1 在 public 网络接口上维护一张 NAT 表:
- 出网(SNAT):实例访问外网时,源 IP 10.0.0.5 被改写为路由器的外网地址,回程流量按表回翻
- 入站(DNAT):外部访问浮动 IP 172.24.4.199 时,目的 IP 被改写为 10.0.0.5
这也解释了两个常见现象:为什么实例不绑浮动 IP 也能上网(出网只靠 SNAT);为什么绑了浮动 IP 还 ping 不通(DNAT 的入站规则有了,但安全组没放行——坑 4)。
想亲眼看这张表:登录 controller 执行ip netns | grep qrouter找到路由器命名空间,ip netns exec qrouter-xxx iptables -t nat -L -n。
九、cirros:为什么全世界的教程都用它
| 特性 | cirros | CentOS/Ubuntu 云镜像 |
|---|---|---|
| 体积 | ~13MB | 200MB~1GB |
| 引导时间 | 数秒~1分钟(无 KVM 下 1~3 分钟) | 无 KVM 下 10 分钟+ |
| 用途 | 专为核心链路验证设计 | 接近生产 |
| 登录方式 | 密码 cubswin:) | 密钥/云-init |
cirros 是 OpenStack 官方维护的迷你测试系统,它的存在意义就是把“验证云平台能不能跑”这个动作的成本压到最低。教学、验收、巡检都用它;真正交付业务时再换云镜像。
它的登录横幅本身就是一份“健康报告”——上面打印的 IP、网卡、主机名信息与元数据服务一致,说明 metadata 链路也是通的。
十、小结
| 阶段 | 关键命令 | 易错点 |
|---|---|---|
| 镜像 | openstack image create | size 只有几百字节 = 302 坑(坑 2) |
| 外网 | flat + allocation-pool | physical-network 名字与 ML2 配置不一致 |
| 内网 | geneve + dhcp | 忘记加 DHCP 实例拿不到 IP |
| 路由 | router set --external-gateway | 忘设外网网关则实例出不了网 |
| 安全组 | 放行 icmp/22(坑 4) | 忘放行症状像“实例死了” |
| 实例 | server create | ACTIVE ≠ 真活,做三连验证(坑 1) |
下篇预告:(五)单机故障排查实录——我们部署时踩到的最隐蔽的坑:Glance 里那个“镜像”,其实是一个 273 字节的 HTML 文件。完整定位过程 + 修复方法。