一、交换机端口规划(华为 / H3C 通用配置)

交换机端口

对接设备

端口模式

所属 VLAN

备注

GE0/0/1

管理节点 eno1

access

VLAN 20(公网)

管理节点公网物理口

GE0/0/2

管理节点 eno2

trunk

VLAN 20,100,200,300

业务 Trunk 口(透传所有业务 VLAN)

GE0/0/3

管理节点 eno3

access

VLAN 10(内部管理)

OpenStack 内部通信

GE0/0/4

管理节点 eno4

access

VLAN 30(PXE/IPMI)

裸金属 PXE 引导、IPMI 管理

GE0/0/9

裸金属节点 BMC

access

VLAN 30(PXE/IPMI)

裸金属 BMC 远程管理

GE0/0/10

裸金属节点 业务口

trunk

VLAN 20,100,200,300

裸金属业务流量口

-

交换机 VLAN 网关

-

VLAN10:10.0.0.254

VLAN20:116.169.215.1

VLAN30: 无网关

三层网关,仅 VLAN10/20 配置


二、管理节点(jiyun1)网络规划

物理网卡

用途

配置模式

IP 地址 / 子网掩码

网关

所属 VLAN

备注

eno1

公网物理口

静态 IP

116.169.215.251/24

116.169.215.1

VLAN 20

系统物理 IP,不与 VIP 冲突

eno2

业务 Trunk 口

无 IP

无 IP

VLAN 20,100,200,300

Neutron 业务透传口

eno3

内部管理口

静态 IP

10.0.0.2/24

VLAN 10

OpenStack 内部 API / 数据库通信

eno4

PXE/IPMI 口

静态 IP

192.168.1.3/24

VLAN 30

裸金属 PXE、IPMI 通信


三、裸金属节点(jiyun2)网络规划

物理网口

用途

配置模式

IP 地址 / 子网掩码

网关

所属 VLAN

备注

BMC 口

裸金属带外管理

静态 IP

192.168.1.2/24

VLAN 30

IPMI 远程管理,无网关

业务网口

裸金属业务流量

Trunk

无固定 IP(DHCP)

VLAN 20,100,200,300

部署后由 OpenStack 分配 IP


四、VIP & PXE 地址池规划(核心无冲突版)

类型

地址

占用服务

用途

状态

内部 VIP

10.0.0.100

HAProxy

OpenStack 内部 API/UI 入口

部署后占用,部署前空闲

外部 VIP

116.169.215.250

HAProxy

OpenStack 公网 API/UI 入口

部署前空闲(ping 不通),无冲突

PXE 地址池

192.168.1.150~199

Ironic DNSMASQ

裸金属部署 DHCP 分配

自动分配,无需手动配置

Inspector 地址池

192.168.1.110~149

Ironic Inspector

裸金属硬件巡检 DHCP 分配

自动分配,无需手动配置

五、完整部署脚本脚本:

#!/bin/bash
# ===================================================================
# Kolla-Ansible Yoga 终极一键部署脚本 (Ubuntu 20.04 纯净环境专用)
# 版本: Final-20260420 - 清华源 + 全自动适配 + 详尽注释
# ===================================================================

set -e

# --------------------- 颜色输出 ---------------------
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }

# --------------------- 环境检查 ---------------------
info "开始环境检查..."
[ "$EUID" -ne 0 ] && error "请使用 root 用户运行此脚本 (sudo su -)"
grep -q "20.04" /etc/os-release || warn "建议使用 Ubuntu 20.04,当前系统可能不兼容"
ping -c 3 -W 2 8.8.8.8 >/dev/null 2>&1 || error "网络不通,请检查互联网连接"

