Administrator
发布于 2025-03-20 / 3 阅读
0

Ubuntu 22.04.5 LTS+OpenStack-C版原生部署

Ubuntu 22.04.5 LTS+OpenStack-C版原生部署

OpenStack-Caracal + Ubuntu 22.04.5 LTS 双节点双网卡搭建

Ubuntu 22.04.5 LTS 最小化安装

资源分配:

主机名 CPU 内存 硬盘
controller 2 8G 50GB
compute 2 4G 100GB

网络安排:

主机名 网卡1(ens33)管理网络 网卡1(ens34)提供网络
controller NAT模式 NAT模式
compute NAT模式 NAT模式

基础环境配置

环境变量脚本

env.sh

#!/bin/bash

### 主机配置

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 控制节点主机密码。例如,000000
CONTROLLER_PASS=000000

# 控制节点管理网络接口名称。例如,eth0 或 ens33
CONTROLLER_INTERFACE_NAME=ens33

# 控制节点管理网络接口地址。例如,192.168.10.10
CONTROLLER_MANAGEMENT_IP=192.168.10.10

# 计算节点主机名称。例如,compute1
COMPUTE_HOSTNAME=compute1

# 计算节点主机密码。例如,000000
COMPUTE_PASS=000000

# 计算节点管理网络接口名称。例如,eth0 或 ens33
COMPUTE_INTERFACE_NAME=ens33

# 计算节点管理网络接口地址。例如,192.168.10.20
COMPUTE_MANAGEMENT_IP=192.168.10.20

### 基础配置

# 避免在安装过程中出现交互式提示。值,noninteractive
export DEBIAN_FRONTEND=noninteractive

# 数据库密码。例如,000000
DB_PASS=000000

# 消息队列密码。例如,000000
RABBIT_PASS=000000

### keystone

# Keystone 数据库密码。例如,000000
KEYSTONE_DBPASS=000000

# Keystone 管理员密码。例如,000000
ADMIN_PASS=000000

### Glance

# Glance 数据库密码。例如,000000
GLANCE_DBPASS=000000

# Glance 服务密码。例如,000000
GLANCE_PASS=000000

### Placement

# Placement 数据库密码。例如,000000
PLACEMENT_DBPASS=000000

# Placement 服务密码。例如,000000
PLACEMENT_PASS=000000

### Nova

# Nova 数据库密码。例如,000000
NOVA_DBPASS=000000

# Nova 服务密码。例如,000000
NOVA_PASS=000000

### Neutron

# Neutron 数据库密码。例如,000000
NEUTRON_DBPASS=000000

# Neutron 服务密码。例如,000000
NEUTRON_PASS=000000

# 提供者网络的 OVS 桥接名称。例如,provider
PROVIDER_BRIDGE_NAME=provider

# CONTROLLERP节点的提供者网络接口的名称。例如,eth1,ens34
CONTROLLER_PROVIDER_INTERFACE_NAME=ens34

# CONTROLLERP节点用于 VXLAN 隧道的本地 IP 地址,提供者网络IP地址。例如,192.168.20.10
CONTROLLERP_PROVIDER_INTERFACE_IP=192.168.100.10

# COMPUTE节点的提供者网络接口的名称。例如,eth1,ens34
COMPUTE_PROVIDER_INTERFACE_NAME=ens34

# COMPUTE节点用于 VXLAN 隧道的本地 IP 地址,提供者网络IP地址。例如,192.168.20.20
COMPUTE_PROVIDER_INTERFACE_IP=192.168.100.20

# 用于元数据代理的共享密钥。例如,000000
METADATA_SECRET_PASS=000000

### Horizon

### Ceilometer

# Gnocchi 数据库密码。例如,000000
GNOCCHI_DBPASS=000000

# Gnocchi 服务密码。例如,000000
GNOCCHI_PASS=000000

# Ceilometer 服务密码。例如,000000
CEILOMETER_PASS=000000

### Aodh

# Aodh 数据库密码。例如,000000
AODH_DBPASS=000000

# Aodh 服务密码。例如,000000
AODH_PASS=000000

### Heat

# Heat 数据库密码。例如,000000
HEAT_DBPASS=000000

# Heat 服务密码。例如,000000
HEAT_PASS=000000

# Heat domain 服务密码。例如,000000
HEAT_DOMAIN_PASS=000000

基础环境搭建脚本

init_base.sh

#!/bin/bash

## 检查 env.sh 文件是否存在
#if [ ! -f /root/env.sh ]; then
#  echo "错误:/root/env.sh 文件不存在,请确保该文件已正确放置。"
#  exit 1
#fi

# 生效配置文件
source /root/env.sh

# 更新控制节点环境
echo "正在更新控制节点环境..."

# 设置禁止ipv6
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf 
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
sudo sysctl -p

# 添加 OpenStack 存储库
add-apt-repository -y cloud-archive:caracal
apt -y update && apt -y upgrade

#apt -y update
#apt -y upgrade

# 安装 sshpass 工具
echo "正在安装 sshpass 工具..."
apt install -y sshpass crudini

# 配置 /etc/hosts 文件
echo "正在配置 /etc/hosts 文件..."

# 在控制节点上配置 /etc/hosts
sed -i "/\b$CONTROLLER_HOSTNAME\b/d" /etc/hosts  # 删除旧的控制节点条目
echo "$CONTROLLER_MANAGEMENT_IP $CONTROLLER_HOSTNAME" | tee -a /etc/hosts  # 添加新的控制节点条目

# 追加计算节点的条目,但仅当它不存在时
if ! grep -q "^$COMPUTE_MANAGEMENT_IP $COMPUTE_HOSTNAME$" /etc/hosts; then
  echo "$COMPUTE_MANAGEMENT_IP $COMPUTE_HOSTNAME" | tee -a /etc/hosts
fi

# 在计算节点上配置 /etc/hosts
echo "正在在计算节点上配置 /etc/hosts 文件..."
sshpass -p "$COMPUTE_PASS" ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME << EOF
  sed -i "/\b$CONTROLLER_HOSTNAME\b/d" /etc/hosts  # 删除旧的控制节点条目
  echo "$CONTROLLER_MANAGEMENT_IP $CONTROLLER_HOSTNAME" | tee -a /etc/hosts  # 添加新的控制节点条目

  if ! grep -q "^$COMPUTE_MANAGEMENT_IP $COMPUTE_HOSTNAME\$" /etc/hosts; then
    echo "$COMPUTE_MANAGEMENT_IP $COMPUTE_HOSTNAME" | tee -a /etc/hosts
  fi
EOF

### 配置 SSH 免密登录

echo "正在设置控制器节点和计算节点之间的 SSH 密钥认证..."

# 生成控制器节点的 SSH 密钥对(如果尚未生成)
if [ ! -f ~/.ssh/id_rsa ]; then
  ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
fi

# 自动接受新的 SSH 主机密钥
if ! grep -q "$COMPUTE_HOSTNAME" ~/.ssh/known_hosts; then
  ssh-keyscan -H $COMPUTE_HOSTNAME >> ~/.ssh/known_hosts
fi

# 将控制器节点的公钥复制到计算节点
echo "正在将控制器节点的公钥复制到计算节点..."
sshpass -p "$COMPUTE_PASS" ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME

# 确保控制器节点自身免密登录
sshpass -p "$CONTROLLER_PASS" ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@$CONTROLLER_HOSTNAME

# 发送 env.sh 到计算节点
echo "正在将 env.sh 发送到计算节点..."
scp env.sh root@$COMPUTE_HOSTNAME:/root/

# 在计算节点上执行的操作
COMPUTE_SCRIPT=$(cat <<EOF
#!/bin/bash

# 设置禁止ipv6
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf 
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
sudo sysctl -p

# 添加 OpenStack 存储库
add-apt-repository -y cloud-archive:caracal
apt -y update && apt -y upgrade

## 更新软件包列表
#apt -y update
#
## 升级所有已安装的软件包
#apt -y upgrade

# 安装 sshpass 和 crudini 工具
apt install -y sshpass crudini

# 生效配置文件
source /root/env.sh

# 生成计算节点的 SSH 密钥对(如果尚未生成)
if [ ! -f ~/.ssh/id_rsa ]; then
  ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
fi

# 将计算节点的公钥复制到控制器节点
sshpass -p "$CONTROLLER_PASS" ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@$CONTROLLER_HOSTNAME

# 确保计算节点自身免密登录
sshpass -p "$COMPUTE_PASS" ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME

# 确保计算节点自身免密登录
if ! grep -q "\$(cat ~/.ssh/id_rsa.pub)" ~/.ssh/authorized_keys; then
  cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
fi

EOF
)

# 通过 SSH 执行计算节点脚本
echo "正在在计算节点上执行配置脚本..."
ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME "bash -s" <<< "$COMPUTE_SCRIPT"

# 检查 SSH 密钥复制是否成功
if [ $? -ne 0 ]; then
  echo "SSH 密钥复制失败,请检查密码和网络连接。"
  exit 1
else
  echo "SSH 密钥认证设置成功。"
fi

### 配置时间同步

# 设置控制节点的时区为上海
echo "正在设置控制节点的时区为上海..."
timedatectl set-timezone Asia/Shanghai

echo "正在配置 NTP 时间同步..."

apt install -y chrony

# 解禁 NTP 客户端访问,并设置本地 stratum
sed -i '/^#allow 192.168\/16/ s/^#//' /etc/chrony/chrony.conf
sed -i '/^#local stratum 10/ s/^#//' /etc/chrony/chrony.conf

echo "allow 192.168/16" >> /etc/chrony/chrony.conf
echo "local stratum 10" >> /etc/chrony/chrony.conf

# 重启并启用 chrony 服务
systemctl enable chrony && systemctl restart chrony

# 在计算节点上安装和配置 chrony
echo "正在在计算节点上配置 NTP 时间同步..."
ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME "bash -s" << EOF
  timedatectl set-timezone Asia/Shanghai
  apt install -y chrony
  sed -i '/^server/ s/^/#/' /etc/chrony/chrony.conf
  sed -i '/^pool/ s/^/#pool/' /etc/chrony/chrony.conf
  echo "server $CONTROLLER_HOSTNAME iburst" | tee -a /etc/chrony/chrony.conf
  systemctl enable chrony && systemctl restart chrony
EOF

### 完成

echo "OpenStack 安装前的基础环境配置完成。您最好重启您的主机以确保更新生效。"

OpenStack环境

初始化需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库密码。例如,000000
DB_PASS=000000

# 消息队列密码。例如,000000
RABBIT_PASS=000000

初始化脚本

init_openstack.sh

#!/bin/bash

### 生效配置

#生效配置文件
source /root/env.sh

###

# 更新环境
#apt -y update && apt -y upgrade

## 添加工具
#apt install -y crudini

###

## 添加 OpenStack 存储库
#add-apt-repository -y cloud-archive:caracal
#apt -y update && apt -y upgrade

###

# 安装openstack客户端
apt install -y python3-openstackclient

###

# 安装并配置 MariaDB
apt install -y mariadb-server python3-pymysql

# 配置 MariaDB
crudini --set /etc/mysql/mariadb.conf.d/99-openstack.cnf mysqld bind-address $CONTROLLER_MANAGEMENT_IP
crudini --set /etc/mysql/mariadb.conf.d/99-openstack.cnf mysqld default-storage-engine innodb
crudini --set /etc/mysql/mariadb.conf.d/99-openstack.cnf mysqld innodb_file_per_table on
crudini --set /etc/mysql/mariadb.conf.d/99-openstack.cnf mysqld max_connections 4096
crudini --set /etc/mysql/mariadb.conf.d/99-openstack.cnf mysqld collation-server utf8_general_ci
crudini --set /etc/mysql/mariadb.conf.d/99-openstack.cnf mysqld character-set-server utf8

