#!/bin/bash # 部署Vault集群的脚本 # 检查并安装Vault if ! which vault >/dev/null; then echo "==== 安装Vault ====" VAULT_VERSION="1.20.4" wget -q https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip unzip -q vault_${VAULT_VERSION}_linux_amd64.zip sudo mv vault /usr/local/bin/ rm vault_${VAULT_VERSION}_linux_amd64.zip fi export PATH=$PATH:/usr/local/bin set -e echo "===== 开始部署Vault集群 =====" # 目录定义 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(dirname "$SCRIPT_DIR")" ANSIBLE_DIR="$ROOT_DIR/playbooks" JOBS_DIR="$ROOT_DIR/components/vault/jobs" # 颜色定义 GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color # 函数定义 log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查命令是否存在 check_command() { if ! command -v $1 &> /dev/null; then log_error "$1 命令未找到,请先安装" exit 1 fi } # 检查必要的命令 check_command ansible-playbook check_command nomad check_command vault # 步骤1: 使用Ansible安装Vault log_info "步骤1: 使用Ansible安装Vault..." ansible-playbook -i "$ANSIBLE_DIR/inventories/production/vault.ini" "$ANSIBLE_DIR/playbooks/install/install_vault.yml" # 步骤2: 部署Vault Nomad作业 log_info "步骤2: 部署Vault Nomad作业..." nomad job run "$JOBS_DIR/vault-cluster-exec.nomad" # 等待Nomad作业部署完成 log_info "等待Nomad作业部署完成..." sleep 10 # 检查Nomad作业状态 nomad_status=$(nomad job status vault-cluster-exec | grep Status | head -1 | awk '{print $2}') if [ "$nomad_status" != "running" ]; then log_warn "Vault Nomad作业状态不是'running',当前状态: $nomad_status" log_info "请检查Nomad作业状态: nomad job status vault-cluster-exec" fi # 步骤3: 检查Vault状态并初始化(如果需要) log_info "步骤3: 检查Vault状态..." export VAULT_ADDR='http://127.0.0.1:8200' # 等待Vault启动 log_info "等待Vault启动..." for i in {1..30}; do if curl -s "$VAULT_ADDR/v1/sys/health" > /dev/null; then break fi echo -n "." sleep 2 done echo "" # 检查Vault是否已初始化 init_status=$(curl -s "$VAULT_ADDR/v1/sys/health" | grep -o '"initialized":[^,}]*' | cut -d ':' -f2) if [ "$init_status" = "false" ]; then log_info "Vault未初始化,正在初始化..." # 初始化Vault并保存密钥 mkdir -p "$ROOT_DIR/security/secrets/vault" vault operator init -key-shares=5 -key-threshold=3 -format=json > "$ROOT_DIR/security/secrets/vault/init_keys.json" if [ $? -eq 0 ]; then log_info "Vault初始化成功,解封密钥和根令牌已保存到 $ROOT_DIR/security/secrets/vault/init_keys.json" log_warn "请确保安全保存这些密钥!" # 提取解封密钥 unseal_key1=$(cat "$ROOT_DIR/security/secrets/vault/init_keys.json" | grep -o '"unseal_keys_b64":\[\([^]]*\)' | sed 's/"unseal_keys_b64":\[//g' | tr ',' '\n' | sed 's/"//g' | head -1) unseal_key2=$(cat "$ROOT_DIR/security/secrets/vault/init_keys.json" | grep -o '"unseal_keys_b64":\[\([^]]*\)' | sed 's/"unseal_keys_b64":\[//g' | tr ',' '\n' | sed 's/"//g' | head -2 | tail -1) unseal_key3=$(cat "$ROOT_DIR/security/secrets/vault/init_keys.json" | grep -o '"unseal_keys_b64":\[\([^]]*\)' | sed 's/"unseal_keys_b64":\[//g' | tr ',' '\n' | sed 's/"//g' | head -3 | tail -1) # 解封Vault log_info "正在解封Vault..." vault operator unseal "$unseal_key1" vault operator unseal "$unseal_key2" vault operator unseal "$unseal_key3" log_info "Vault已成功解封" else log_error "Vault初始化失败" exit 1 fi else log_info "Vault已初始化" # 检查Vault是否已解封 sealed_status=$(curl -s "$VAULT_ADDR/v1/sys/health" | grep -o '"sealed":[^,}]*' | cut -d ':' -f2) if [ "$sealed_status" = "true" ]; then log_warn "Vault已初始化但仍处于密封状态,请手动解封" log_info "使用以下命令解封Vault:" log_info "export VAULT_ADDR='http://127.0.0.1:8200'" log_info "vault operator unseal <解封密钥1>" log_info "vault operator unseal <解封密钥2>" log_info "vault operator unseal <解封密钥3>" else log_info "Vault已初始化且已解封,可以正常使用" fi fi # 显示Vault状态 log_info "Vault状态:" vault status log_info "===== Vault集群部署完成 =====" log_info "请在其他节点上运行解封操作,确保集群完全可用"