然后
#!/bin/bash
#############################################
GCP 嵌套虚拟化一键配置脚本
作者: Claude
用途: 在 GCP Compute Engine 上一键开启嵌套虚拟化并安装 KVM
适用: N1/N2/N2D/C2/C2D/N3 等机型 (E2 不支持)
使用: 在 Cloud Shell 中运行
bash enable-nested-virt.sh <实例名> <区域>
例如:
bash enable-nested-virt.sh instance-20260422-153218 asia-east2-b
#############################################
set -e # 遇到错误立即退出
颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 恢复默认色
日志函数
log_info() { echo -e "BLUE[INFO]{BLUE}[INFO]BLUE[INFO]{NC} KaTeX parse error: Expected 'EOF', got '}' at position 5: 1"; }̲ log_ok() { ...{GREEN}[ OK ]{NC} KaTeX parse error: Expected 'EOF', got '}' at position 5: 1"; }̲ log_warn() { ...{YELLOW}\[WARN\]{NC} KaTeX parse error: Expected 'EOF', got '}' at position 5: 1"; }̲ log_error() { ...{RED}[FAIL]{NC} 1"; }
分隔线
separator() {
echo -e "BLUE═══════════════════════════════════════════════════════{BLUE}═══════════════════════════════════════════════════════BLUE═══════════════════════════════════════════════════════{NC}"
}
#############################################
参数检查
#############################################
if [ KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ -lt 2 ]; then ...{YELLOW}用法: 0<实例名><区域>[机型]0 <实例名> <区域> [机型]0<实例名><区域>[机型]{NC}"
echo -e "${YELLOW}例如: 0instance−20260422−153218asia−east2−b0 instance-20260422-153218 asia-east2-b0instance−20260422−153218asia−east2−b{NC}"
echo -e "${YELLOW}可选: 0instance−20260422−153218asia−east2−bn2−highcpu−160 instance-20260422-153218 asia-east2-b n2-highcpu-160instance−20260422−153218asia−east2−bn2−highcpu−16{NC}"
exit 1
fi
INSTANCE_NAME="$1"
ZONE="2"TARGETMACHINETYPE="2" TARGET_MACHINE_TYPE="2"TARGETMACHINETYPE="{3:-n2-highcpu-16}" # 默认机型
separator
echo -e "GREENGCP嵌套虚拟化一键配置脚本{GREEN} GCP 嵌套虚拟化一键配置脚本GREENGCP嵌套虚拟化一键配置脚本{NC}"
separator
log_info "实例名: $INSTANCE_NAME"
log_info "区域: $ZONE"
log_info "默认替换机型(仅E2时用): $TARGET_MACHINE_TYPE"
separator
#############################################
步骤 1: 检查 gcloud 是否可用
#############################################
log_info "[1/8] 检查 gcloud 命令..."
if ! command -v gcloud &> /dev/null; then
log_error "gcloud 命令未找到,请先安装 Google Cloud SDK"
exit 1
fi
log_ok "gcloud 已就绪"
#############################################
步骤 2: 检查实例是否存在
#############################################
log_info "[2/8] 检查实例 INSTANCENAME是否存在..."if!gcloudcomputeinstancesdescribe"INSTANCE_NAME 是否存在..." if ! gcloud compute instances describe "INSTANCENAME是否存在..."if!gcloudcomputeinstancesdescribe"INSTANCE_NAME" --zone="$ZONE" &> /dev/null; then
log_error "实例 INSTANCE_NAME 在区域 ZONE 中不存在"
exit 1
fi
log_ok "实例存在"
#############################################
步骤 3: 检查机型
#############################################
log_info "[3/8] 检查机型..."
MACHINE_TYPE_URL=(gcloudcomputeinstancesdescribe"(gcloud compute instances describe "(gcloudcomputeinstancesdescribe"INSTANCE_NAME" --zone="ZONE"−−format="get(machineType)")CURRENTMACHINETYPE=ZONE" --format="get(machineType)") CURRENT_MACHINE_TYPE=ZONE"−−format="get(machineType)")CURRENTMACHINETYPE=(basename "$MACHINE_TYPE_URL")
log_info "当前机型: $CURRENT_MACHINE_TYPE"
if [[ "$CURRENT_MACHINE_TYPE" == e2-* ]]; then
log_warn "E2 机型不支持嵌套虚拟化"
read -p "是否自动替换为 TARGETMACHINETYPE?(y/n):"CONFIRMif[["TARGET_MACHINE_TYPE ? (y/n): " CONFIRM if [[ "TARGETMACHINETYPE?(y/n):"CONFIRMif[["CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then
log_error "已取消操作"
exit 1
fi
# 停止并更换机型
log_info "停止实例..."
gcloud compute instances stop "$INSTANCE_NAME" --zone="$ZONE" --quiet
log_info "更换机型为 $TARGET_MACHINE_TYPE..."
gcloud compute instances set-machine-type "$INSTANCE_NAME" \
--zone="$ZONE" \
--machine-type="$TARGET_MACHINE_TYPE"
log_ok "机型已更换"
else
log_ok "机型支持嵌套虚拟化"
fi
#############################################
步骤 4: 停止实例(如果还在运行)
#############################################
log_info "[4/8] 确保实例已停止..."
STATUS=(gcloudcomputeinstancesdescribe"(gcloud compute instances describe "(gcloudcomputeinstancesdescribe"INSTANCE_NAME" --zone="ZONE"−−format="get(status)")if["ZONE" --format="get(status)") if [ "ZONE"−−format="get(status)")if["STATUS" != "TERMINATED" ]; then
log_info "当前状态: STATUS,正在停止..."gcloudcomputeinstancesstop"STATUS,正在停止..." gcloud compute instances stop "STATUS,正在停止..."gcloudcomputeinstancesstop"INSTANCE_NAME" --zone="$ZONE" --quiet
fi
log_ok "实例已停止"
#############################################
步骤 5: 导出并修改配置
#############################################
log_info "[5/8] 导出实例配置..."
TEMP_CONFIG="/tmp/gcp-nested-config-$.yaml"gcloudcomputeinstancesexport".yaml" gcloud compute instances export ".yaml"gcloudcomputeinstancesexport"INSTANCE_NAME"
--destination="TEMPCONFIG" −−zone="TEMP_CONFIG" \ --zone="TEMPCONFIG" −−zone="ZONE"
log_ok "配置已导出到 $TEMP_CONFIG"
检查是否已经启用过
if grep -q "enableNestedVirtualization: true" "KaTeX parse error: Expected 'EOF', got '#' at position 89: ...套虚拟化配置..." #̲ 检查是否已有 advance...TEMP_CONFIG"; then
已有节点,在其下添加
sed -i '/^advancedMachineFeatures:/a\ enableNestedVirtualization: true' "KaTeX parse error: Expected 'EOF', got '#' at position 31: ... else #̲ 没有节点,追加到文件末尾 ...TEMP_CONFIG"
fi
log_ok "配置已修改"
fi
#############################################
步骤 6: 应用配置
#############################################
log_info "[6/8] 应用新配置..."
gcloud compute instances update-from-file "INSTANCENAME" −−source="INSTANCE_NAME" \ --source="INSTANCENAME" −−source="TEMP_CONFIG"
--most-disruptive-allowed-action=RESTART
--zone="$ZONE"
log_ok "配置已应用"
清理临时文件
rm -f "$TEMP_CONFIG"
#############################################
步骤 7: 启动实例
#############################################
log_info "[7/8] 启动实例..."
gcloud compute instances start "INSTANCENAME"−−zone="INSTANCE_NAME" --zone="INSTANCENAME"−−zone="ZONE" --quiet
log_ok "实例已启动"
等待实例完全启动
log_info "等待实例完全就绪(30 秒)..."
sleep 30
#############################################
步骤 8: 远程验证 + 安装 KVM
#############################################
log_info "[8/8] 远程验证嵌套虚拟化并安装 KVM..."
创建远程执行脚本
REMOTE_SCRIPT='
set -e
颜色
GREEN="\033[0;32m"
RED="\033[0;31m"
YELLOW="\033[1;33m"
NC="\033[0m"
echo -e "YELLOW===验证VMX支持==={YELLOW}=== 验证 VMX 支持 ===YELLOW===验证VMX支持==={NC}"
VMX_COUNT=(grep−cvmx/proc/cpuinfo∣∣echo0)if["(grep -c vmx /proc/cpuinfo || echo 0) if [ "(grep−cvmx/proc/cpuinfo∣∣echo0)if["VMX_COUNT" -eq 0 ]; then
echo -e "RED嵌套虚拟化未启用!{RED}嵌套虚拟化未启用!RED嵌套虚拟化未启用!{NC}"
exit 1
fi
echo -e "${GREEN}VMX 已启用,支持数: VMXCOUNTVMX_COUNTVMXCOUNT{NC}"
echo -e "YELLOW===安装KVM和相关工具==={YELLOW}=== 安装 KVM 和相关工具 ===YELLOW===安装KVM和相关工具==={NC}"
sudo apt-get update -qq
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq
qemu-kvm
libvirt-daemon-system
libvirt-clients
bridge-utils
virtinst
cpu-checker
echo -e "YELLOW===验证KVM加速==={YELLOW}=== 验证 KVM 加速 ===YELLOW===验证KVM加速==={NC}"
sudo kvm-ok
echo -e "YELLOW===将当前用户加入虚拟化组==={YELLOW}=== 将当前用户加入虚拟化组 ===YELLOW===将当前用户加入虚拟化组==={NC}"
sudo usermod -aG kvm,libvirt $USER
echo -e "YELLOW===启动libvirt服务==={YELLOW}=== 启动 libvirt 服务 ===YELLOW===启动libvirt服务==={NC}"
sudo systemctl enable --now libvirtd
sudo systemctl status libvirtd --no-pager | head -5
echo ""
echo -e "GREEN══════════════════════════════════════════{GREEN}══════════════════════════════════════════GREEN══════════════════════════════════════════{NC}"
echo -e "GREEN全部配置完成!{GREEN} 全部配置完成!GREEN全部配置完成!{NC}"
echo -e "GREEN══════════════════════════════════════════{GREEN}══════════════════════════════════════════GREEN══════════════════════════════════════════{NC}"
echo "VMX 核心数: VMXCOUNT"echo"KVM设备:/dev/kvm(可用)"echo"libvirt状态:已启动"echo""echo−e"VMX_COUNT" echo "KVM 设备: /dev/kvm (可用)" echo "libvirt 状态: 已启动" echo "" echo -e "VMXCOUNT"echo"KVM设备:/dev/kvm(可用)"echo"libvirt状态:已启动"echo""echo−e"{YELLOW}注意:需要重新 SSH 登录后组权限才生效!${NC}"
'
通过 SSH 执行远程脚本(带重试)
MAX_RETRY=3
for i in $(seq 1 MAXRETRY);doifgcloudcomputessh"MAX_RETRY); do if gcloud compute ssh "MAXRETRY);doifgcloudcomputessh"INSTANCE_NAME" --zone="ZONE"−−command="ZONE" --command="ZONE"−−command="REMOTE_SCRIPT" 2>/dev/null; then
break
else
log_warn "SSH 连接失败(第 $i 次),10 秒后重试..."
sleep 10
if [ i -eq MAX_RETRY ]; then
log_error "SSH 连接失败,请手动 SSH 进入验证:"
echo " gcloud compute ssh INSTANCENAME−−zone=INSTANCE_NAME --zone=INSTANCENAME−−zone=ZONE"
echo " 然后运行: grep -c vmx /proc/cpuinfo"
exit 1
fi
fi
done
#############################################
完成
#############################################
separator
log_ok "🎉 嵌套虚拟化全部配置完成!"
separator
echo ""
echo -e "GREEN下一步操作:{GREEN}下一步操作:GREEN下一步操作:{NC}"
echo " 1. SSH 连接: gcloud compute ssh INSTANCENAME−−zone=INSTANCE_NAME --zone=INSTANCENAME−−zone=ZONE"
echo " 2. 退出后重新登录使组权限生效"
echo " 3. 测试创建虚拟机: virsh list --all"
echo ""
separator
最后
chmod +x enable-nested-virt.sh
./enable-nested-virt.sh 实例名 区域