# 重启 MariaDB 服务
systemctl enable mariadb && systemctl restart mariadb

# 运行MySQL配置脚本
expect -c "
spawn mysql_secure_installation
expect \"Enter current password for root (enter for none):\"
send \"\r\"
expect \"Set root password?\"
send \"y\r\"
expect \"New password:\"
send \"$DB_PASS\r\"
expect \"Re-enter new password:\"
send \"$DB_PASS\r\"
expect \"Remove anonymous users?\"
send \"y\r\"
expect \"Disallow root login remotely?\"
send \"n\r\"
expect \"Remove test database and access to it?\"
send \"y\r\"
expect \"Reload privilege tables now?\"
send \"y\r\"
expect eof
"

###

# 安装并配置 RabbitMQ
apt install -y rabbitmq-server

# 配置 RabbitMQ
rabbitmqctl add_user openstack $RABBIT_PASS
rabbitmqctl set_permissions openstack ".*" ".*" ".*"

# 重启 RabbitMQ 服务
systemctl enable rabbitmq-server && systemctl restart rabbitmq-server

###

# 安装并配置 Memcached
apt install -y memcached python3-memcache

# 配置 Memcached
sed -i  -e 's/-l 127.0.0.1/-l 127.0.0.1,'$CONTROLLER_MANAGEMENT_IP'/g' /etc/memcached.conf

# 重启 Memcached 服务
systemctl enable memcached && systemctl restart memcached

###

# 安装并配置 Etcd
apt install -y etcd

# 备份 Etcd 配置文件
cp /etc/default/etcd{,.bak}

## 配置 Etcd
#crudini --set /etc/default/etcd ETCD_NAME "controller"
#crudini --set /etc/default/etcd ETCD_DATA_DIR "/var/lib/etcd"
#crudini --set /etc/default/etcd ETCD_INITIAL_CLUSTER_STATE "new"
#crudini --set /etc/default/etcd ETCD_INITIAL_CLUSTER_TOKEN "etcd-cluster-01"
#crudini --set /etc/default/etcd ETCD_INITIAL_CLUSTER "controller=http://$CONTROLLER_MANAGEMENT_IP:2380"
#crudini --set /etc/default/etcd ETCD_INITIAL_ADVERTISE_PEER_URLS "http://$CONTROLLER_MANAGEMENT_IP:2380"
#crudini --set /etc/default/etcd ETCD_ADVERTISE_CLIENT_URLS "http://$CONTROLLER_MANAGEMENT_IP:2379"
#crudini --set /etc/default/etcd ETCD_LISTEN_PEER_URLS "http://0.0.0.0:2380"
#crudini --set /etc/default/etcd ETCD_LISTEN_CLIENT_URLS "http://$CONTROLLER_MANAGEMENT_IP:2379"

# 使用 sed 替换配置项
sed -i -e '/^# *ETCD_NAME=/c\ETCD_NAME="controller"' \
        -e '/^# *ETCD_DATA_DIR=/c\ETCD_DATA_DIR="/var/lib/etcd"' \
        -e '/^# *ETCD_INITIAL_CLUSTER_STATE=/c\ETCD_INITIAL_CLUSTER_STATE="new"' \
        -e '/^# *ETCD_INITIAL_CLUSTER_TOKEN=/c\ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01"' \
        -e "/^# *ETCD_INITIAL_CLUSTER=/c\ETCD_INITIAL_CLUSTER=\"controller=http://$CONTROLLER_MANAGEMENT_IP:2380\"" \
        -e "/^# *ETCD_INITIAL_ADVERTISE_PEER_URLS=/c\ETCD_INITIAL_ADVERTISE_PEER_URLS=\"http://$CONTROLLER_MANAGEMENT_IP:2380\"" \
        -e "/^# *ETCD_ADVERTISE_CLIENT_URLS=/c\ETCD_ADVERTISE_CLIENT_URLS=\"http://$CONTROLLER_MANAGEMENT_IP:2379\"" \
        -e '/^# *ETCD_LISTEN_PEER_URLS=/c\ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"' \
        -e "/^# *ETCD_LISTEN_CLIENT_URLS=/c\ETCD_LISTEN_CLIENT_URLS=\"http://$CONTROLLER_MANAGEMENT_IP:2379\"" \
        /etc/default/etcd

# 重启 Etcd 服务
systemctl enable etcd && systemctl restart etcd

###

echo "OpenStack 基础服务已安装并配置完成。您最好重启您的主机以确保更新生效。"

Keystone

keystone需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库密码。例如,000000
DB_PASS=000000

# Keystone 数据库密码。例如,000000
KEYSTONE_DBPASS=000000

# Keystone 管理员密码。例如,000000
ADMIN_PASS=000000

Keystone脚本

install_keystone.sh

#!/bin/bash

### 生效配置

#生效配置文件
source /root/env.sh

# 创建 Keystone 数据库
mysql -uroot -p$DB_PASS -e "create database IF NOT EXISTS keystone;"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '$KEYSTONE_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '$KEYSTONE_DBPASS';"

# 安装 Keystone 和相关依赖
apt install -y keystone

# 备份 Keystone 配置文件
cp /etc/keystone/keystone.conf{,.bak}

# 使用 crudini 修改 Keystone 配置文件
crudini --set /etc/keystone/keystone.conf database connection "mysql+pymysql://keystone:$KEYSTONE_DBPASS@$CONTROLLER_HOSTNAME/keystone"
crudini --set /etc/keystone/keystone.conf token provider fernet

# 同步数据库
su -s /bin/sh -c "keystone-manage db_sync" keystone

# 设置 Fernet 和 Credential 密钥
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
keystone-manage credential_setup --keystone-user keystone --keystone-group keystone

# 引导 Keystone
keystone-manage bootstrap --bootstrap-password $ADMIN_PASS \
  --bootstrap-admin-url http://$CONTROLLER_HOSTNAME:5000/v3/ \
  --bootstrap-internal-url http://$CONTROLLER_HOSTNAME:5000/v3/ \
  --bootstrap-public-url http://$CONTROLLER_HOSTNAME:5000/v3/ \
  --bootstrap-region-id RegionOne

# 配置 Apache
#sed -i "s/#ServerName www.example.com:80/ServerName $CONTROLLER_HOSTNAME/g" /etc/apache2/apache2.conf
echo "ServerName controller" >> /etc/apache2/apache2.conf 

systemctl enable apache2 && systemctl restart apache2

# 创建 admin-openrc.sh 文件
cat <<EOF | tee /etc/keystone/admin-openrc.sh
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=$ADMIN_PASS
export OS_AUTH_URL=http://$CONTROLLER_HOSTNAME:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
EOF

# 复制 admin-openrc.sh 到根目录
cp /etc/keystone/admin-openrc.sh /root/admin-openrc.sh

# 加载环境变量
source /etc/keystone/admin-openrc.sh

# 创建 Service 项目
openstack project create --domain default --description "Service Project" service

# 验证 Keystone
openstack token issue

echo "Keystone 已安装并配置完成。"

Glance

Glance需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库 root 用户密码。例如,000000
DB_PASS=000000

# Glance 数据库密码。例如,000000
GLANCE_DBPASS=000000

# Glance 服务密码。例如,000000
GLANCE_PASS=000000

Glance脚本

install_glance.sh

#!/bin/bash

### 生效配置

#生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh 
source /etc/keystone/admin-openrc.sh 

# 创建 Glance 数据库
mysql -uroot -p$DB_PASS -e "CREATE DATABASE IF NOT EXISTS glance;"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY '$GLANCE_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY '$GLANCE_DBPASS';"

# 创建 Glance 用户
openstack user create --domain default --password $GLANCE_PASS glance

# 添加 Glance 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user glance admin

# 创建 Glance 服务
openstack service create --name glance --description "OpenStack Image" image

# 创建 Glance 端点
openstack endpoint create --region RegionOne image public http://$CONTROLLER_HOSTNAME:9292
openstack endpoint create --region RegionOne image internal http://$CONTROLLER_HOSTNAME:9292
openstack endpoint create --region RegionOne image admin http://$CONTROLLER_HOSTNAME:9292

# 安装 Glance
apt install -y glance

# 备份 Glance 配置文件
cp /etc/glance/glance-api.conf{,.bak}

# 使用 crudini 修改 Glance 配置文件
crudini --set /etc/glance/glance-api.conf database connection "mysql+pymysql://glance:$GLANCE_DBPASS@$CONTROLLER_HOSTNAME/glance"
crudini --set /etc/glance/glance-api.conf keystone_authtoken www_authenticate_uri "http://$CONTROLLER_HOSTNAME:5000"
crudini --set /etc/glance/glance-api.conf keystone_authtoken auth_url "http://$CONTROLLER_HOSTNAME:5000"
crudini --set /etc/glance/glance-api.conf keystone_authtoken memcached_servers "$CONTROLLER_HOSTNAME:11211"
crudini --set /etc/glance/glance-api.conf keystone_authtoken auth_type password
crudini --set /etc/glance/glance-api.conf keystone_authtoken project_domain_name Default
crudini --set /etc/glance/glance-api.conf keystone_authtoken user_domain_name Default
crudini --set /etc/glance/glance-api.conf keystone_authtoken project_name service
crudini --set /etc/glance/glance-api.conf keystone_authtoken username glance
crudini --set /etc/glance/glance-api.conf keystone_authtoken password $GLANCE_PASS
crudini --set /etc/glance/glance-api.conf paste_deploy flavor keystone

# 同步数据库
su -s /bin/sh -c "glance-manage db_sync" glance

# 启用并重启 Glance API 服务
systemctl enable glance-api && systemctl restart glance-api

# 加载 admin-openrc 文件
source /root/admin-openrc.sh 
source /etc/keystone/admin-openrc.sh 

# 下载并上传镜像
# wget http://download.cirros-cloud.net/0.6.3/cirros-0.6.3-x86_64-disk.img
# openstack image create cirros --file cirros-0.6.3-x86_64-disk.img --disk-format qcow2 --container-format bare
# glance image-create --name "cirros-10" --file cirros-0.6.3-x86_64-disk.img --disk-format qcow2 --container-format bare

# 列出镜像
# openstack image list

echo "Glance 已安装并配置完成。"
# CentOS 7.5 x86_64 XD
openstack image create "CentOS 7.5 x86_64 XD" --file CentOS_7.5_x86_64_XD.qcow2 --disk-format qcow2 --container-format bare --public

# CentOS 7 x86_64 2009
openstack image create "CentOS 7 x86_64 2009" --file CentOS-7-x86_64-2009.qcow2 --disk-format qcow2 --container-format bare --public

# CentOS 7 GenericCloud 2003
openstack image create "CentOS 7 GenericCloud 2003" --file CentOS-7-x86_64-GenericCloud-2003.qcow2 --disk-format qcow2 --container-format bare --public

# CentOS 6.5 x86_64 XD
openstack image create "CentOS 6.5 x86_64 XD" --file CentOS_6.5_x86_64_XD.qcow2 --disk-format qcow2 --container-format bare --public

# CentOS 7.2 x86_64 XD
openstack image create "CentOS 7.2 x86_64 XD" --file CentOS_7.2_x86_64_XD.qcow2 --disk-format qcow2 --container-format bare --public

# CentOS7 1804
openstack image create "CentOS7 1804" --file CentOS7-1804.qcow2 --disk-format qcow2 --container-format bare --public

# CirrOS 0.5.2
openstack image create "CirrOS 0.5.2" --file cirros-0.5.2-x86_64-disk.img --disk-format qcow2 --container-format bare --public

# CirrOS 0.6.3
openstack image create "CirrOS 0.6.3" --file cirros-0.6.3-x86_64-disk.img --disk-format qcow2 --container-format bare --public

