第 15 章:生产最佳实践
第 15 章:生产最佳实践
Alpine Linux 在生产环境中的部署规范、Docker 最佳实践和安全基线。
15.1 服务器部署规范
系统初始化清单
| 步骤 | 操作 | 优先级 |
|---|---|---|
| 1 | 系统更新 apk update && apk upgrade | 必须 |
| 2 | 设置时区 setup-timezone Asia/Shanghai | 必须 |
| 3 | 创建管理员用户 | 必须 |
| 4 | 配置 SSH 密钥认证 | 必须 |
| 5 | 禁用 root 密码登录 | 必须 |
| 6 | 配置防火墙 | 必须 |
| 7 | 安装 Fail2Ban | 推荐 |
| 8 | 配置 NTP 时间同步 | 推荐 |
| 9 | 设置日志轮转 | 推荐 |
| 10 | 配置监控告警 | 推荐 |
自动化部署脚本
cat > /usr/local/bin/prod-init << 'SCRIPT'
#!/bin/sh
set -e
echo "=== Alpine Production Init ==="
# 1. 系统更新
echo "[1/10] Updating system..."
apk update && apk upgrade
# 2. 安装基础工具
echo "[2/10] Installing base packages..."
apk add --no-cache \
bash bash-completion \
vim htop tmux \
curl wget \
openssh \
sudo \
chrony \
logrotate \
fail2ban
# 3. 时区配置
echo "[3/10] Setting timezone..."
setup-timezone Asia/Shanghai
# 4. 创建管理员用户
echo "[4/10] Creating admin user..."
ADMIN_USER="admin"
adduser -D -s /bin/bash "$ADMIN_USER"
addgroup "$ADMIN_USER" wheel
echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel
chmod 440 /etc/sudoers.d/wheel
# 5. SSH 配置
echo "[5/10] Configuring SSH..."
cat > /etc/ssh/sshd_config << 'SSHEOF'
Port 22
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowAgentForwarding no
SSHEOF
# 6. 防火墙
echo "[6/10] Configuring firewall..."
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
/etc/init.d/iptables save
# 7. NTP
echo "[7/10] Configuring NTP..."
rc-update add chronyd
rc-service chronyd start
# 8. 内核参数
echo "[8/10] Tuning kernel parameters..."
cat >> /etc/sysctl.conf << 'SYSEOF'
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.ip_local_port_range = 1024 65535
vm.swappiness = 10
fs.file-max = 2097152
SYSEOF
sysctl -p
# 9. 日志轮转
echo "[9/10] Configuring logrotate..."
cat > /etc/logrotate.d/messages << 'LOGEOF'
/var/log/messages {
daily
rotate 14
compress
delaycompress
missingok
notifempty
}
LOGEOF
# 10. 启动服务
echo "[10/10] Starting services..."
rc-update add sshd default
rc-service sshd start
echo "=== Production init complete! ==="
echo "Please add your SSH public key to /home/$ADMIN_USER/.ssh/authorized_keys"
SCRIPT
chmod +x /usr/local/bin/prod-init
15.2 Docker 最佳实践
Dockerfile 规范
# 1. 使用明确的版本标签
FROM alpine:3.20
# 2. 元数据标签
LABEL maintainer="[email protected]"
LABEL version="1.2.3"
LABEL description="Production API Server"
# 3. 安全:创建非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# 4. 安装依赖:单层 + --no-cache
RUN apk add --no-cache \
ca-certificates \
tini \
&& update-ca-certificates
# 5. 设置工作目录
WORKDIR /app
# 6. 先复制依赖文件(利用缓存)
COPY go.mod go.sum ./
RUN go mod download
# 7. 复制源码并构建
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app/server .
# 8. 多阶段构建:生产镜像
FROM alpine:3.20
RUN apk add --no-cache ca-certificates tini
COPY --from=builder /app/server /usr/local/bin/server
# 9. 非 root 用户运行
USER appuser
# 10. 暴露端口
EXPOSE 8080
# 11. 健康检查
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1
# 12. 使用 tini 作为 PID 1
ENTRYPOINT ["tini", "--"]
CMD ["server"]
Docker Compose 生产配置
version: "3.8"
services:
app:
image: myapp:1.2.3
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
networks:
- frontend
- backend
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
read_only: true
tmpfs:
- /tmp
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
networks:
- backend
deploy:
resources:
limits:
memory: 512M
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./certs:/etc/nginx/certs:ro
networks:
- frontend
depends_on:
- app
networks:
frontend:
backend:
volumes:
pgdata:
secrets:
db_password:
file: ./secrets/db_password.txt
15.3 安全基线
CIS Benchmark 配置
# 1. 文件系统加固
chmod 600 /etc/shadow
chmod 600 /etc/gshadow
chmod 644 /etc/passwd
chmod 644 /etc/group
chmod 700 /root
chmod 600 /etc/ssh/sshd_config
# 2. 禁用不需要的文件系统
cat >> /etc/modprobe.d/disable-fs.conf << 'EOF'
install cramfs /bin/true
install freevxfs /bin/true
install hfs /bin/true
install hfsplus /bin/true
install jffs2 /bin/true
install udf /bin/true
EOF
# 3. 禁用不需要的网络协议
cat >> /etc/modprobe.d/disable-net.conf << 'EOF'
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true
EOF
# 4. 设置密码策略
apk add libpwquality
cat > /etc/security/pwquality.conf << 'EOF'
minlen = 12
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
EOF
# 5. 配置审计
apk add audit
cat > /etc/audit/audit.rules << 'EOF'
-D
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshd
-a always,exit -F arch=b64 -S execve -k exec
EOF
rc-update add auditd
安全扫描脚本
cat > /usr/local/bin/security-audit << 'SCRIPT'
#!/bin/sh
echo "=== Alpine Security Audit Report ==="
echo "Date: $(date)"
echo "Hostname: $(hostname)"
echo ""
echo "--- 系统信息 ---"
echo "Alpine: $(cat /etc/alpine-release)"
echo "Kernel: $(uname -r)"
echo "Uptime: $(uptime)"
echo ""
echo "--- 用户检查 ---"
echo "Root login: $(grep '^PermitRootLogin' /etc/ssh/sshd_config 2>/dev/null || echo 'Not configured')"
echo "Password auth: $(grep '^PasswordAuthentication' /etc/ssh/sshd_config 2>/dev/null || echo 'Not configured')"
echo "Empty passwords: $(awk -F: '($2 == "") {print $1}' /etc/shadow)"
echo ""
echo "--- 文件权限 ---"
echo "World-writable files: $(find / -xdev -type f -perm -0002 2>/dev/null | wc -l)"
echo "SUID files: $(find / -xdev -type f -perm -4000 2>/dev/null | wc -l)"
echo "SGID files: $(find / -xdev -type f -perm -2000 2>/dev/null | wc -l)"
echo ""
echo "--- 网络 ---"
echo "Listening ports:"
ss -tlnp | grep LISTEN
echo ""
echo "--- 防火墙 ---"
iptables -L -n --line-numbers 2>/dev/null | head -20
echo ""
echo "--- 磁盘 ---"
df -h | grep -E '^/dev'
echo ""
echo "--- 可更新包 ---"
apk update > /dev/null 2>&1
UPDATES=$(apk version -l '<' 2>/dev/null | wc -l)
echo "Available updates: $UPDATES"
echo ""
SCRIPT
chmod +x /usr/local/bin/security-audit
15.4 监控与告警
基础监控脚本
cat > /usr/local/bin/health-check << 'SCRIPT'
#!/bin/sh
# 阈值
CPU_THRESHOLD=90
MEM_THRESHOLD=85
DISK_THRESHOLD=90
# CPU 使用率
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print int($2 + $4)}')
if [ "$CPU_USAGE" -gt "$CPU_THRESHOLD" ]; then
logger -t health-check "ALERT: CPU usage ${CPU_USAGE}%"
fi
# 内存使用率
MEM_USAGE=$(free | awk '/Mem:/ {printf("%.0f", $3/$2 * 100)}')
if [ "$MEM_USAGE" -gt "$MEM_THRESHOLD" ]; then
logger -t health-check "ALERT: Memory usage ${MEM_USAGE}%"
fi
# 磁盘使用率
for line in $(df -h | grep -E '^/dev' | awk '{print $5 "|" $6}'); do
USAGE=$(echo "$line" | cut -d'|' -f1 | tr -d '%')
MOUNT=$(echo "$line" | cut -d'|' -f2)
if [ "$USAGE" -gt "$DISK_THRESHOLD" ]; then
logger -t health-check "ALERT: Disk ${MOUNT} usage ${USAGE}%"
fi
done
# 服务检查
for svc in nginx sshd; do
if ! rc-service "$svc" status > /dev/null 2>&1; then
logger -t health-check "ALERT: Service $svc is down"
fi
done
SCRIPT
chmod +x /usr/local/bin/health-check
# 定期执行
echo "*/5 * * * * /usr/local/bin/health-check" >> /etc/crontabs/root
15.5 备份策略
自动备份脚本
cat > /usr/local/bin/backup << 'SCRIPT'
#!/bin/sh
set -e
BACKUP_DIR="/backup"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
LOGFILE="/var/log/backup.log"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOGFILE"
}
log "Starting backup..."
# 创建备份目录
mkdir -p "$BACKUP_DIR/$DATE"
# 系统配置备份
log "Backing up system config..."
tar -czf "$BACKUP_DIR/$DATE/etc.tar.gz" /etc/
# 应用数据备份
log "Backing up application data..."
tar -czf "$BACKUP_DIR/$DATE/app.tar.gz" /opt/app/ 2>/dev/null || true
# 数据库备份
if command -v pg_dump > /dev/null 2>&1; then
log "Backing up PostgreSQL..."
su - postgres -c "pg_dump -Fc appdb" > "$BACKUP_DIR/$DATE/appdb.dump"
fi
if command -v mysqldump > /dev/null 2>&1; then
log "Backing up MySQL..."
mysqldump --single-transaction appdb > "$BACKUP_DIR/$DATE/appdb.sql"
fi
# Docker 卷备份
if command -v docker > /dev/null 2>&1; then
log "Backing up Docker volumes..."
for vol in $(docker volume ls -q); do
docker run --rm -v "$vol":/data -v "$BACKUP_DIR/$DATE":/backup \
alpine tar -czf "/backup/vol_${vol}.tar.gz" /data
done
fi
# 清理旧备份
log "Cleaning old backups..."
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
# 备份完整性检查
log "Verifying backup..."
if [ -f "$BACKUP_DIR/$DATE/etc.tar.gz" ]; then
log "Backup completed successfully"
else
log "ERROR: Backup verification failed"
exit 1
fi
SCRIPT
chmod +x /usr/local/bin/backup
# 每天凌晨 3 点执行
echo "0 3 * * * /usr/local/bin/backup" >> /etc/crontabs/root
15.6 性能优化
系统调优参数
cat >> /etc/sysctl.conf << 'EOF'
# === 性能优化参数 ===
# 网络性能
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.ip_local_port_range = 1024 65535
# 文件系统
fs.file-max = 2097152
fs.nr_open = 1048576
# 内存
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
vm.overcommit_memory = 1
EOF
# 用户限制
cat >> /etc/security/limits.conf << 'EOF'
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
EOF
15.7 本章小结
生产部署检查清单
| 类别 | 检查项 | 状态 |
|---|---|---|
| 系统 | 最小化安装 | ☐ |
| 系统 | 自动安全更新 | ☐ |
| 认证 | SSH 密钥认证 | ☐ |
| 认证 | 禁用 root 密码 | ☐ |
| 网络 | 防火墙配置 | ☐ |
| 网络 | 仅开放必要端口 | ☐ |
| 监控 | 系统监控 | ☐ |
| 监控 | 服务健康检查 | ☐ |
| 备份 | 自动备份 | ☐ |
| 备份 | 备份验证 | ☐ |
| Docker | 多阶段构建 | ☐ |
| Docker | 非 root 运行 | ☐ |
| Docker | 健康检查 | ☐ |
| Docker | 资源限制 | ☐ |
| 安全 | 审计日志 | ☐ |
| 安全 | Fail2Ban | ☐ |
扩展阅读
上一章:第 14 章:嵌入式应用 返回目录:Alpine Linux 完全指南