# 自动检测网卡
INTERFACES=($(ip -o link show | awk -F': ' '{print $2}' | grep -v lo))
[ ${#INTERFACES[@]} -lt 2 ] && error "至少需要2个网卡,当前检测到: ${INTERFACES[@]}"
info "当前可用网卡: ${INTERFACES[@]}"

# --------------------- 系统初始化 ---------------------
info "更新系统软件包..."
apt update && apt upgrade -y
apt install -y git python3-pip sshpass curl wget vim
systemctl disable --now apt-daily.timer apt-daily-upgrade.timer 2>/dev/null || true

# --------------------- 安装 Docker (清华大学镜像源) ---------------------
info "安装 Docker CE (清华大学镜像源)..."
apt install -y ca-certificates curl gnupg lsb-release
mkdir -p /etc/apt/keyrings
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
chmod a+r /etc/apt/keyrings/docker.gpg
apt update
apt install -y docker-ce docker-ce-cli containerd.io
systemctl enable --now docker
info "Docker 安装完成: $(docker --version)"

# --------------------- 修复 Python 环境 ---------------------
info "修复 Python3 环境..."
apt install --reinstall -y python3-openssl python3-pip python3-setuptools python3-wheel
curl -sS https://bootstrap.pypa.io/pip/3.8/get-pip.py | python3

# --------------------- 安装 Ansible (卸载旧版,安装2.12) ---------------------
info "安装 Ansible (兼容 Yoga 版本)..."
# 彻底移除旧版
apt remove --purge ansible -y 2>/dev/null || true
apt autoremove -y
# 使用 pip 安装 ansible-core 2.12.x
pip3 install 'ansible-core>=2.12,<2.13'

# 确保 PATH 包含 ~/.local/bin
export PATH="$HOME/.local/bin:$PATH"
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
hash -r
ANSIBLE_VER=$(ansible --version | head -1)
info "Ansible 安装完成: $ANSIBLE_VER"

# 安装 Ansible 所需集合
ansible-galaxy collection install ansible.netcommon ansible.posix community.general

# 安装 python3-docker 依赖
apt install -y python3-docker

# --------------------- 安装 Kolla-Ansible Yoga ---------------------
info "安装 Kolla-Ansible Yoga..."
pip3 install --no-cache-dir 'kolla-ansible>=14,<15'
command -v kolla-ansible >/dev/null || error "kolla-ansible 命令未找到"

# --------------------- 获取配置模板 (从 tarball) ---------------------
info "下载 Kolla-Ansible 配置模板..."
cd /tmp
wget -q https://tarballs.opendev.org/openstack/kolla-ansible/kolla-ansible-stable-yoga.tar.gz
tar -xzf kolla-ansible-stable-yoga.tar.gz
KOLLA_DIR=$(find /tmp -maxdepth 1 -type d -name "kolla-ansible*" | head -1)
[ -z "$KOLLA_DIR" ] && error "未找到解压后的目录"
rm -rf /etc/kolla
mkdir -p /etc/kolla
cp -r "$KOLLA_DIR/etc/kolla" /etc/
cp "$KOLLA_DIR/ansible/inventory/all-in-one" /etc/kolla/
rm -rf "$KOLLA_DIR" kolla-ansible-stable-yoga.tar.gz
cd ~

# --------------------- 生成密码 ---------------------
info "生成服务密码..."
if command -v kolla-genpwd >/dev/null; then
    kolla-genpwd
else
    warn "kolla-genpwd 未找到,手动生成密码文件"
    cat > /etc/kolla/passwords.yml << EOF
---
keystone_admin_password: $(openssl rand -hex 16)
database_password: $(openssl rand -hex 16)
rabbitmq_password: $(openssl rand -hex 16)
EOF
fi

# --------------------- 写入 globals.yml (自动适配网卡) ---------------------
info "配置 globals.yml..."
EXT_IF="${INTERFACES[0]}"
NEUTRON_IF="${INTERFACES[1]}"
MGMT_IF="${INTERFACES[2]:-${INTERFACES[0]}}"
IRONIC_IF="${INTERFACES[3]:-${INTERFACES[0]}}"

cat > /etc/kolla/globals.yml << EOF
---
openstack_release: "yoga"
kolla_base_distro: "ubuntu"
kolla_install_type: "source"

kolla_internal_vip_address: "10.0.0.100"
kolla_external_vip_address: "116.169.215.250"
kolla_external_vip_interface: "$EXT_IF"

network_interface: "$MGMT_IF"
neutron_external_interface: "$NEUTRON_IF"
ironic_dnsmasq_interface: "$IRONIC_IF"

enable_horizon: "yes"
enable_haproxy: "yes"
enable_ironic: "no"               # 默认禁用裸金属部署服务,如需启用请改为 yes 并下载 agent 镜像
enable_ironic_inspector: "no"     # 禁用裸金属自动发现功能,不影响 Ironic 核心;启用需先确保 ironic-agent 镜像存在

neutron_network_vlan_ranges: "physnet1:100,200,300"

ironic_dnsmasq_dhcp_range: "192.168.1.150,192.168.1.199"
ironic_inspector_dhcp_range: "192.168.1.110,192.168.1.149"
EOF

info "网卡分配: 外网=$EXT_IF, Neutron=$NEUTRON_IF, 管理=$MGMT_IF, Ironic=$IRONIC_IF"
warn "如果分配不符,请立即编辑 /etc/kolla/globals.yml 修正!"

# --------------------- 修正 inventory ---------------------
sed -i 's/^localhost$/localhost ansible_connection=local/' /etc/kolla/all-in-one

# --------------------- 修复主机名解析 ---------------------
info "修复主机名解析..."
HOSTNAME=$(hostname -s)
# 移除旧的 127.0.1.1 行,添加管理 IP 解析
sed -i "/127.0.1.1.*${HOSTNAME}/d" /etc/hosts
echo "10.0.0.2 ${HOSTNAME}" >> /etc/hosts
info "主机名 ${HOSTNAME} 已解析到 10.0.0.2"

# --------------------- 修复 Docker SDK 兼容性 ---------------------
info "配置 Docker Python SDK..."
pip3 uninstall -y docker urllib3 requests 2>/dev/null || true
pip3 install 'docker==5.0.3' 'urllib3<2.0' 'requests>=2.20.0,<2.28.0' jmespath
systemctl restart docker

# --------------------- 网卡 IP 配置提示 ---------------------
info "检查网卡 IP 配置..."
for IFACE in "$EXT_IF" "$NEUTRON_IF" "$MGMT_IF" "$IRONIC_IF"; do
    IP=$(ip -4 addr show "$IFACE" 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
    if [ -z "$IP" ]; then
        warn "网卡 $IFACE 未配置 IPv4 地址,预检查可能失败。请使用 netplan 配置后再重试。"
    else
        info "$IFACE: $IP"
    fi
done

# --------------------- 预检查 ---------------------
info "开始环境预检查 (prechecks)..."
kolla-ansible -i /etc/kolla/all-in-one prechecks

if [ $? -eq 0 ]; then
    info "✅ 预检查通过!可以执行部署命令:"
    info "   kolla-ansible -i /etc/kolla/all-in-one deploy"
else
    warn "预检查发现警告或错误,请根据输出修正后再运行 deploy"
fi

info "脚本执行完毕。"

文章作者: 楚少爱看雪
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 楚少爱看雪
学习 Study
喜欢就支持一下吧