# CirrOS 0.3.3
openstack image create "CirrOS 0.3.3" --file cirros-0.3.3-x86_64-disk.img --disk-format qcow2 --container-format bare --public

# CirrOS 0.3.4
openstack image create "CirrOS 0.3.4" --file cirros-0.3.4-x86_64-disk.img --disk-format qcow2 --container-format bare --public

# CirrOS 0.5.1
openstack image create "CirrOS 0.5.1" --file cirros-0.5.1-x86_64-disk.img --disk-format qcow2 --container-format bare --public

# Ubuntu Jammy (22.04 LTS)
openstack image create "Ubuntu Jammy" --file jammy-server-cloudimg-amd64.img --disk-format qcow2 --container-format bare --public

# Alpine Linux 3.20.3
openstack image create "Alpine Linux 3.20.3" --file alpine-standard-3.20.3-x86_64.iso --disk-format iso --container-format bare --public

# Amphora HAProxy
openstack image create "Amphora HAProxy" --file amphora-x64-haproxy.qcow2 --disk-format qcow2 --container-format bare --public

# MySQL 5.6 XD
openstack image create "MySQL 5.6 XD" --file MySQL_5.6_XD.qcow2 --disk-format qcow2 --container-format bare --public

# Windows Server 2012 R2
openstack image create "Windows Server 2012 R2" --file windows_server_2012_r2_standard_eval_kvm_20170321.qcow2 --disk-format qcow2 --container-format bare --public

Placement

Placement需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库 root 用户密码。例如,000000
DB_PASS=000000

# Placement 数据库密码。例如,000000
PLACEMENT_DBPASS=000000

# Placement 服务密码。例如,000000
PLACEMENT_PASS=000000

Placement脚本

install_placement.sh

#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

# 创建 Placement 数据库
mysql -uroot -p$DB_PASS -e "CREATE DATABASE IF NOT EXISTS placement;"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' IDENTIFIED BY '$PLACEMENT_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' IDENTIFIED BY '$PLACEMENT_DBPASS';"

# 创建 Placement 用户
openstack user create --domain default --password $PLACEMENT_PASS placement

# 添加 Placement 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user placement admin

# 创建 Placement 服务
openstack service create --name placement --description "Placement API" placement

# 创建 Placement 端点
openstack endpoint create --region RegionOne placement public http://$CONTROLLER_HOSTNAME:8778
openstack endpoint create --region RegionOne placement internal http://$CONTROLLER_HOSTNAME:8778
openstack endpoint create --region RegionOne placement admin http://$CONTROLLER_HOSTNAME:8778

# 安装 Placement
apt install -y placement-api

# 备份 Placement 配置文件
cp /etc/placement/placement.conf{,.bak}

# 使用 crudini 修改 Placement 配置文件
crudini --set /etc/placement/placement.conf placement_database connection "mysql+pymysql://placement:$PLACEMENT_DBPASS@$CONTROLLER_HOSTNAME/placement"
crudini --set /etc/placement/placement.conf api auth_strategy keystone
crudini --set /etc/placement/placement.conf keystone_authtoken auth_url "http://$CONTROLLER_HOSTNAME:5000/v3"
crudini --set /etc/placement/placement.conf keystone_authtoken memcached_servers "$CONTROLLER_HOSTNAME:11211"
crudini --set /etc/placement/placement.conf keystone_authtoken auth_type password
crudini --set /etc/placement/placement.conf keystone_authtoken project_domain_name Default
crudini --set /etc/placement/placement.conf keystone_authtoken user_domain_name Default
crudini --set /etc/placement/placement.conf keystone_authtoken project_name service
crudini --set /etc/placement/placement.conf keystone_authtoken username placement
crudini --set /etc/placement/placement.conf keystone_authtoken password $PLACEMENT_PASS

# 同步数据库
su -s /bin/sh -c "placement-manage db sync" placement

# 启用并重启 Web 服务
systemctl enable apache2 && systemctl restart apache2

# 验证
# placement-status upgrade check

echo "Placement 已安装并配置完成。"

Nova

Nova需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 控制节点管理网络接口地址。例如,192.168.10.10
CONTROLLER_MANAGEMENT_IP=192.168.10.225

# 计算节点主机名称。例如,compute1
COMPUTE_HOSTNAME=compute1

# 计算节点管理网络接口地址。例如,192.168.10.20
COMPUTE_MANAGEMENT_IP=192.168.10.22

# 数据库 root 用户密码。例如,000000
DB_PASS=000000

# 消息队列密码。例如,000000
RABBIT_PASS=000000

# Nova 数据库密码。例如,000000
NOVA_DBPASS=000000

# Nova 服务密码。例如,000000
NOVA_PASS=000000

Nova脚本

install_nova.sh

#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

# 创建 Nova 数据库
mysql -uroot -p$DB_PASS -e "CREATE DATABASE nova_api;"
mysql -uroot -p$DB_PASS -e "CREATE DATABASE nova;"
mysql -uroot -p$DB_PASS -e "CREATE DATABASE nova_cell0;"

mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY '$NOVA_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY '$NOVA_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY '$NOVA_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY '$NOVA_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY '$NOVA_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY '$NOVA_DBPASS';"

# 创建 Nova 用户
openstack user create --domain default --password $NOVA_PASS nova

# 添加 Nova 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user nova admin

# 创建 Nova 服务
openstack service create --name nova --description "OpenStack Compute" compute

# 创建 Nova 端点
openstack endpoint create --region RegionOne compute public http://$CONTROLLER_HOSTNAME:8774/v2.1
openstack endpoint create --region RegionOne compute internal http://$CONTROLLER_HOSTNAME:8774/v2.1
openstack endpoint create --region RegionOne compute admin http://$CONTROLLER_HOSTNAME:8774/v2.1

# 安装 Nova
apt install -y nova-api nova-conductor nova-novncproxy nova-scheduler

# 备份 Nova 配置文件
cp /etc/nova/nova.conf{,.bak}

# 使用 crudini 修改 Nova 配置文件
crudini --set /etc/nova/nova.conf api_database connection "mysql+pymysql://nova:$NOVA_DBPASS@$CONTROLLER_HOSTNAME/nova_api"
crudini --set /etc/nova/nova.conf database connection "mysql+pymysql://nova:$NOVA_DBPASS@$CONTROLLER_HOSTNAME/nova"
crudini --set /etc/nova/nova.conf DEFAULT transport_url "rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME:5672/"
crudini --set /etc/nova/nova.conf api auth_strategy keystone
crudini --set /etc/nova/nova.conf keystone_authtoken www_authenticate_uri "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf keystone_authtoken auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf keystone_authtoken memcached_servers "$CONTROLLER_HOSTNAME:11211"
crudini --set /etc/nova/nova.conf keystone_authtoken auth_type password
crudini --set /etc/nova/nova.conf keystone_authtoken project_domain_name Default
crudini --set /etc/nova/nova.conf keystone_authtoken user_domain_name Default
crudini --set /etc/nova/nova.conf keystone_authtoken project_name service
crudini --set /etc/nova/nova.conf keystone_authtoken username nova
crudini --set /etc/nova/nova.conf keystone_authtoken password $NOVA_PASS
crudini --set /etc/nova/nova.conf service_user send_service_user_token true
crudini --set /etc/nova/nova.conf service_user auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf service_user auth_strategy keystone
crudini --set /etc/nova/nova.conf service_user auth_type password
crudini --set /etc/nova/nova.conf service_user project_domain_name Default
crudini --set /etc/nova/nova.conf service_user project_name service
crudini --set /etc/nova/nova.conf service_user user_domain_name Default
crudini --set /etc/nova/nova.conf service_user username nova
crudini --set /etc/nova/nova.conf service_user password $NOVA_PASS
crudini --set /etc/nova/nova.conf DEFAULT my_ip $CONTROLLER_MANAGEMENT_IP
crudini --set /etc/nova/nova.conf vnc enabled true
crudini --set /etc/nova/nova.conf vnc server_listen $CONTROLLER_MANAGEMENT_IP
crudini --set /etc/nova/nova.conf vnc server_proxyclient_address $CONTROLLER_MANAGEMENT_IP
crudini --set /etc/nova/nova.conf glance api_servers "http://$CONTROLLER_HOSTNAME:9292"
crudini --set /etc/nova/nova.conf oslo_concurrency lock_path /var/lib/nova/tmp
crudini --set /etc/nova/nova.conf placement region_name RegionOne
crudini --set /etc/nova/nova.conf placement project_domain_name Default
crudini --set /etc/nova/nova.conf placement project_name service
crudini --set /etc/nova/nova.conf placement auth_type password
crudini --set /etc/nova/nova.conf placement user_domain_name Default
crudini --set /etc/nova/nova.conf placement auth_url "http://$CONTROLLER_HOSTNAME:5000/v3"
crudini --set /etc/nova/nova.conf placement username placement
crudini --set /etc/nova/nova.conf placement password $PLACEMENT_PASS

# 使用 crudini 修改 Nova 配置文件
crudini --set /etc/nova/nova.conf scheduler discover_hosts_in_cells_interval 300

# 同步数据库
su -s /bin/sh -c "nova-manage api_db sync" nova
su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
su -s /bin/sh -c "nova-manage db sync" nova
su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova

# 启用并重启 Compute 服务
systemctl enable nova-api && systemctl restart nova-api
systemctl enable nova-scheduler && systemctl restart nova-scheduler
systemctl enable nova-conductor && systemctl restart nova-conductor
systemctl enable nova-novncproxy && systemctl restart nova-novncproxy

## 验证
#openstack compute service list
#openstack catalog list
#nova-status upgrade check

echo "Nova Controller 已安装并配置完成。"

# env.sh 发送到 compute 节点

scp env.sh root@$COMPUTE_HOSTNAME:/root/

# 在计算节点上执行的操作
COMPUTE_SCRIPT=$(cat <<EOF
#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 安装 Nova
apt install -y nova-compute

# 备份 Nova 配置文件
cp /etc/nova/nova.conf{,.bak}

# 使用 crudini 修改 Nova 配置文件
crudini --set /etc/nova/nova.conf DEFAULT transport_url "rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME"
crudini --set /etc/nova/nova.conf api auth_strategy keystone
crudini --set /etc/nova/nova.conf keystone_authtoken www_authenticate_uri "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf keystone_authtoken auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf keystone_authtoken memcached_servers "$CONTROLLER_HOSTNAME:11211"
crudini --set /etc/nova/nova.conf keystone_authtoken auth_type password
crudini --set /etc/nova/nova.conf keystone_authtoken project_domain_name Default
crudini --set /etc/nova/nova.conf keystone_authtoken user_domain_name Default
crudini --set /etc/nova/nova.conf keystone_authtoken project_name service
crudini --set /etc/nova/nova.conf keystone_authtoken username nova
crudini --set /etc/nova/nova.conf keystone_authtoken password $NOVA_PASS
crudini --set /etc/nova/nova.conf service_user send_service_user_token true
crudini --set /etc/nova/nova.conf service_user auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf service_user auth_strategy keystone
crudini --set /etc/nova/nova.conf service_user auth_type password
crudini --set /etc/nova/nova.conf service_user project_domain_name Default
crudini --set /etc/nova/nova.conf service_user project_name service
crudini --set /etc/nova/nova.conf service_user user_domain_name Default
crudini --set /etc/nova/nova.conf service_user username nova
crudini --set /etc/nova/nova.conf service_user password $NOVA_PASS
crudini --set /etc/nova/nova.conf DEFAULT my_ip $COMPUTE_MANAGEMENT_IP
crudini --set /etc/nova/nova.conf vnc enabled true
crudini --set /etc/nova/nova.conf vnc server_listen 0.0.0.0
crudini --set /etc/nova/nova.conf vnc server_proxyclient_address $COMPUTE_MANAGEMENT_IP
crudini --set /etc/nova/nova.conf vnc novncproxy_base_url "http://$CONTROLLER_HOSTNAME:6080/vnc_auto.html"
crudini --set /etc/nova/nova.conf glance api_servers "http://$CONTROLLER_HOSTNAME:9292"
crudini --set /etc/nova/nova.conf oslo_concurrency lock_path /var/lib/nova/tmp
crudini --set /etc/nova/nova.conf placement region_name RegionOne
crudini --set /etc/nova/nova.conf placement project_domain_name Default
crudini --set /etc/nova/nova.conf placement project_name service
crudini --set /etc/nova/nova.conf placement auth_type password
crudini --set /etc/nova/nova.conf placement user_domain_name Default
crudini --set /etc/nova/nova.conf placement auth_url "http://$CONTROLLER_HOSTNAME:5000/v3"
crudini --set /etc/nova/nova.conf placement username placement
crudini --set /etc/nova/nova.conf placement password $PLACEMENT_PASS

# 确定您的计算节点是否支持硬件虚拟化
if [ \$(egrep -c '(vmx|svm)' /proc/cpuinfo) -eq 0 ]; then
  # 如果不支持硬件加速,则配置为使用 QEMU
  cp /etc/nova/nova-compute.conf{,.bak}
  crudini --set /etc/nova/nova-compute.conf libvirt virt_type qemu
fi

# 启用并重启 Compute 服务
systemctl enable nova-compute && systemctl restart nova-compute

echo "Nova Compute 已安装并配置完成。"
EOF
)

