本文目录导读:

我来介绍Shell脚本管理容器配置文件的方法和最佳实践。
基础配置文件管理
环境变量替换
#!/bin/bash
# config-manager.sh - 容器配置文件管理工具
# 使用envsubst进行环境变量替换
envsubst < config.template.yaml > config.yaml
# 示例: Nginx配置模板
cat > nginx.template.conf << 'EOF'
server {
listen ${NGINX_PORT:-80};
server_name ${SERVER_NAME:-localhost};
location / {
proxy_pass http://${APP_HOST}:${APP_PORT:-3000};
}
}
EOF
# 生成配置文件
export NGINX_PORT=8080
export SERVER_NAME=example.com
envsubst < nginx.template.conf > /etc/nginx/conf.d/app.conf
多环境配置文件管理
#!/bin/bash
# multi-env-config.sh - 多环境配置管理
ENV=${1:-development}
CONFIG_DIR="/app/config"
# 环境配置映射
declare -A ENV_CONFIGS
ENV_CONFIGS["development"]="dev"
ENV_CONFIGS["staging"]="staging"
ENV_CONFIGS["production"]="prod"
# 合并配置文件
merge_configs() {
local base_config="${CONFIG_DIR}/base.yaml"
local env_config="${CONFIG_DIR}/${ENV_CONFIGS[$ENV]}.yaml"
local output="/app/config/application.yaml"
# 使用yq合并YAML文件
yq eval-all '. as $item ireduce ({}; . *+ $item)' \
"$base_config" "$env_config" > "$output"
}
# 验证配置
validate_config() {
local config_file=$1
local schema_file="${CONFIG_DIR}/schema.yaml"
# 使用yq验证配置
yq eval -e "true" "$config_file" || {
echo "Invalid configuration"
exit 1
}
}
# 生成环境特定配置
generate_config() {
case $ENV in
development)
export DB_HOST="localhost"
export DB_PORT=5432
export LOG_LEVEL="debug"
;;
production)
export DB_HOST="${PROD_DB_HOST}"
export DB_PORT=5432
export LOG_LEVEL="info"
;;
esac
envsubst < "${CONFIG_DIR}/template.yaml" > "/app/config/application.yaml"
}
配置加密与解密
#!/bin/bash
# encrypted-config.sh - 加密配置管理
# 加密配置文件
encrypt_config() {
local input_file=$1
local output_file="${input_file}.encrypted"
local key_file="/etc/config/keys/config.key"
# 使用OpenSSL加密
openssl enc -aes-256-cbc \
-salt \
-in "$input_file" \
-out "$output_file" \
-pass file:"$key_file"
echo "Config encrypted: $output_file"
}
# 解密配置文件
decrypt_config() {
local encrypted_file=$1
local output_file="${encrypted_file%.encrypted}"
local key_file="/etc/config/keys/config.key"
openssl enc -d -aes-256-cbc \
-in "$encrypted_file" \
-out "$output_file" \
-pass file:"$key_file"
}
# 安全加载配置
load_secure_config() {
local config_file=$1
# 解密临时文件
local temp_file=$(mktemp)
decrypt_config "$config_file" "$temp_file"
# 加载配置到环境变量
source "$temp_file"
# 安全删除临时文件
shred -u "$temp_file"
}
配置版本控制与回滚
#!/bin/bash
# config-versioning.sh - 配置版本管理
CONFIG_DIR="/app/config"
BACKUP_DIR="/backups/configs"
MAX_BACKUPS=5
# 备份当前配置
backup_config() {
local timestamp=$(date +%Y%m%d_%H%M%S)
local backup_file="${BACKUP_DIR}/config_${timestamp}.tar.gz"
# 创建备份
tar -czf "$backup_file" -C "$CONFIG_DIR" .
# 记录变更日志
echo "[${timestamp}] Config backed up: $backup_file" >> "${BACKUP_DIR}/changelog.txt"
# 清理旧备份
cleanup_old_backups
}
# 回滚配置
rollback_config() {
local version=$1
local backup_file="${BACKUP_DIR}/config_${version}.tar.gz"
if [ -f "$backup_file" ]; then
# 备份当前配置
backup_config
# 恢复旧版本
tar -xzf "$backup_file" -C "$CONFIG_DIR"
echo "Rolled back to version: $version"
else
echo "Version not found: $version"
exit 1
fi
}
# 清理旧备份
cleanup_old_backups() {
local count=$(ls -1 ${BACKUP_DIR}/config_*.tar.gz 2>/dev/null | wc -l)
if [ "$count" -gt "$MAX_BACKUPS" ]; then
# 删除最旧的备份
ls -t ${BACKUP_DIR}/config_*.tar.gz | tail -n +$((MAX_BACKUPS + 1)) | xargs rm -f
fi
}
# 列出可用版本
list_versions() {
echo "Available config versions:"
for backup in ${BACKUP_DIR}/config_*.tar.gz; do
local version=$(basename "$backup" | sed 's/config_//;s/\.tar\.gz//')
local date_formatted=$(date -d "${version:0:8} ${version:9:4}" "+%Y-%m-%d %H:%M" 2>/dev/null)
echo " - $version ($date_formatted)"
done
}
动态配置生成器
#!/bin/bash
# dynamic-config.sh - 动态配置生成
# Docker Compose配置生成
generate_docker_compose() {
local service_name=$1
local port=${2:-80}
cat > docker-compose.local.yml << EOF
version: '3.8'
services:
${service_name}:
image: ${service_name}:latest
ports:
- "${port}:${port}"
environment:
- NODE_ENV=development
- DB_HOST=localhost
volumes:
- ./config:/app/config
command: npm run dev
EOF
}
# Nginx配置生成
generate_nginx_config() {
local domain=$1
local upstream=$2
local ssl_enabled=${3:-false}
if [ "$ssl_enabled" = true ]; then
cat > "/etc/nginx/sites-available/${domain}.conf" << EOF
server {
listen 443 ssl http2;
server_name ${domain};
ssl_certificate /etc/nginx/ssl/${domain}.crt;
ssl_certificate_key /etc/nginx/ssl/${domain}.key;
location / {
proxy_pass http://${upstream};
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
}
}
EOF
else
cat > "/etc/nginx/sites-available/${domain}.conf" << EOF
server {
listen 80;
server_name ${domain};
location / {
proxy_pass http://${upstream};
}
}
EOF
fi
}
配置热更新与监听
#!/bin/bash
# hot-reload-config.sh - 配置热更新
WATCH_DIR="/app/config"
PID_FILE="/var/run/app.pid"
# 配置文件监听
watch_config() {
echo "Watching config directory: $WATCH_DIR"
# 使用inotifywait监听文件变化
while inotifywait -r -e modify,create,delete "$WATCH_DIR"; do
echo "Configuration changed!"
reload_application
done
}
# 重新加载应用配置
reload_application() {
local app_pid=$(cat "$PID_FILE" 2>/dev/null)
if [ -n "$app_pid" ]; then
# 发送SIGHUP信号重新加载配置
kill -HUP "$app_pid"
echo "Sent reload signal to PID: $app_pid"
fi
}
# 配置文件状态检查
check_config_status() {
local config_hash_file="${WATCH_DIR}/.config_hash"
local current_hash=$(find "$WATCH_DIR" -type f -not -name '.config_hash' -exec md5sum {} \; | md5sum)
if [ -f "$config_hash_file" ]; then
local previous_hash=$(cat "$config_hash_file")
if [ "$current_hash" != "$previous_hash" ]; then
echo "Configuration changed"
echo "$current_hash" > "$config_hash_file"
return 0
fi
else
echo "$current_hash" > "$config_hash_file"
fi
return 1
}
配置文件验证器
#!/bin/bash
# config-validator.sh - 配置文件验证
# JSON配置验证
validate_json_config() {
local config_file=$1
local schema_file=$2
# 检查JSON格式
if ! jq '.' "$config_file" > /dev/null 2>&1; then
echo "Error: Invalid JSON format"
return 1
fi
# 使用schema验证
if [ -n "$schema_file" ] && [ -f "$schema_file" ]; then
if ! jq -e "include \"$schema_file\"; validate(.)" "$config_file" > /dev/null 2>&1; then
echo "Error: Config does not match schema"
return 1
fi
fi
echo "Config validation passed"
return 0
}
# YAML配置验证
validate_yaml_config() {
local config_file=$1
# 检查YAML格式
if ! yq eval '.' "$config_file" > /dev/null 2>&1; then
echo "Error: Invalid YAML format"
return 1
fi
# 检查必需字段
local required_fields=("version" "services")
for field in "${required_fields[@]}"; do
if ! yq eval ".${field}" "$config_file" > /dev/null 2>&1; then
echo "Error: Missing required field: $field"
return 1
fi
done
}
综合使用示例
#!/bin/bash
# main.sh - 主管理脚本
# 使用配置文件管理工具
source ./config-manager.sh
source ./multi-env-config.sh
source ./config-versioning.sh
# 初始化配置目录
init_config() {
mkdir -p /app/config
mkdir -p /backups/configs
mkdir -p /etc/nginx/sites-enabled
# 复制默认配置
cp /app/defaults/*.yaml /app/config/
}
# 管理配置流程
manage_config() {
local action=$1
local env=$2
case $action in
init)
init_config
;;
generate)
generate_config "$env"
;;
backup)
backup_config
;;
rollback)
rollback_config "$env"
;;
validate)
validate_yaml_config "/app/config/application.yaml"
;;
*)
echo "Usage: $0 {init|generate|backup|rollback|validate} [environment]"
exit 1
;;
esac
}
# 主执行
if [ $# -lt 1 ]; then
echo "Usage: $0 {init|generate|backup|rollback|validate} [environment]"
exit 1
fi
manage_config "$@"
这些Shell脚本提供了完整的容器配置文件管理解决方案,包括模板化、版本控制、加密、热更新和验证等功能,根据实际需求选择合适的工具和方法。