305 lines
8.9 KiB
Bash
Executable File
305 lines
8.9 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
set -euo pipefail
|
||
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
RED='\033[0;31m'
|
||
NC='\033[0m'
|
||
|
||
log_info() {
|
||
echo -e "${GREEN}[INFO]${NC} $1"
|
||
}
|
||
|
||
log_warn() {
|
||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||
}
|
||
|
||
log_err() {
|
||
echo -e "${RED}[ERROR]${NC} $1"
|
||
}
|
||
|
||
# 检查 root 权限
|
||
if [ "$EUID" -ne 0 ]; then
|
||
log_err "请使用 root 权限执行此脚本(如: sudo bash $0)"
|
||
exit 1
|
||
fi
|
||
|
||
log_info "=========================================="
|
||
log_info "开始初始化实验环境..."
|
||
log_info "=========================================="
|
||
|
||
# 直接连接终端,保留 yum 原生下载进度条;不要通过 tee 管道转存输出。
|
||
run_yum() {
|
||
local status
|
||
log_info "执行 yum $*(下载速度取决于网络和镜像源)..."
|
||
if yum "$@"; then
|
||
log_info "yum 操作完成。"
|
||
else
|
||
status=$?
|
||
log_err "yum 操作失败(退出码 $status),请查看上方错误信息。"
|
||
return "$status"
|
||
fi
|
||
}
|
||
|
||
REPO_DIR="/etc/yum.repos.d"
|
||
BACKUP_DIR="/etc/yum.repos.d.bak"
|
||
|
||
# 首次运行时备份原有软件源
|
||
if [ ! -d "$BACKUP_DIR" ]; then
|
||
log_info "备份原有 yum 软件源..."
|
||
cp -a "$REPO_DIR" "$BACKUP_DIR"
|
||
fi
|
||
|
||
# 配置 CentOS 7.9 基础源
|
||
log_info "配置 CentOS 7.9 腾讯云软件源..."
|
||
|
||
cat > "$REPO_DIR/CentOS-Base.repo" <<'EOF'
|
||
[base]
|
||
name=CentOS-7 - Base - Tencent
|
||
baseurl=https://mirrors.cloud.tencent.com/centos-vault/7.9.2009/os/$basearch/
|
||
gpgcheck=0
|
||
enabled=1
|
||
|
||
[updates]
|
||
name=CentOS-7 - Updates - Tencent
|
||
baseurl=https://mirrors.cloud.tencent.com/centos-vault/7.9.2009/updates/$basearch/
|
||
gpgcheck=0
|
||
enabled=1
|
||
|
||
[extras]
|
||
name=CentOS-7 - Extras - Tencent
|
||
baseurl=https://mirrors.cloud.tencent.com/centos-vault/7.9.2009/extras/$basearch/
|
||
gpgcheck=0
|
||
enabled=1
|
||
EOF
|
||
|
||
# 配置 QEMU EV 源
|
||
cat > "$REPO_DIR/CentOS-QEMU-EV.repo" <<'EOF'
|
||
[centos-qemu-ev]
|
||
name=CentOS-7 - QEMU EV - Tencent
|
||
baseurl=https://mirrors.cloud.tencent.com/centos-vault/7.9.2009/virt/$basearch/kvm-common/
|
||
gpgcheck=0
|
||
enabled=1
|
||
EOF
|
||
|
||
# 配置 OpenStack Rocky 源
|
||
cat > "$REPO_DIR/CentOS-OpenStack-rocky.repo" <<'EOF'
|
||
[centos-openstack-rocky]
|
||
name=CentOS-7 - OpenStack Rocky - Tencent
|
||
baseurl=https://mirrors.cloud.tencent.com/centos-vault/7.9.2009/cloud/$basearch/openstack-rocky/
|
||
gpgcheck=0
|
||
enabled=1
|
||
exclude=sip,PyQt4
|
||
EOF
|
||
|
||
# 删除不再需要的 Ceph 源,避免 yum 读取其元数据
|
||
rm -f "$REPO_DIR/CentOS-Ceph-Luminous.repo"
|
||
|
||
|
||
# 清除旧仓库元数据,保留已下载的软件包缓存
|
||
log_info "刷新软件源元数据..."
|
||
run_yum clean metadata
|
||
|
||
# 安装 KVM / libvirt
|
||
log_info "安装/检查虚拟化软件包..."
|
||
|
||
run_yum install -y \
|
||
qemu-kvm \
|
||
libvirt \
|
||
virt-install \
|
||
bridge-utils \
|
||
qemu-img
|
||
|
||
# 启动 libvirtd
|
||
log_info "启动 libvirtd 服务..."
|
||
|
||
systemctl enable --now libvirtd > /dev/null
|
||
|
||
# 验证服务状态
|
||
if systemctl is-active --quiet libvirtd; then
|
||
log_info "libvirtd 状态正常。"
|
||
else
|
||
log_err "libvirtd 启动失败!"
|
||
exit 1
|
||
fi
|
||
|
||
log_info "=========================================="
|
||
log_info "基础虚拟化环境初始化完成,开始配置控制节点..."
|
||
log_info "=========================================="
|
||
|
||
CONTROLLER_IP="192.168.30.129"
|
||
CONTROLLER_HOSTNAME="controller"
|
||
|
||
# 首次修改时备份配置,重复运行不覆盖原始备份。
|
||
backup_config() {
|
||
if [ -f "$1" ] && [ ! -e "$1.env3-1.bak" ]; then
|
||
cp -a "$1" "$1.env3-1.bak"
|
||
fi
|
||
}
|
||
|
||
log_info "关闭防火墙和 SELinux..."
|
||
if systemctl list-unit-files firewalld.service --no-legend | grep -q '^firewalld.service'; then
|
||
systemctl stop firewalld
|
||
systemctl disable firewalld
|
||
fi
|
||
if command -v getenforce > /dev/null 2>&1; then
|
||
if [ "$(getenforce)" = "Enforcing" ]; then
|
||
setenforce 0
|
||
fi
|
||
fi
|
||
if [ -f /etc/selinux/config ]; then
|
||
backup_config /etc/selinux/config
|
||
sed -i '/^[[:space:]]*SELINUX=/d' /etc/selinux/config
|
||
echo 'SELINUX=disabled' >> /etc/selinux/config
|
||
fi
|
||
|
||
log_info "配置主机名和 hosts 解析..."
|
||
hostnamectl set-hostname "$CONTROLLER_HOSTNAME"
|
||
backup_config /etc/hosts
|
||
# 移除旧 controller 映射,保留同一行的其他别名及注释。
|
||
HOSTS_TMP=$(mktemp)
|
||
awk -v host="$CONTROLLER_HOSTNAME" '
|
||
/^[[:space:]]*#/ || NF == 0 { print; next }
|
||
{
|
||
comment = ""
|
||
pos = index($0, "#")
|
||
if (pos) {
|
||
comment = substr($0, pos)
|
||
$0 = substr($0, 1, pos - 1)
|
||
}
|
||
line = $1
|
||
aliases = 0
|
||
for (i = 2; i <= NF; i++) {
|
||
if ($i != host) {
|
||
line = line " " $i
|
||
aliases++
|
||
}
|
||
}
|
||
if (aliases) print line (comment == "" ? "" : " " comment)
|
||
else if (comment != "") print comment
|
||
}
|
||
' /etc/hosts > "$HOSTS_TMP"
|
||
cat "$HOSTS_TMP" > /etc/hosts
|
||
rm -f "$HOSTS_TMP"
|
||
printf '%s %s\n' "$CONTROLLER_IP" "$CONTROLLER_HOSTNAME" >> /etc/hosts
|
||
|
||
log_info "升级系统软件包并安装 OpenStack 基础服务..."
|
||
run_yum -y upgrade
|
||
run_yum install -y chrony python2-openstackclient \
|
||
mariadb mariadb-server python2-PyMySQL \
|
||
rabbitmq-server memcached python-memcached etcd
|
||
|
||
log_info "配置 chrony 时间服务器..."
|
||
backup_config /etc/chrony.conf
|
||
if ! grep -Eq '^[[:space:]]*allow[[:space:]]+all([[:space:]]*(#.*)?)?$' /etc/chrony.conf; then
|
||
printf '\n# 允许所有网段的机器访问同步时间\nallow all\n' >> /etc/chrony.conf
|
||
fi
|
||
systemctl enable chronyd
|
||
systemctl restart chronyd
|
||
|
||
log_info "配置 MariaDB..."
|
||
mkdir -p /etc/my.cnf.d
|
||
backup_config /etc/my.cnf.d/openstack.cnf
|
||
cat > /etc/my.cnf.d/openstack.cnf <<'EOF'
|
||
[mysqld]
|
||
bind-address = 0.0.0.0
|
||
# 默认使用 InnoDB,每个表的数据独立保存成文件。
|
||
default-storage-engine = innodb
|
||
innodb_file_per_table = on
|
||
# 调高最大连接数,并使用 UTF-8 字符集。
|
||
max_connections = 4096
|
||
collation-server = utf8_general_ci
|
||
character-set-server = utf8
|
||
EOF
|
||
systemctl enable mariadb
|
||
systemctl restart mariadb
|
||
|
||
log_info "初始化 MariaDB 安全配置及 root 远程登录权限..."
|
||
# CentOS 7 的 MariaDB 5.5:自动执行 mysql_secure_installation 的等效操作。
|
||
# 使用权限为 600 的临时客户端配置,避免把密码放进进程参数。
|
||
MYSQL_AUTH_FILE=$(mktemp)
|
||
trap 'rm -f "$MYSQL_AUTH_FILE"' EXIT
|
||
chmod 600 "$MYSQL_AUTH_FILE"
|
||
cat > "$MYSQL_AUTH_FILE" <<'EOF'
|
||
[client]
|
||
user=root
|
||
password=123456
|
||
protocol=socket
|
||
EOF
|
||
MYSQL_CMD=(mysql --defaults-extra-file="$MYSQL_AUTH_FILE")
|
||
if ! "${MYSQL_CMD[@]}" -e 'SELECT 1' > /dev/null 2>&1; then
|
||
MYSQL_CMD=(mysql --no-defaults --user=root --protocol=socket)
|
||
if ! "${MYSQL_CMD[@]}" -e 'SELECT 1' > /dev/null 2>&1; then
|
||
log_err "无法使用空密码或预设密码连接 MariaDB root,请检查已有数据库凭据。"
|
||
exit 1
|
||
fi
|
||
fi
|
||
"${MYSQL_CMD[@]}" <<'SQL'
|
||
DELETE FROM mysql.user WHERE User = '';
|
||
DELETE FROM mysql.user
|
||
WHERE User = 'root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
|
||
UPDATE mysql.user SET Password = PASSWORD('123456') WHERE User = 'root';
|
||
DROP DATABASE IF EXISTS test;
|
||
DELETE FROM mysql.db WHERE Db = 'test' OR Db = 'test\_%';
|
||
FLUSH PRIVILEGES;
|
||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
|
||
FLUSH PRIVILEGES;
|
||
SQL
|
||
mysql --defaults-extra-file="$MYSQL_AUTH_FILE" -e 'SELECT 1' > /dev/null
|
||
rm -f "$MYSQL_AUTH_FILE"
|
||
trap - EXIT
|
||
|
||
log_info "配置 RabbitMQ 用户及权限..."
|
||
systemctl enable rabbitmq-server
|
||
systemctl start rabbitmq-server
|
||
RABBITMQ_USERS=$(rabbitmqctl list_users -q)
|
||
if awk '$1 == "openstack" { found = 1 } END { exit !found }' <<< "$RABBITMQ_USERS"; then
|
||
rabbitmqctl change_password openstack openstack
|
||
else
|
||
rabbitmqctl add_user openstack openstack
|
||
fi
|
||
rabbitmqctl set_permissions -p / openstack '.*' '.*' '.*'
|
||
|
||
log_info "配置 Memcached..."
|
||
backup_config /etc/sysconfig/memcached
|
||
sed -i '/^[[:space:]]*OPTIONS=/d' /etc/sysconfig/memcached
|
||
echo 'OPTIONS="-l 127.0.0.1,::1,controller"' >> /etc/sysconfig/memcached
|
||
systemctl enable memcached
|
||
systemctl restart memcached
|
||
|
||
log_info "配置 Etcd..."
|
||
backup_config /etc/etcd/etcd.conf
|
||
cat > /etc/etcd/etcd.conf <<'EOF'
|
||
#[Member]
|
||
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
|
||
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
|
||
ETCD_NAME="controller"
|
||
|
||
#[Clustering]
|
||
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://controller:2380"
|
||
ETCD_ADVERTISE_CLIENT_URLS="http://controller:2379"
|
||
ETCD_INITIAL_CLUSTER="controller=http://controller:2380"
|
||
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01"
|
||
ETCD_INITIAL_CLUSTER_STATE="new"
|
||
EOF
|
||
systemctl enable etcd
|
||
systemctl restart etcd
|
||
|
||
log_info "检查各项服务状态..."
|
||
for service in libvirtd chronyd mariadb rabbitmq-server memcached etcd; do
|
||
if systemctl is-active --quiet "$service"; then
|
||
log_info "$service 状态正常。"
|
||
else
|
||
log_err "$service 未正常运行,请使用 journalctl -u $service 查看日志。"
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
log_info "=========================================="
|
||
log_info "OpenStack 控制节点初始化完成!"
|
||
log_info "控制节点:$CONTROLLER_HOSTNAME ($CONTROLLER_IP)"
|
||
log_info "MariaDB root 密码:123456,已允许远程登录。"
|
||
log_info "RabbitMQ 用户/密码:openstack / openstack"
|
||
log_info "=========================================="
|