# 通过 SSH 执行计算节点脚本
#sshpass -p $COMPUTE_PASS ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME "bash -s" <<< "$COMPUTE_SCRIPT"
ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME "bash -s" <<< "$COMPUTE_SCRIPT"

# 在控制器节点上运行以下命令
openstack compute service list
su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova

# 验证
openstack compute service list
openstack catalog list
# nova-status upgrade check
# 通用型 flavors
openstack flavor create --vcpus 1 --ram 512 --disk 10 --public m1.nano
openstack flavor create --vcpus 1 --ram 1024 --disk 20 --public m1.micro
openstack flavor create --vcpus 1 --ram 2048 --disk 40 --public m1.small
openstack flavor create --vcpus 2 --ram 4096 --disk 80 --public m1.medium
openstack flavor create --vcpus 4 --ram 8192 --disk 160 --public m1.large
openstack flavor create --vcpus 8 --ram 16384 --disk 320 --public m1.xlarge

# 计算优化型 flavors
openstack flavor create --vcpus 4 --ram 4096 --disk 80 --public c1.small
openstack flavor create --vcpus 8 --ram 8192 --disk 160 --public c1.medium
openstack flavor create --vcpus 16 --ram 16384 --disk 320 --public c1.large
openstack flavor create --vcpus 32 --ram 32768 --disk 640 --public c1.xlarge

# 内存优化型 flavors
openstack flavor create --vcpus 2 --ram 8192 --disk 80 --public r1.small
openstack flavor create --vcpus 4 --ram 16384 --disk 160 --public r1.medium
openstack flavor create --vcpus 8 --ram 32768 --disk 320 --public r1.large
openstack flavor create --vcpus 16 --ram 65536 --disk 640 --public r1.xlarge

# 存储优化型 flavors
openstack flavor create --vcpus 2 --ram 4096 --disk 200 --public d1.small
openstack flavor create --vcpus 4 --ram 8192 --disk 400 --public d1.medium
openstack flavor create --vcpus 8 --ram 16384 --disk 800 --public d1.large
openstack flavor create --vcpus 16 --ram 32768 --disk 1600 --public d1.xlarge

Neutron

Neutron需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库 root 用户密码。例如,000000
DB_PASS=000000

# 消息队列密码。例如,000000
RABBIT_PASS=000000

# Neutron 数据库密码。例如,000000
NEUTRON_DBPASS=000000

# Neutron 服务密码。例如,000000
NEUTRON_PASS=000000

# 提供者网络的 OVS 桥接名称。例如,provider
PROVIDER_BRIDGE_NAME=provider

# CONTROLLERP节点的提供者网络接口的名称。例如,eth1,ens34
CONTROLLER_PROVIDER_INTERFACE_NAME=eth1

# CONTROLLERP节点用于 VXLAN 隧道的本地 IP 地址,提供者网络IP地址。例如,192.168.20.10
CONTROLLERP_ROVIDER_INTERFACE_IP=192.168.20.139

# COMPUTE节点的提供者网络接口的名称。例如,eth1,ens34
COMPUTE_PROVIDER_INTERFACE_NAME=eth1

# CONTROLLERP节点用于 VXLAN 隧道的本地 IP 地址,提供者网络IP地址。例如,192.168.20.20
COMPUTE_ROVIDER_INTERFACE_IP=192.168.20.52

# 用于元数据代理的共享密钥。例如,000000
METADATA_SECRET_PASS=000000

Neutron脚本

install_neutron.sh

#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

# 创建 Neutron 数据库
mysql -uroot -p$DB_PASS -e "CREATE DATABASE neutron;"

mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY '$NEUTRON_DBPASS'"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY '$NEUTRON_DBPASS';"

# 创建 Neutron 用户
openstack user create --domain default --password $NEUTRON_PASS neutron

# 添加 Neutron 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user neutron admin

# 创建 Neutron 服务
openstack service create --name neutron --description "OpenStack Networking" network

# 创建 Neutron 端点
openstack endpoint create --region RegionOne network public http://$CONTROLLER_HOSTNAME:9696
openstack endpoint create --region RegionOne network internal http://$CONTROLLER_HOSTNAME:9696
openstack endpoint create --region RegionOne network admin http://$CONTROLLER_HOSTNAME:9696

# 安装 Neutron
apt install -y neutron-server neutron-plugin-ml2 neutron-openvswitch-agent neutron-l3-agent neutron-dhcp-agent neutron-metadata-agent

# 备份 Neutron 配置文件
cp /etc/neutron/neutron.conf{,.bak}

# 使用 crudini 修改 Neutron 配置文件
crudini --set /etc/neutron/neutron.conf database connection "mysql+pymysql://neutron:$NEUTRON_DBPASS@$CONTROLLER_HOSTNAME/neutron"
crudini --set /etc/neutron/neutron.conf DEFAULT core_plugin ml2
crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins router
crudini --set /etc/neutron/neutron.conf DEFAULT transport_url "rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME"
crudini --set /etc/neutron/neutron.conf DEFAULT auth_strategy keystone
crudini --set /etc/neutron/neutron.conf keystone_authtoken www_authenticate_uri "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/neutron/neutron.conf keystone_authtoken memcached_servers "$CONTROLLER_HOSTNAME:11211"
crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_type password
crudini --set /etc/neutron/neutron.conf keystone_authtoken project_domain_name Default
crudini --set /etc/neutron/neutron.conf keystone_authtoken user_domain_name Default
crudini --set /etc/neutron/neutron.conf keystone_authtoken project_name service
crudini --set /etc/neutron/neutron.conf keystone_authtoken username neutron
crudini --set /etc/neutron/neutron.conf keystone_authtoken password $NEUTRON_PASS
crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_status_changes true
crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_data_changes true
crudini --set /etc/neutron/neutron.conf nova auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/neutron/neutron.conf nova auth_type password
crudini --set /etc/neutron/neutron.conf nova project_domain_name Default
crudini --set /etc/neutron/neutron.conf nova user_domain_name Default
crudini --set /etc/neutron/neutron.conf nova region_name RegionOne
crudini --set /etc/neutron/neutron.conf nova project_name service
crudini --set /etc/neutron/neutron.conf nova username nova
crudini --set /etc/neutron/neutron.conf nova password $NOVA_PASS
crudini --set /etc/neutron/neutron.conf oslo_concurrency lock_path /var/lib/neutron/tmp

# 创建 OVS 桥接
ovs-vsctl add-br $PROVIDER_BRIDGE_NAME
ovs-vsctl add-port $PROVIDER_BRIDGE_NAME $CONTROLLER_PROVIDER_INTERFACE_NAME

# 备份 Neutron 配置文件
cp /etc/neutron/plugins/ml2/ml2_conf.ini{,.bak}

# 使用 crudini 修改 Neutron 配置文件
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 type_drivers flat,vlan,vxlan
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types vxlan
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 mechanism_drivers openvswitch,l2population
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 extension_drivers port_security
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_flat flat_networks provider
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_vxlan vni_ranges 1:1000
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs bridge_mappings provider:$PROVIDER_BRIDGE_NAME
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs local_ip $CONTROLLER_PROVIDER_INTERFACE_IP
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini agent tunnel_types vxlan
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini agent l2_population true
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup enable_security_group true
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup firewall_driver openvswitch

# 备份 Neutron 配置文件
cp /etc/neutron/l3_agent.ini{,.bak}

# 使用 crudini 修改 Neutron 配置文件
crudini --set /etc/neutron/l3_agent.ini DEFAULT interface_driver openvswitch
crudini --set /etc/neutron/l3_agent.ini DEFAULT dhcp_driver neutron.agent.linux.dhcp.Dnsmasq
crudini --set /etc/neutron/l3_agent.ini DEFAULT enable_isolated_metadata true

# 备份 Neutron 配置文件
cp /etc/neutron/dhcp_agent.ini{,.bak}

# 使用 crudini 修改 Neutron 配置文件
crudini --set /etc/neutron/dhcp_agent.ini DEFAULT interface_driver openvswitch
crudini --set /etc/neutron/dhcp_agent.ini DEFAULT dhcp_driver neutron.agent.linux.dhcp.Dnsmasq
crudini --set /etc/neutron/dhcp_agent.ini DEFAULT enable_isolated_metadata true

# 备份 Neutron 配置文件
cp /etc/neutron/metadata_agent.ini{,.bak}

# 使用 crudini 修改 Neutron 配置文件
crudini --set /etc/neutron/metadata_agent.ini DEFAULT nova_metadata_host $CONTROLLER_HOSTNAME
crudini --set /etc/neutron/metadata_agent.ini DEFAULT metadata_proxy_shared_secret $METADATA_SECRET_PASS

# 备份 Neutron 配置文件
cp /etc/nova/nova.conf{,.bak}

# 使用 crudini 修改 Nova 配置文件
crudini --set /etc/nova/nova.conf neutron auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf neutron auth_type password
crudini --set /etc/nova/nova.conf neutron project_domain_name Default
crudini --set /etc/nova/nova.conf neutron user_domain_name Default
crudini --set /etc/nova/nova.conf neutron region_name RegionOne
crudini --set /etc/nova/nova.conf neutron project_name service
crudini --set /etc/nova/nova.conf neutron username neutron
crudini --set /etc/nova/nova.conf neutron password $NEUTRON_PASS
crudini --set /etc/nova/nova.conf neutron service_metadata_proxy true
crudini --set /etc/nova/nova.conf neutron metadata_proxy_shared_secret $METADATA_SECRET_PASS

# 同步数据库
su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron

# 启用并重启 Compute Neutron 服务
systemctl enable nova-api && systemctl restart nova-api

systemctl enable neutron-server && systemctl restart neutron-server
systemctl enable neutron-openvswitch-agent && systemctl restart neutron-openvswitch-agent
systemctl enable neutron-dhcp-agent && systemctl restart neutron-dhcp-agent
systemctl enable neutron-metadata-agent && systemctl restart neutron-metadata-agent
systemctl enable neutron-l3-agent && systemctl restart neutron-l3-agent

echo "Neutron Controller 已安装并配置完成。"

