Files

305 lines
8.9 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 "=========================================="