- 项目概述
1.1 项目背景
MaxKey是业界领先的企业级IAM身份管理和认证产品,支持OAuth 2.x/OpenID Connect、SAML 2.0、JWT、CAS等标准协议,提供统一身份认证、单点登录(SSO)、RBAC权限管理和资源管理等能力。
1.2 部署目标
构建高可用、可扩展的统一身份认证平台
支持5000+用户并发访问
实现与现有业务系统的无缝集成
确保系统安全性和稳定性
- 系统架构设计
2.1 部署架构
text
┌─────────────────────────────────────────────────┐
│ 负载均衡层 │
│ (Nginx/HAProxy) │
└─────────────────┬───────────────┬───────────────┘
│ │
┌─────────────▼─────┐ ┌───────▼─────────────┐
│ MaxKey应用节点1 │ │ MaxKey应用节点2 │
│ (Docker容器) │ │ (Docker容器) │
└─────────────┬─────┘ └───────┬─────────────┘
│ │
┌─────────────▼────────────────▼─────────────┐
│ Redis集群(哨兵模式) │
└─────────────┬────────────────┬─────────────┘
│ │
┌─────────────▼────────────────▼─────────────┐
│ MySQL主从集群 │
└─────────────────────────────────────────────┘
2.2 技术栈
应用服务器: Tomcat 9/JDK 11
数据库: MySQL 8.0 集群
缓存: Redis 6.x 集群
反向代理: Nginx 1.20+
容器: Docker 20.10+ / Docker Compose
监控: Prometheus + Grafana
日志: ELK Stack
- 环境要求
3.1 硬件配置
角色 CPU 内存 存储 数量
应用节点 4核 8GB 100GB 2
数据库节点 4核 16GB 500GB 2
Redis节点 2核 4GB 50GB 3
Nginx节点 2核 4GB 50GB 2
3.2 软件要求
操作系统: CentOS 7.9+/Ubuntu 20.04+
Docker: 20.10.0+
Docker Compose: 2.0.0+
MySQL: 8.0.26+
Redis: 6.2.6+
Nginx: 1.20.1+
- 详细部署步骤
4.1 环境准备
4.1.1 系统初始化
bash
所有节点执行
sudo hostnamectl set-hostname maxkey-node1
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo setenforce 0
sudo sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/g’ /etc/selinux/config
时间同步
sudo yum install -y ntpdate
sudo ntpdate ntp.aliyun.com
sudo echo “0 */12 * * * /usr/sbin/ntpdate ntp.aliyun.com” >> /var/spool/cron/root
4.1.2 Docker安装
bash
安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
添加Docker源
sudo yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
安装Docker Compose
sudo curl -L “https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s)-$(uname -m)” \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
4.2 数据库部署
4.2.1 MySQL主从配置
主节点配置 (maxkey-mysql-master):
ini
/etc/mysql/my.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
expire_logs_days=7
max_binlog_size=100M
binlog_cache_size=4M
max_binlog_cache_size=512M
从节点配置 (maxkey-mysql-slave):
ini
/etc/mysql/my.cnf
[mysqld]
server-id=2
relay-log=mysql-relay-bin
read_only=1
4.2.2 使用Docker Compose部署MySQL
yaml
docker-compose-mysql.yml
version: ‘3.8’
services:
mysql-master:
image: mysql:8.0.26
container_name: maxkey-mysql-master
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: maxkey
MYSQL_USER: maxkey
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
ports:
– “3306:3306”
volumes:
– ./mysql/master/data:/var/lib/mysql
– ./mysql/master/conf:/etc/mysql/conf.d
– ./mysql/master/init:/docker-entrypoint-initdb.d
networks:
– maxkey-network
mysql-slave:
image: mysql:8.0.26
container_name: maxkey-mysql-slave
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
ports:
– “3307:3306”
volumes:
– ./mysql/slave/data:/var/lib/mysql
– ./mysql/slave/conf:/etc/mysql/conf.d
networks:
– maxkey-network
networks:
maxkey-network:
driver: bridge
4.2.3 初始化数据库
sql
— 在主节点执行
CREATE DATABASE IF NOT EXISTS maxkey DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER ‘maxkey’@’%’ IDENTIFIED BY ‘${MYSQL_PASSWORD}’;
GRANT ALL PRIVILEGES ON maxkey.* TO ‘maxkey’@’%’;
FLUSH PRIVILEGES;
4.3 Redis集群部署
4.3.1 Docker Compose配置
yaml
docker-compose-redis.yml
version: ‘3.8’
services:
redis-node1:
image: redis:6.2.6-alpine
container_name: redis-node1
command: redis-server –port 6379 –cluster-enabled yes –cluster-config-file nodes.conf –cluster-node-timeout 5000 –appendonly yes
ports:
– “6379:6379”
volumes:
– ./redis/node1/data:/data
networks:
– maxkey-network
redis-node2:
image: redis:6.2.6-alpine
container_name: redis-node2
command: redis-server –port 6380 –cluster-enabled yes –cluster-config-file nodes.conf –cluster-node-timeout 5000 –appendonly yes
ports:
– “6380:6380”
volumes:
– ./redis/node2/data:/data
networks:
– maxkey-network
redis-node3:
image: redis:6.2.6-alpine
container_name: redis-node3
command: redis-server –port 6381 –cluster-enabled yes –cluster-config-file nodes.conf –cluster-node-timeout 5000 –appendonly yes
ports:
– “6381:6381”
volumes:
– ./redis/node3/data:/data
networks:
– maxkey-network
networks:
maxkey-network:
driver: bridge
4.3.2 创建Redis集群
bash
进入任一Redis容器
docker exec -it redis-node1 sh
创建集群
redis-cli –cluster create \
172.18.0.4:6379 \
172.18.0.5:6380 \
172.18.0.6:6381 \
–cluster-replicas 0
4.4 MaxKey应用部署
4.4.1 下载和准备MaxKey
bash
创建工作目录
mkdir -p /opt/maxkey && cd /opt/maxkey
下载最新版本
wget https://github.com/dromara/MaxKey/releases/download/v4.0.0/maxkey-4.0.0-ga.zip
unzip maxkey-4.0.0-ga.zip
准备Dockerfile
cat > Dockerfile << EOF
FROM tomcat:9.0-jdk11-openjdk-slim
LABEL maintainer=”maxkey@example.com”
删除默认应用
RUN rm -rf /usr/local/tomcat/webapps/*
拷贝MaxKey应用
COPY maxkey-web-maxkey-4.0.0-ga.war /usr/local/tomcat/webapps/ROOT.war
创建解压目录
RUN mkdir -p /usr/local/tomcat/webapps/ROOT
解压WAR包
RUN unzip /usr/local/tomcat/webapps/ROOT.war -d /usr/local/tomcat/webapps/ROOT/
拷贝配置文件
COPY application.properties /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/
暴露端口
EXPOSE 8080
CMD [“catalina.sh”, “run”]
EOF
4.4.2 应用配置文件
properties
application.properties
数据库配置
maxkey.db.type=mysql
maxkey.db.url=jdbc:mysql://maxkey-mysql-master:3306/maxkey?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
maxkey.db.username=maxkey
maxkey.db.password=${MYSQL_PASSWORD}
Redis配置
maxkey.redis.host=redis-node1,redis-node2,redis-node3
maxkey.redis.port=6379,6380,6381
maxkey.redis.password=
maxkey.redis.cluster=true
maxkey.redis.timeout=10000
会话配置
server.servlet.session.timeout=7200
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=false
安全配置
maxkey.sso.cookie.domain=.example.com
maxkey.sso.cookie.path=/
4.4.3 Docker Compose部署应用
yaml
docker-compose-app.yml
version: ‘3.8’
services:
maxkey-app1:
build: .
container_name: maxkey-app1
restart: always
ports:
– “8081:8080”
environment:
– JAVA_OPTS=-Xms2g -Xmx2g -XX:+UseG1GC -Djava.security.egd=file:/dev/./urandom
volumes:
– ./logs/app1:/usr/local/tomcat/logs
depends_on:
– mysql-master
– redis-node1
networks:
– maxkey-network
healthcheck:
test: [“CMD”, “curl”, “-f”, “http://localhost:8080/login”]
interval: 30s
timeout: 10s
retries: 3
maxkey-app2:
build: .
container_name: maxkey-app2
restart: always
ports:
– “8082:8080”
environment:
– JAVA_OPTS=-Xms2g -Xmx2g -XX:+UseG1GC -Djava.security.egd=file:/dev/./urandom
volumes:
– ./logs/app2:/usr/local/tomcat/logs
depends_on:
– mysql-master
– redis-node1
networks:
– maxkey-network
healthcheck:
test: [“CMD”, “curl”, “-f”, “http://localhost:8080/login”]
interval: 30s
timeout: 10s
retries: 3
networks:
maxkey-network:
external: true
4.5 Nginx负载均衡配置
4.5.1 Nginx配置文件
nginx
/etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# 开启gzip压缩
gzip on;
gzip_min_length 1k;
gzip_comp_level 2;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss;
# 负载均衡配置
upstream maxkey_backend {
least_conn;
server 192.168.1.101:8081 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8082 max_fails=3 fail_timeout=30s;
keepalive 32;
}
server {
listen 80;
server_name sso.example.com;
# 重定向到HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name sso.example.com;
ssl_certificate /etc/nginx/ssl/sso.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/sso.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://maxkey_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 30s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_buffering off;
}
# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
proxy_pass http://maxkey_backend;
}
}
}
4.5.2 Docker部署Nginx
yaml
docker-compose-nginx.yml
version: ‘3.8’
services:
nginx:
image: nginx:1.20-alpine
container_name: maxkey-nginx
restart: always
ports:
– “80:80”
– “443:443”
volumes:
– ./nginx/conf:/etc/nginx
– ./nginx/logs:/var/log/nginx
– ./nginx/ssl:/etc/nginx/ssl
networks:
– maxkey-network
4.6 监控和日志配置
4.6.1 Prometheus配置
yaml
prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: ‘maxkey-app’
metrics_path: ‘/actuator/prometheus’
static_configs:- targets: [‘maxkey-app1:8080’, ‘maxkey-app2:8080’]
labels:
application: ‘maxkey’
- targets: [‘maxkey-app1:8080’, ‘maxkey-app2:8080’]
- job_name: ‘nginx’
static_configs:- targets: [‘nginx:9113’]
labels:
service: ‘nginx’
4.6.2 应用监控配置
在application.properties中添加:
- targets: [‘nginx:9113’]
properties
监控配置
management.endpoints.web.exposure.include=health,info,metrics,prometheus
management.metrics.export.prometheus.enabled=true
management.endpoint.health.show-details=always
- 初始化配置
5.1 数据库初始化
bash
执行数据库初始化脚本
mysql -h maxkey-mysql-master -u maxkey -p maxkey < /opt/maxkey/sql/maxkey.sql
mysql -h maxkey-mysql-master -u maxkey -p maxkey < /opt/maxkey/sql/maxkey_data.sql
5.2 MaxKey初始配置
访问 https://sso.example.com
使用默认管理员登录:
用户名:administrator
密码:maxkey
修改管理员密码
配置组织架构
导入用户或配置LDAP连接
配置应用集成
5.3 应用集成配置
以集成GitLab为例:
yaml
GitLab OAuth配置
applicationName: GitLab
applicationKey: gitlab
applicationSecret: ${GITLAB_SECRET}
redirectUri: https://sso.example.com/oauth/authorize
provider: gitlab
scope: read_user openid profile email
- 备份和恢复策略
6.1 数据库备份
bash
!/bin/bash
backup_mysql.sh
BACKUP_DIR=”/backup/mysql”
DATE=$(date +%Y%m%d_%H%M%S)
备份数据库
mysqldump -h maxkey-mysql-master -u maxkey -p${MYSQL_PASSWORD} \
–single-transaction \
–routines \
–triggers \
–events \
maxkey | gzip > ${BACKUP_DIR}/maxkey_${DATE}.sql.gz
保留最近7天备份
find ${BACKUP_DIR} -name “maxkey_*.sql.gz” -mtime +7 -delete
6.2 Redis备份
bash
!/bin/bash
backup_redis.sh
BACKUP_DIR=”/backup/redis”
DATE=$(date +%Y%m%d_%H%M%S)
备份Redis
redis-cli –cluster backup ${BACKUP_DIR}/redis_${DATE}.rdb
保留最近7天备份
find ${BACKUP_DIR} -name “redis_*.rdb” -mtime +7 -delete
- 安全配置
7.1 SSL/TLS配置
bash
使用Let’s Encrypt获取证书
certbot certonly –nginx -d sso.example.com \
–email admin@example.com \
–agree-tos \
–non-interactive
7.2 安全加固
修改默认端口
配置防火墙规则
启用WAF防护
定期安全扫描
审计日志监控
- 维护和监控
8.1 日常维护任务
监控系统资源使用情况
检查日志文件中的错误信息
定期备份数据库和配置文件
更新系统和应用补丁
8.2 监控指标
应用响应时间
系统负载
数据库连接数
缓存命中率
错误率
- 故障排除
9.1 常见问题
应用无法启动:检查日志文件,确认数据库连接
单点登录失败:检查Redis集群状态
性能下降:检查数据库连接池和缓存命中率
9.2 故障恢复流程
确认故障现象和影响范围
检查应用日志和系统监控
根据故障类型执行恢复操作
验证恢复结果
记录故障报告和改进措施
- 附录
10.1 配置文件模板
所有配置文件模板可在 /opt/maxkey/config-templates/ 目录找到
10.2 部署检查清单
环境准备完成
数据库集群部署完成
Redis集群部署完成
MaxKey应用部署完成
Nginx负载均衡配置完成
SSL证书配置完成
监控系统部署完成
备份策略配置完成
安全加固完成
测试验证通过
10.3 性能测试建议
使用JMeter进行压力测试,验证系统在以下场景下的表现:
500用户并发登录
1000用户并发访问
会话持久化测试
故障切换测试
部署完成时间预估:4-6小时
人员要求:2名中级运维工程师
注意事项:生产环境部署前务必在测试环境充分验证