# env.sh 发送到 compute 节点
scp env.sh root@$COMPUTE_HOSTNAME:/root/

# 在计算节点上执行的操作
COMPUTE_SCRIPT=$(cat <<EOF
#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 安装 Neutron
apt install -y neutron-openvswitch-agent

# 备份 Neutron 配置文件
cp /etc/neutron/neutron.conf{,.bak}

# 使用 crudini 修改 Neutron 配置文件
crudini --set /etc/neutron/neutron.conf DEFAULT transport_url "rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME"
crudini --set /etc/neutron/neutron.conf oslo_concurrency lock_path /var/lib/neutron/tmp

# 创建 OVS 桥接
ovs-vsctl add-br $PROVIDER_BRIDGE_NAME
ovs-vsctl add-port $PROVIDER_BRIDGE_NAME $COMPUTE_PROVIDER_INTERFACE_NAME

# 备份 Neutron 配置文件
cp /etc/neutron/plugins/ml2/openvswitch_agent.ini{,.bak}

# 使用 crudini 修改 Neutron 配置文件
crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs bridge_mappings provider:$PROVIDER_BRIDGE_NAME
crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs local_ip $COMPUTE_PROVIDER_INTERFACE_IP
crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini agent tunnel_types vxlan
crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini agent l2_population true
crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini securitygroup enable_security_group true
crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini securitygroup firewall_driver openvswitch

# 备份 Neutron 配置文件
cp /etc/nova/nova.conf{,.bak}

# 使用 crudini 修改 Nova 配置文件
crudini --set /etc/nova/nova.conf neutron auth_url "http://$CONTROLLER_HOSTNAME:5000/"
crudini --set /etc/nova/nova.conf neutron auth_type password
crudini --set /etc/nova/nova.conf neutron project_domain_name Default
crudini --set /etc/nova/nova.conf neutron user_domain_name Default
crudini --set /etc/nova/nova.conf neutron region_name RegionOne
crudini --set /etc/nova/nova.conf neutron project_name service
crudini --set /etc/nova/nova.conf neutron username neutron
crudini --set /etc/nova/nova.conf neutron password $NEUTRON_PASS

# 启用并重启 Compute Neutron 服务
systemctl enable nova-compute && systemctl restart nova-compute
systemctl enable neutron-openvswitch-agent && systemctl restart neutron-openvswitch-agent

echo "Neutron Compute 已安装并配置完成。"
EOF
)

# 通过 SSH 执行计算节点脚本
ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME "bash -s" <<< "$COMPUTE_SCRIPT"

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

# 验证
openstack extension list --network
openstack network agent list
mysql -uroot -p$DB_PASS -e "CREATE DATABASE neutron;"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY '$NEUTRON_DBPASS'"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY '$NEUTRON_DBPASS';"

openstack user create --domain default --password $NEUTRON_PASS neutron
openstack role add --project service --user neutron admin
openstack service create --name neutron --description "OpenStack Networking" network

openstack endpoint create --region RegionOne network public http://$CONTROLLER_HOSTNAME:9696
openstack endpoint create --region RegionOne network internal http://$CONTROLLER_HOSTNAME:9696
openstack endpoint create --region RegionOne network admin http://$CONTROLLER_HOSTNAME:9696

apt -y install neutron-server neutron-plugin-ml2 python3-neutronclient ovn-central openvswitch-switch

cp /etc/neutron/neutron.conf{,.bak}

crudini --set /etc/neutron/neutron.conf DEFAULT bind_host $CONTROLLER_HOSTNAME
crudini --set /etc/neutron/neutron.conf DEFAULT bind_port 9696
crudini --set /etc/neutron/neutron.conf DEFAULT core_plugin ml2
crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins ovn-router
crudini --set /etc/neutron/neutron.conf DEFAULT auth_strategy keystone
crudini --set /etc/neutron/neutron.conf DEFAULT state_path /var/lib/neutron
crudini --set /etc/neutron/neutron.conf DEFAULT allow_overlapping_ips True
crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_status_changes True
crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_data_changes True
crudini --set /etc/neutron/neutron.conf DEFAULT transport_url "rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME"

crudini --set /etc/neutron/neutron.conf agent root_helper '"sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf"'

crudini --set /etc/neutron/neutron.conf database connection "mysql+pymysql://neutron:$NEUTRON_DBPASS@$CONTROLLER_HOSTNAME/neutron"

crudini --set /etc/neutron/neutron.conf keystone_authtoken www_authenticate_uri "http://$CONTROLLER_HOSTNAME:5000"
crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_url "http://$CONTROLLER_HOSTNAME:5000"
crudini --set /etc/neutron/neutron.conf keystone_authtoken memcached_servers $CONTROLLER_HOSTNAME:11211
crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_type password
crudini --set /etc/neutron/neutron.conf keystone_authtoken project_domain_name Default
crudini --set /etc/neutron/neutron.conf keystone_authtoken user_domain_name Default
crudini --set /etc/neutron/neutron.conf keystone_authtoken project_name service
crudini --set /etc/neutron/neutron.conf keystone_authtoken username neutron
crudini --set /etc/neutron/neutron.conf keystone_authtoken password $NEUTRON_PASS

crudini --set /etc/neutron/neutron.conf nova auth_url "http://$CONTROLLER_HOSTNAME:5000"
crudini --set /etc/neutron/neutron.conf nova auth_type password
crudini --set /etc/neutron/neutron.conf nova project_domain_name Default
crudini --set /etc/neutron/neutron.conf nova user_domain_name Default
crudini --set /etc/neutron/neutron.conf nova region_name RegionOne
crudini --set /etc/neutron/neutron.conf nova project_name service
crudini --set /etc/neutron/neutron.conf nova username nova
crudini --set /etc/neutron/neutron.conf nova password $NOVA_PASS

crudini --set /etc/neutron/neutron.conf oslo_concurrency lock_path /var/lib/neutron/tmp

cp /etc/neutron/plugins/ml2/ml2_conf.ini{,.bak}

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini DEFAULT debug false

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 type_drivers flat,geneve
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types geneve
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 mechanism_drivers ovn
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 extension_drivers port_security
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 overlay_ip_version 4

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_flat flat_networks '*'

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_geneve vni_ranges 1:65536
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_geneve max_header_size 38

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_nb_connection tcp:$CONTROLLER_MANAGEMENT_IP:6641
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_sb_connection tcp:$CONTROLLER_MANAGEMENT_IP:6642
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_l3_scheduler leastloaded
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_metadata_enabled True

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup enable_security_group True
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup firewall_driver neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

cp /etc/nova/nova.conf{,.bak2}

crudini --set /etc/nova/nova.conf neutron auth_url http://$CONTROLLER_HOSTNAME:5000
crudini --set /etc/nova/nova.conf neutron auth_type password
crudini --set /etc/nova/nova.conf neutron project_domain_name Default
crudini --set /etc/nova/nova.conf neutron user_domain_name Default
crudini --set /etc/nova/nova.conf neutron region_name RegionOne
crudini --set /etc/nova/nova.conf neutron project_name service
crudini --set /etc/nova/nova.conf neutron username neutron
crudini --set /etc/nova/nova.conf neutron password $NEUTRON_PASS
crudini --set /etc/nova/nova.conf neutron service_metadata_proxy True
crudini --set /etc/nova/nova.conf neutron metadata_proxy_shared_secret ws
crudini --set /etc/nova/nova.conf neutron insecure false

cp /etc/default/openvswitch-switch{,.bak}

cat << EOF >> /etc/default/openvswitch-switch
OVS_CTL_OPTS="--ovsdb-server-options='--remote=ptcp:6640:127.0.0.1'"
EOF

su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron

service nova-api restart
systemctl restart openvswitch-switch
systemctl enable openvswitch-switch

ovs-vsctl add-br $PROVIDER_BRIDGE_NAME

systemctl restart ovn-central ovn-northd
systemctl enable ovn-central ovn-northd
ovn-nbctl set-connection ptcp:6641:$CONTROLLER_MANAGEMENT_IP -- set connection . inactivity_probe=60000
ovn-sbctl set-connection ptcp:6642:$CONTROLLER_MANAGEMENT_IP -- set connection . inactivity_probe=60000

ovs-vsctl add-br $PROVIDER_BRIDGE_NAME
ovs-vsctl add-port $PROVIDER_BRIDGE_NAME $CONTROLLER_PROVIDER_INTERFACE_NAME

ovs-vsctl set open . external-ids:ovn-bridge-mappings=physnet1:$PROVIDER_BRIDGE_NAME

service neutron-server restart

scp env.sh root@$COMPUTE_HOSTNAME:/root/

COMPUTE_SCRIPT=$(cat <<EOF
#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

apt -y install neutron-common neutron-plugin-ml2 neutron-ovn-metadata-agent ovn-host openvswitch-switch

cp /etc/neutron/neutron.conf{,.bak}

crudini --set /etc/neutron/neutron.conf DEFAULT core_plugin ml2
crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins ovn-router
crudini --set /etc/neutron/neutron.conf DEFAULT auth_strategy keystone
crudini --set /etc/neutron/neutron.conf DEFAULT state_path /var/lib/neutron
crudini --set /etc/neutron/neutron.conf DEFAULT allow_overlapping_ips True
crudini --set /etc/neutron/neutron.conf DEFAULT transport_url "rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME"

crudini --set /etc/neutron/neutron.conf agent root_helper '"sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf"'

crudini --set /etc/neutron/neutron.conf keystone_authtoken www_authenticate_uri "http://$CONTROLLER_HOSTNAME:5000"
crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_url "http://$CONTROLLER_HOSTNAME:5000"
crudini --set /etc/neutron/neutron.conf keystone_authtoken memcached_servers $CONTROLLER_HOSTNAME:11211
crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_type password
crudini --set /etc/neutron/neutron.conf keystone_authtoken project_domain_name Default
crudini --set /etc/neutron/neutron.conf keystone_authtoken user_domain_name Default
crudini --set /etc/neutron/neutron.conf keystone_authtoken project_name service
crudini --set /etc/neutron/neutron.conf keystone_authtoken username neutron
crudini --set /etc/neutron/neutron.conf keystone_authtoken password $NEUTRON_PASS

crudini --set /etc/neutron/neutron.conf oslo_concurrency lock_path /var/lib/neutron/tmp

cp /etc/neutron/plugins/ml2/ml2_conf.ini{,.bak}

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini DEFAULT debug false

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 type_drivers flat,geneve
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types geneve
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 mechanism_drivers ovn
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 extension_drivers port_security
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 overlay_ip_version 4

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_flat flat_networks '*'

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_geneve vni_ranges 1:65536
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_geneve max_header_size 38

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_nb_connection tcp:$CONTROLLER_MANAGEMENT_IP:6641
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_sb_connection tcp:$CONTROLLER_MANAGEMENT_IP:6642
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_l3_scheduler leastloaded
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovn ovn_metadata_enabled True

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup enable_security_group True
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup firewall_driver neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

cp /etc/neutron/neutron_ovn_metadata_agent.ini{,.bak}

crudini --set /etc/neutron/neutron_ovn_metadata_agent.ini DEFAULT nova_metadata_host $CONTROLLER_HOSTNAME
crudini --set /etc/neutron/neutron_ovn_metadata_agent.ini DEFAULT nova_metadata_protocol http
crudini --set /etc/neutron/neutron_ovn_metadata_agent.ini DEFAULT metadata_proxy_shared_secret ws
crudini --set /etc/neutron/neutron_ovn_metadata_agent.ini ovs ovsdb_connection tcp:127.0.0.1:6640
crudini --set /etc/neutron/neutron_ovn_metadata_agent.ini agent root_helper "sudo neutron-rootwrap /etc/neutron/rootwrap.conf"
crudini --set /etc/neutron/neutron_ovn_metadata_agent.ini ovn ovn_sb_connection tcp:$CONTROLLER_MANAGEMENT_IP:6642

cp /etc/nova/nova.conf{,.bak2}

crudini --set /etc/nova/nova.conf neutron auth_url http://$CONTROLLER_HOSTNAME:5000
crudini --set /etc/nova/nova.conf neutron auth_type password
crudini --set /etc/nova/nova.conf neutron project_domain_name Default
crudini --set /etc/nova/nova.conf neutron user_domain_name Default
crudini --set /etc/nova/nova.conf neutron region_name RegionOne
crudini --set /etc/nova/nova.conf neutron project_name service
crudini --set /etc/nova/nova.conf neutron username neutron
crudini --set /etc/nova/nova.conf neutron password $NEUTRON_PASS
crudini --set /etc/nova/nova.conf neutron service_metadata_proxy True
crudini --set /etc/nova/nova.conf neutron metadata_proxy_shared_secret ws
crudini --set /etc/nova/nova.conf neutron insecure false

cp /etc/default/openvswitch-switch{,.bak}

cat << EOF >> /etc/default/openvswitch-switch
OVS_CTL_OPTS="--ovsdb-server-options='--remote=ptcp:6640:127.0.0.1'"
EOF

systemctl enable openvswitch-switch ovn-controller ovn-host
systemctl enable neutron-ovn-metadata-agent
systemctl enable nova-compute

systemctl restart openvswitch-switch ovn-controller ovn-host
systemctl restart neutron-ovn-metadata-agent
systemctl restart nova-compute

ovs-vsctl set open . external-ids:ovn-remote=tcp:$CONTROLLER_MANAGEMENT_IP:6642
ovs-vsctl set open . external-ids:ovn-encap-type=geneve
ovs-vsctl set open . external-ids:ovn-encap-ip=$COMPUTE_MANAGEMENT_IP

ovs-vsctl add-br $PROVIDER_BRIDGE_NAME
ovs-vsctl add-port $PROVIDER_BRIDGE_NAME $COMPUTE_PROVIDER_INTERFACE_NAME

ovs-vsctl set open . external-ids:ovn-bridge-mappings=physnet1:$PROVIDER_BRIDGE_NAME

systemctl enable openvswitch-switch ovn-controller ovn-host
systemctl enable neutron-ovn-metadata-agent
systemctl enable nova-compute

systemctl restart openvswitch-switch ovn-controller ovn-host
systemctl restart neutron-ovn-metadata-agent
systemctl restart nova-compute

echo "Neutron Compute 已安装并配置完成。"
EOF
)

vim /usr/lib/python3/dist-packages/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb

service neutron-server restart
# 创建外部网络
openstack network create --share --external --provider-network-type flat --provider-physical-network physnet1 external_network

# 创建外部网络的子网
openstack subnet create --network external_network --subnet-range 192.168.200.0/24 --gateway 192.168.200.1 external_subnet

# 创建第一个内部网络 (GENEVE),并指定VNI
openstack network create --provider-network-type geneve --provider:segmentation-id 1001 internal_network1

# 创建第一个内部网络的子网
openstack subnet create --network internal_network1 --subnet-range 172.16.10.0/24 --gateway 172.16.10.1 internal_subnet1

# 创建第二个内部网络 (GENEVE),并指定VNI
openstack network create --provider-network-type geneve --provider:segmentation-id 1002 internal_network2

# 创建第二个内部网络的子网
openstack subnet create --network internal_network2 --subnet-range 172.16.20.0/24 --gateway 172.16.20.1 internal_subnet2

# 创建路由器
openstack router create my_router

# 将路由器连接到外部网络
openstack router set --external-gateway external_network my_router

# 将路由器连接到第一个内部网络
openstack router add subnet my_router internal_subnet1

# 将路由器连接到第二个内部网络
openstack router add subnet my_router internal_subnet2

# 一次性为所有协议添加入站规则
openstack security group rule create --proto icmp default
openstack security group rule create --proto tcp --dst-port 1:65535 default
openstack security group rule create --proto udp --dst-port 1:65535 default

# 一次性为所有协议添加出站规则
openstack security group rule create --egress --proto icmp default
openstack security group rule create --egress --proto tcp --dst-port 1:65535 default
openstack security group rule create --egress --proto udp --dst-port 1:65535 default

Horizon

Horizon需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

Horizon脚本

install_horizon.sh

#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

# 安装 OpenStack Dashboard
apt install -y openstack-dashboard

# 备份 local_settings.py 文件
cp /etc/openstack-dashboard/local_settings.py{,.bak}

# 修改 local_settings.py 文件
# 取消注释并更新或添加 OPENSTACK_HOST
sed -i '/^OPENSTACK_HOST = /c\OPENSTACK_HOST = "controller"' /etc/openstack-dashboard/local_settings.py

# 取消注释并更新或添加 ALLOWED_HOSTS
sed -i '/^# *ALLOWED_HOSTS = /c\ALLOWED_HOSTS = ["*"]' /etc/openstack-dashboard/local_settings.py

# 取消注释并更新或添加 SESSION_ENGINE
sed -i '/^# *SESSION_ENGINE = /c\SESSION_ENGINE = "django.contrib.sessions.backends.cache"' /etc/openstack-dashboard/local_settings.py

# 取消注释并更新或添加 CACHES
sed -i '/^CACHES = {/,/^}/c\CACHES = {\n    "default": {\n        "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",\n        "LOCATION": "controller:11211",\n    }\n}' /etc/openstack-dashboard/local_settings.py

# 取消注释并更新或添加 OPENSTACK_KEYSTONE_URL
sed -i 's/^OPENSTACK_KEYSTONE_URL = .*/OPENSTACK_KEYSTONE_URL = "http:\/\/%s:5000\/v3" % OPENSTACK_HOST/' /etc/openstack-dashboard/local_settings.py

# 取消注释并更新或添加 TIME_ZONE
sed -i '/^TIME_ZONE = /c\TIME_ZONE = "Asia/Shanghai"' /etc/openstack-dashboard/local_settings.py

cat  >> /etc/openstack-dashboard/local_settings.py << EOF
OPENSTACK_API_VERSIONS = {
    "identity": 3,
    "image": 2,
    "volume": 3,
}

OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default"

OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"

EOF

# 备份 openstack-dashboard.conf 文件
cp /etc/apache2/conf-available/openstack-dashboard.conf{,.bak}

# 启用并重启 Web 服务
systemctl enable apache2 && systemctl restart apache2

# 验证
placement-status upgrade check

echo "Horizon 已安装并配置完成。"
#cloud-config
chpasswd:
  list: |
    ubuntu:000000
  expire: False
root@controller:~# openstack resource provider inventory list 7ded31bd-ebca-4dfb-917d-c8d29e450d91
+----------------+------------------+----------+----------+----------+-----------+--------+------+
| resource_class | allocation_ratio | min_unit | max_unit | reserved | step_size |  total | used |
+----------------+------------------+----------+----------+----------+-----------+--------+------+
| VCPU           |              4.0 |        1 |       40 |        0 |         1 |     40 |    9 |
| MEMORY_MB      |              1.0 |        1 |   257795 |      512 |         1 | 257795 | 8704 |
| DISK_GB        |              1.0 |        1 |    40795 |        0 |         1 |  40795 |  170 |
+----------------+------------------+----------+----------+----------+-----------+--------+------+
root@controller:~# openstack resource provider usage show 7ded31bd-ebca-4dfb-917d-c8d29e450d91
+----------------+-------+
| resource_class | usage |
+----------------+-------+
| VCPU           |     9 |
| MEMORY_MB      |  8704 |
| DISK_GB        |   170 |
+----------------+-------+

openstack resource provider inventory list 输出字段解释
1. resource_class
描述:表示资源的类别,即该资源提供者可以提供的资源类型。
示例值:
VCPU:虚拟CPU的数量。
MEMORY_MB:内存大小,以MB为单位。
DISK_GB:磁盘空间大小,以GB为单位。
2. allocation_ratio
描述:分配比例(也称为超分比例),是指定资源类别的超额分配因子。例如,如果设置为4.0,则理论上可以分配4倍于实际物理资源的虚拟资源。
示例值:
VCPU 的 allocation_ratio 是 4.0,意味着可以在物理上40个VCPU的基础上分配最多160个VCPU(40 * 4)。
MEMORY_MB 和 DISK_GB 的 allocation_ratio 是 1.0,表示不进行超额分配。
3. min_unit
描述:每次分配时该资源类别的最小单位。这是创建实例时可分配的最小资源量。
示例值:对于所有资源类别,通常最小单位是1。
4. max_unit
描述:每次分配时该资源类别的最大单位。这是创建实例时可分配的最大资源量。
示例值:
VCPU 的 max_unit 是 40,意味着单次分配最多可以使用40个VCPU。
MEMORY_MB 的 max_unit 是 257795 MB。
DISK_GB 的 max_unit 是 40795 GB。
5. reserved
描述:为系统保留的资源数量,确保在任何情况下都至少有这么多资源可用。
示例值:
MEMORY_MB 的 reserved 是 512 MB,这意味着总是会保留512 MB的内存供系统使用。
其他资源类别的 reserved 值为0,表示没有特别预留。
6. step_size
描述:增量步长,即每次分配或释放资源时的最小变化单位。这决定了资源分配的粒度。
示例值:对于所有资源类别,通常步长是1。
7. total
描述:该资源提供者的总资源量,即物理硬件上的资源总数。
示例值:
VCPU 的 total 是 40,表示共有40个VCPU。
MEMORY_MB 的 total 是 257795 MB。
DISK_GB 的 total 是 40795 GB。
8. used
描述:当前已使用的资源量。
示例值:
VCPU 的 used 是 9,表示当前已经分配了9个VCPU。
MEMORY_MB 的 used 是 8704 MB。
DISK_GB 的 used 是 170 GB。
openstack resource provider usage show 输出字段解释
1. resource_class
描述:同上,表示资源的类别。
2. usage
描述:当前已使用的资源量,与inventory list中的used字段相同。
示例值:
VCPU 的 usage 是 9。
MEMORY_MB 的 usage 是 8704 MB。
DISK_GB 的 usage 是 170 GB。
计算剩余资源
为了计算剩余资源,你可以从total中减去used和reserved:

剩余VCPU = 总VCPU - 已用VCPU - 预留VCPU = 40 - 9 - 0 = 31
剩余内存 (MB) = 总内存 - 已用内存 - 预留内存 = 257795 - 8704 - 512 = 248579 MB
剩余磁盘 (GB) = 总磁盘 - 已用磁盘 - 预留磁盘 = 40795 - 170 - 0 = 40625 GB

Ceilometer

数据来源(Notifications/Polling/REST API)

→ RabbitMQ(仅Notifications数据)

→ Ceilometer(Notification Agent处理Notifications,Polling Agent采集数据)

→ Pipeline处理(Transformers过滤/聚合,Publishers分发)

→ Gnocchi(默认存储后端)

→ Gnocchi API(提供查询接口)

→ Grafana(通过插件对接,可视化展示)

数据来源如(glance,nova)

配置文件,设置数据传输。

Ceilometer数据收集。

通过yaml文件定义采集那些数据。

gnocchi后端存储。

安装需要

  1. Incoming Measure Storage(新接收度量存储)
    • 这个组件负责存储新接收到的原始度量数据。Gnocchi 在接收到新的度量数据后,会先将其存储在这里,然后再进行聚合处理。
    • 可用的驱动包括:
      • File:默认驱动,将数据存储在本地文件系统中。
      • Ceph:使用 Ceph 对象存储来存储数据。
      • OpenStack Swift:使用 OpenStack Swift 对象存储。
      • Amazon S3:使用 Amazon S3 对象存储。
      • Redis:使用 Redis 作为临时存储。
  2. Aggregated Metric Storage(聚合度量存储)
    • 这个组件负责存储经过聚合处理后的度量数据。Gnocchi 会对新接收到的数据进行聚合计算,并将结果存储在这个存储中。
    • 可用的驱动与 Incoming Measure Storage 类似,包括:
      • File:默认驱动,将数据存储在本地文件系统中。
      • Ceph:使用 Ceph 对象存储来存储数据。
      • OpenStack Swift:使用 OpenStack Swift 对象存储。
      • Amazon S3:使用 Amazon S3 对象存储。
      • Redis:使用 Redis 作为临时存储。
  3. Index(索引)
    • 这个组件负责存储资源和度量的元数据,例如资源的定义、类型、属性以及度量之间的关系。
    • 可用的驱动包括:
      • PostgreSQL:推荐使用的数据库,用于索引。
      • MySQL:至少需要版本 5.6.4 或更高版本。
  • 协调 URL (Coordination URL):在 Gnocchi 的配置文件中,可以看到 coordination_url = redis://controller:6379。这是一个可选配置,用于提高工作负载分配的性能。如果没有 Redis 服务,可以考虑不配置它,但推荐部署一个 Redis 服务来优化性能。

Gnocchi中有四层数据,Resource Type -> Resources -> Metric -> Measure

Resource Type 资源种类。资源的名称,种类,(如实例类型)

Resources 资源。存在的资源,(如实例)

Metric 资源度量。存在的资源的下属属性,(如实例的cpu,ram,disk)

Measure资源测量值。存在的资源的属性的详细值,(如实例的cpu在某个时段的占用)

grafana前端展示,要使用gnocchi插件,版本3-6之间的,高了低了都不行。

向gnocchi请求数据并展示,请求数据需要API认证所以说还需要keystone认证。

所以说需要keystone API 和 gnocchi API。

aodh通知。

Ceilometer需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库 root 用户密码。例如,000000
DB_PASS=000000

# Gnocchi 数据库密码。例如,000000
GNOCCHI_DBPASS=000000

# Gnocchi 服务密码。例如,000000
GNOCCHI_PASS=000000

# Ceilometer 服务密码。例如,000000
CEILOMETER_PASS=000000

Ceilometer脚本

install_ceilometer.sh

#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

# 创建 Placement 数据库
mysql -uroot -p$DB_PASS -e "CREATE DATABASE IF NOT EXISTS gnocchi;"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'localhost' IDENTIFIED BY '$GNOCCHI_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'%' IDENTIFIED BY '$GNOCCHI_DBPASS';"

# 创建 ceilometer 用户
openstack user create --domain default --password $CEILOMETER_PASS ceilometer

# 添加 ceilometer 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user ceilometer admin

# 创建 ceilometer 服务
# openstack service create --name ceilometer --description "Telemetry" metering

# 创建 gnocchi 用户
openstack user create --domain default --password $GNOCCHI_PASS gnocchi

# 添加 gnocchi 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user gnocchi admin

# 创建 gnocchi 服务
openstack service create --name gnocchi --description "Metric Service" metric

# 创建 gnocchi 端点
openstack endpoint create --region RegionOne metric public http://$CONTROLLER_HOSTNAME:8041
openstack endpoint create --region RegionOne metric internal http://$CONTROLLER_HOSTNAME:8041
openstack endpoint create --region RegionOne metric admin http://$CONTROLLER_HOSTNAME:8041

# 安装 redis 
apt install -y redis
pip3 install redis
#pip3 install redis-5.2.0-py3-none-any.whl

cp /etc/redis/redis.conf{,.bak}

sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" /etc/redis/redis.conf
sed -i "s/protected-mode yes/protected-mode no/g" /etc/redis/redis.conf

systemctl enable redis && systemctl restart redis

# keystone
crudini --set /etc/keystone/keystone.conf cors allowed_origin http://$CONTROLLER_HOSTNAME:3000

systemctl enable apache2 && systemctl restart apache2

crudini --set /etc/glance/glance-api.conf DEFAULT transport_url rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME
crudini --set /etc/glance/glance-api.conf oslo_messaging_notifications driver messagingv2

systemctl enable glance-api && systemctl restart glance-api

crudini --set /etc/neutron/neutron.conf oslo_messaging_notifications driver messagingv2

systemctl enable nova-api && systemctl restart nova-api

systemctl enable neutron-server && systemctl restart neutron-server
systemctl enable neutron-openvswitch-agent && systemctl restart neutron-openvswitch-agent
systemctl enable neutron-dhcp-agent && systemctl restart neutron-dhcp-agent
systemctl enable neutron-metadata-agent && systemctl restart neutron-metadata-agent
systemctl enable neutron-l3-agent && systemctl restart neutron-l3-agent

# 安装 Gnocchi 相关软件包
apt install -y gnocchi-api gnocchi-metricd python3-gnocchiclient
apt install -y uwsgi-plugin-python3 uwsgi

# 备份 Gnocchi 配置文件
cp /etc/gnocchi/gnocchi.conf{,.bak}

# 使用 crudini 修改 Gnocchi 配置文件
crudini --set /etc/gnocchi/gnocchi.conf DEFAULT coordination_url redis://$CONTROLLER_HOSTNAME:6379
crudini --set /etc/gnocchi/gnocchi.conf api auth_mode keystone
crudini --set /etc/gnocchi/gnocchi.conf api port 8041
crudini --set /etc/gnocchi/gnocchi.conf api uwsgi_mode http-socket
crudini --set /etc/gnocchi/gnocchi.conf cors allowed_origin http://$CONTROLLER_HOSTNAME:3000
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken auth_type password
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken auth_url http://$CONTROLLER_HOSTNAME:5000/v3
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken project_domain_name Default
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken user_domain_name Default
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken project_name service
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken username gnocchi
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken password $GNOCCHI_PASS
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken interface internalURL
crudini --set /etc/gnocchi/gnocchi.conf keystone_authtoken region_name RegionOne
crudini --set /etc/gnocchi/gnocchi.conf indexer url mysql+pymysql://gnocchi:$GNOCCHI_DBPASS@$CONTROLLER_HOSTNAME/gnocchi
crudini --set /etc/gnocchi/gnocchi.conf storage coordination_url redis://$CONTROLLER_HOSTNAME:6379
crudini --set /etc/gnocchi/gnocchi.conf storage file_basepath /var/lib/gnocchi
crudini --set /etc/gnocchi/gnocchi.conf storage driver file

# 工作线程,差不多可以设置为cpu核心数量的两倍
crudini --set /etc/gnocchi/gnocchi.conf DEFAULT parallel_operations 8
# 每次处理的数据量,可以减少 I/O 操作次数,从而提高处理效率。但是,如果单次处理的数据量过大,可能会导致内存使用过高。多少合并成一次处理
crudini --set /etc/gnocchi/gnocchi.conf DEFAULT batch_size 100

# 请求的最大返回结果数量。
crudini --set /etc/gnocchi/gnocchi.conf api max_limit 1000

# 工作线程,差不多可以设置为cpu核心数量的两倍
crudini --set /etc/gnocchi/gnocchi.conf metricd workers 8
# 多久处理一次收集到的数据
crudini --set /etc/gnocchi/gnocchi.conf metricd metric_processing_delay 10
# 尽可能多尽可能块的处理数据
crudini --set /etc/gnocchi/gnocchi.conf metricd greedy true
# 报告时间,多久提交一次处理完成的数据
crudini --set /etc/gnocchi/gnocchi.conf metricd metric_reporting_delay 60
# 超过多少秒删除处理过的数据
crudini --set /etc/gnocchi/gnocchi.conf metricd metric_cleanup_delay 300

chmod -R 777 /var/lib/gnocchi

# 初始化 Gnocchi
gnocchi-upgrade

# 启用并重启 Gnocchi 服务
#systemctl enable gnocchi-api && systemctl restart gnocchi-api
systemctl enable gnocchi-metricd && systemctl restart gnocchi-metricd

# 安装 Ceilometer 相关软件包
apt-get install -y ceilometer-agent-notification ceilometer-agent-central

# 备份 Ceilometer 配置文件
#cp /etc/ceilometer/pipeline.yaml{,.bak}

openstack metric archive-policy create custom-high-res \
    --definition 'granularity:900,points:5760' \
    --definition 'granularity:3600,points:168' \
    --definition 'granularity:86400,points:365' \
    --back-window 2678400 \
    --aggregation-method mean

# 配置 Ceilometer
cat <<EOF > /etc/ceilometer/pipeline.yaml
sources:
    - name: meter_source
      meters:
          - "*"
      sinks:
          - meter_sink
sinks:
    - name: meter_sink
      publishers:
          - gnocchi://?filter_project=service&archive_policy=custom-high-res
EOF

cp /etc/ceilometer/polling.yaml{,.bak}

cat <<EOF > /etc/ceilometer/polling.yaml
---
sources:
    - name: some_pollsters
      interval: 15
      meters:
        - "*"
EOF

# 备份 Ceilometer 配置文件
cp /etc/ceilometer/ceilometer.conf{,.bak}

# 使用 crudini 修改 Ceilometer 配置文件

crudini --set /etc/ceilometer/ceilometer.conf DEFAULT pipeline_cfg_file pipeline.yaml
crudini --set /etc/ceilometer/ceilometer.conf polling cfg_file polling.yaml

crudini --set /etc/ceilometer/ceilometer.conf DEFAULT transport_url rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME
crudini --set /etc/ceilometer/ceilometer.conf service_credentials auth_type password
crudini --set /etc/ceilometer/ceilometer.conf service_credentials auth_url http://$CONTROLLER_HOSTNAME:5000/v3
crudini --set /etc/ceilometer/ceilometer.conf service_credentials project_domain_id default
crudini --set /etc/ceilometer/ceilometer.conf service_credentials user_domain_id default
crudini --set /etc/ceilometer/ceilometer.conf service_credentials project_name service
crudini --set /etc/ceilometer/ceilometer.conf service_credentials username ceilometer
crudini --set /etc/ceilometer/ceilometer.conf service_credentials password $CEILOMETER_PASS
crudini --set /etc/ceilometer/ceilometer.conf service_credentials interface internalURL
crudini --set /etc/ceilometer/ceilometer.conf service_credentials region_name RegionOne

# 在 Gnocchi 中创建 Ceilometer 资源
ceilometer-upgrade

# 启用并重启 Ceilometer 服务
systemctl enable ceilometer-agent-central && systemctl restart ceilometer-agent-central
systemctl enable ceilometer-agent-notification && systemctl restart ceilometer-agent-notification

#crudini --set /etc/glance/glance-api.conf DEFAULT transport_url rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME
#crudini --set /etc/glance/glance-api.conf oslo_messaging_notifications driver messagingv2
#
#service glance-api restart
#
#crudini --set /etc/neutron/neutron.conf oslo_messaging_notifications driver messagingv2
#
#service neutron-server restart

echo "Ceilometer Controller 已安装并配置完成。"

###

# 在计算节点上执行的操作
COMPUTE_SCRIPT=$(cat <<EOF
#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

apt-get install -y ceilometer-agent-compute
apt-get install ceilometer-agent-ipmi

cp /etc/ceilometer/ceilometer.conf{,.bak}

crudini --set /etc/ceilometer/ceilometer.conf DEFAULT transport_url rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME
crudini --set /etc/ceilometer/ceilometer.conf service_credentials auth_url http://$CONTROLLER_HOSTNAME:5000/v3
crudini --set /etc/ceilometer/ceilometer.conf service_credentials project_domain_id default
crudini --set /etc/ceilometer/ceilometer.conf service_credentials user_domain_id default
crudini --set /etc/ceilometer/ceilometer.conf service_credentials auth_type password
crudini --set /etc/ceilometer/ceilometer.conf service_credentials username ceilometer
crudini --set /etc/ceilometer/ceilometer.conf service_credentials project_name service
crudini --set /etc/ceilometer/ceilometer.conf service_credentials password $CEILOMETER_PASS
crudini --set /etc/ceilometer/ceilometer.conf service_credentials interface internalURL
crudini --set /etc/ceilometer/ceilometer.conf service_credentials region_name RegionOne

echo "ceilometer ALL = (root) NOPASSWD: /usr/bin/ceilometer-rootwrap /etc/ceilometer/rootwrap.conf *" >> /etc/sudoers

cp /etc/ceilometer/polling.yaml{,.bak}

cat <<EOF2 > /etc/ceilometer/polling.yaml
---
sources:
    - name: some_pollsters
      interval: 15
      meters:
        - "*"
EOF2

service ceilometer-agent-compute restart
service ceilometer-agent-ipmi restart

# cp /etc/nova/nova.conf{,.bak2}

crudini --set /etc/nova/nova.conf DEFAULT instance_usage_audit True
crudini --set /etc/nova/nova.conf DEFAULT instance_usage_audit_period hour
crudini --set /etc/nova/nova.conf notifications notify_on_state_change vm_and_task_state
crudini --set /etc/nova/nova.conf oslo_messaging_notifications driver messagingv2

service nova-compute restart
systemctl restart nova-compute

echo "Ceilometer Compute 已安装并配置完成。"

EOF
)

# 通过 SSH 执行计算节点脚本
#sshpass -p $COMPUTE_PASS ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME "bash -s" <<< "$COMPUTE_SCRIPT"
ssh -o StrictHostKeyChecking=no root@$COMPUTE_HOSTNAME "bash -s" <<< "$COMPUTE_SCRIPT"
systemctl restart apache2

gnocchi-upgrade

systemctl restart gnocchi-metricd

ceilometer-upgrade

systemctl restart ceilometer-agent-central

systemctl restart ceilometer-agent-notification

Aodh

Aodh需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库 root 用户密码。例如,000000
DB_PASS=000000

# 消息队列密码。例如,000000
RABBIT_PASS=000000

# Aodh 数据库密码。例如,000000
AODH_DBPASS=000000

# Aodh 服务密码。例如,000000
AODH_PASS=000000

Aodh脚本

install_aodh.sh

#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

# 创建 Aodh 数据库
mysql -uroot -p$DB_PASS -e "CREATE DATABASE aodh;"

mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON aodh.* TO 'aodh'@'localhost' IDENTIFIED BY '$AODH_DBPASS'"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON aodh.* TO 'aodh'@'%' IDENTIFIED BY '$AODH_DBPASS';"

# 创建 Aodh 用户
openstack user create --domain default --password $AODH_PASS aodh

# 添加 Aodh 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user aodh admin

# 创建 Aodh 服务
openstack service create --name aodh --description "Telemetry" alarming

# 创建 Aodh 端点
openstack endpoint create --region RegionOne alarming public http://$CONTROLLER_HOSTNAME:8042
openstack endpoint create --region RegionOne alarming internal http://$CONTROLLER_HOSTNAME:8042
openstack endpoint create --region RegionOne alarming admin http://$CONTROLLER_HOSTNAME:8042

# 安装 Aodh
apt install -y aodh-api aodh-evaluator aodh-notifier aodh-listener aodh-expirer python3-aodhclient

# 备份 Aodh 配置文件
cp /etc/aodh/aodh.conf{,.bak}

# 使用 crudini 修改 Aodh 配置文件
crudini --set /etc/aodh/aodh.conf database connection mysql+pymysql://aodh:$AODH_DBPASS@$CONTROLLER_HOSTNAME/aodh
crudini --set /etc/aodh/aodh.conf DEFAULT transport_url rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME
crudini --set /etc/aodh/aodh.conf DEFAULT auth_strategy keystone
crudini --set /etc/aodh/aodh.conf keystone_authtoken www_authenticate_uri http://$CONTROLLER_HOSTNAME:5000
crudini --set /etc/aodh/aodh.conf keystone_authtoken auth_url http://$CONTROLLER_HOSTNAME:5000
crudini --set /etc/aodh/aodh.conf keystone_authtoken memcached_servers $CONTROLLER_HOSTNAME:11211
crudini --set /etc/aodh/aodh.conf keystone_authtoken auth_type password
crudini --set /etc/aodh/aodh.conf keystone_authtoken project_domain_id default
crudini --set /etc/aodh/aodh.conf keystone_authtoken user_domain_id default
crudini --set /etc/aodh/aodh.conf keystone_authtoken project_name service
crudini --set /etc/aodh/aodh.conf keystone_authtoken username aodh
crudini --set /etc/aodh/aodh.conf keystone_authtoken password $AODH_PASS
crudini --set /etc/aodh/aodh.conf service_credentials auth_type password
crudini --set /etc/aodh/aodh.conf service_credentials auth_url http://$CONTROLLER_HOSTNAME:5000/v3
crudini --set /etc/aodh/aodh.conf service_credentials project_domain_id default
crudini --set /etc/aodh/aodh.conf service_credentials user_domain_id default
crudini --set /etc/aodh/aodh.conf service_credentials project_name service
crudini --set /etc/aodh/aodh.conf service_credentials username aodh
crudini --set /etc/aodh/aodh.conf service_credentials password $AODH_PASS
crudini --set /etc/aodh/aodh.conf service_credentials interface internalURL
crudini --set /etc/aodh/aodh.conf service_credentials region_name RegionOne

chmod -R 777 /etc/aodh/

#aodh-dbsync
su -s /bin/sh -c "aodh-dbsync" aodh

service apache2 restart
service aodh-api restart
service aodh-evaluator restart
service aodh-notifier restart
service aodh-listener restart

systemctl restart apache2 aodh-api aodh-evaluator aodh-notifier aodh-listener 
systemctl enable aodh-api aodh-evaluator aodh-notifier aodh-listener 

echo "Aodh 已安装并配置完成。"
安装后检查可能错误,可能是环境变量有问题,后面要取消环境变量或者是切换bash页面

Heat

Heat需要的变量

#!/bin/bash

# 控制节点主机名称。例如,controller
CONTROLLER_HOSTNAME=controller

# 数据库 root 用户密码。例如,000000
DB_PASS=000000

# 消息队列密码。例如,000000
RABBIT_PASS=000000

# Heat 数据库密码。例如,000000
HEAT_DBPASS=000000

# Heat 服务密码。例如,000000
HEAT_PASS=000000

# Heat domain 服务密码。例如,000000
HEAT_DOMAIN_PASS=000000

Heat脚本

install_heat.sh

#!/bin/bash

### 生效配置

# 生效配置文件
source /root/env.sh

# 加载 admin-openrc 文件
source /root/admin-openrc.sh
source /etc/keystone/admin-openrc.sh

mysql -uroot -p$DB_PASS -e "CREATE DATABASE IF NOT EXISTS heat;"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'localhost' IDENTIFIED BY '$HEAT_DBPASS';"
mysql -uroot -p$DB_PASS -e "GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'%' IDENTIFIED BY '$HEAT_DBPASS';"

# 创建 Heat 用户
openstack user create --domain default --password $HEAT_PASS heat

# 添加 Heat 用户到 service 项目并赋予 admin 角色
openstack role add --project service --user heat admin

# 创建 Heat 服务
openstack service create --name heat --description "Orchestration" orchestration
openstack service create --name heat-cfn --description "Orchestration"  cloudformation

# 创建 Heat 端点
openstack endpoint create --region RegionOne orchestration public http://$CONTROLLER_HOSTNAME:8004/v1/%\(tenant_id\)s
openstack endpoint create --region RegionOne orchestration internal http://$CONTROLLER_HOSTNAME:8004/v1/%\(tenant_id\)s
openstack endpoint create --region RegionOne orchestration admin http://$CONTROLLER_HOSTNAME:8004/v1/%\(tenant_id\)s
openstack endpoint create --region RegionOne cloudformation public http://$CONTROLLER_HOSTNAME:8000/v1
openstack endpoint create --region RegionOne cloudformation internal http://$CONTROLLER_HOSTNAME:8000/v1
openstack endpoint create --region RegionOne cloudformation admin http://$CONTROLLER_HOSTNAME:8000/v1

# 创建 Heat domain
openstack domain create --description "Stack projects and users" heat
openstack user create --domain heat --password $HEAT_DOMAIN_PASS heat_domain_admin
openstack role add --domain heat --user-domain heat --user heat_domain_admin admin
openstack role create heat_stack_owner
openstack role create heat_stack_user

# 安装 Heat
apt install -y heat-api heat-api-cfn heat-engine
#apt install -y python3-heatclient python3-vitrageclient python3-zunclient

# 备份 Heat 配置文件
cp /etc/heat/heat.conf{,.bak}

# 使用 crudini 修改 Heat 配置文件
crudini --set /etc/heat/heat.conf database connection mysql+pymysql://heat:$HEAT_DBPASS@$CONTROLLER_HOSTNAME/heat

crudini --set /etc/heat/heat.conf DEFAULT transport_url rabbit://openstack:$RABBIT_PASS@$CONTROLLER_HOSTNAME
crudini --set /etc/heat/heat.conf DEFAULT heat_metadata_server_url http://$CONTROLLER_HOSTNAME:8000
crudini --set /etc/heat/heat.conf DEFAULT heat_waitcondition_server_url http://$CONTROLLER_HOSTNAME:8000/v1/waitcondition
crudini --set /etc/heat/heat.conf DEFAULT stack_domain_admin heat_domain_admin
crudini --set /etc/heat/heat.conf DEFAULT stack_domain_admin_password $HEAT_DOMAIN_PASS
crudini --set /etc/heat/heat.conf DEFAULT stack_user_domain_name heat

crudini --set /etc/heat/heat.conf keystone_authtoken www_authenticate_uri http://$CONTROLLER_HOSTNAME:5000
crudini --set /etc/heat/heat.conf keystone_authtoken auth_url http://$CONTROLLER_HOSTNAME:5000
crudini --set /etc/heat/heat.conf keystone_authtoken memcached_servers $CONTROLLER_HOSTNAME:11211
crudini --set /etc/heat/heat.conf keystone_authtoken auth_type password
crudini --set /etc/heat/heat.conf keystone_authtoken project_domain_name default
crudini --set /etc/heat/heat.conf keystone_authtoken user_domain_name default
crudini --set /etc/heat/heat.conf keystone_authtoken project_name service
crudini --set /etc/heat/heat.conf keystone_authtoken username heat
crudini --set /etc/heat/heat.conf keystone_authtoken password $HEAT_PASS

crudini --set /etc/heat/heat.conf trustee auth_type password
crudini --set /etc/heat/heat.conf trustee auth_url http://$CONTROLLER_HOSTNAME:5000
crudini --set /etc/heat/heat.conf trustee username heat
crudini --set /etc/heat/heat.conf trustee password $HEAT_PASS
crudini --set /etc/heat/heat.conf trustee user_domain_name default

crudini --set /etc/heat/heat.conf clients_keystone auth_uri http://$CONTROLLER_HOSTNAME:5000

# 填充 Heat 数据库表
su -s /bin/sh -c "heat-manage db_sync" heat

# 重启 Heat 服务
service heat-api restart
service heat-api-cfn restart
service heat-engine restart

systemctl enable heat-api heat-api-cfn heat-engine
systemctl start heat-api heat-api-cfn heat-engine

# 验证 Heat
openstack orchestration service list

echo "Heat 已安装并配置完成。"