利用docker-compose和nginx搭建高可用负载均衡
前言
实验环境
Ubuntu16.04
Docker
Nginx
https://github.com/CTFd/CTFd
ps: 并未实现跨域部署
服务文件以及思路展现
初始的docker-compose.yml里面有一个主服务,一个数据库。
version: '2'
services:
ctfd:
build: .
user: root
restart: always
ports:
- "81:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
db:
image: mariadb:10.4
restart: always
environment:
- MYSQL_ROOT_PASSWORD=ctfd
- MYSQL_USER=ctfd
- MYSQL_PASSWORD=ctfd
- MYSQL_DATABASE=ctfd
volumes:
- .data/mysql:/var/lib/mysql
networks:
internal:
# This command is required to set important mariadb defaults
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --wait_timeout=28800, --log-warnings=0]
cache:
image: redis:4
restart: always
volumes:
- .data/redis:/data
networks:
internal:
networks:
default:
internal:
internal: true
思路就是添加主服务的容器数量并且link同一个数据库容器,通过不同的端口运行主服务,提供机器的高可用性。如果需要使用跨域搭建请参考(openvswitch网桥)
所以现在只需要添加主服务ctf的数量,且分配不同的ip即可。
version: '2'
services:
ctfd1:
build: .
user: root
restart: always
# expose:
# - 8000
ports:
- "81:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
ctfd2:
build: .
user: root
restart: always
# expose:
# - 8000
ports:
- "82:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
ctfd3:
build: .
user: root
restart: always
# expose:
# - 8000
ports:
- "83:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
ctfd4:
build: .
user: root
restart: always
# expose:
# - 8000
ports:
- "84:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
ctfd5:
build: .
user: root
restart: always
# expose:
# - 8000
ports:
- "85:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
ctfd6:
build: .
user: root
restart: always
# expose:
# - 8000
ports:
- "86:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
db:
image: mariadb:10.4
restart: always
environment:
- MYSQL_ROOT_PASSWORD=ctfd
- MYSQL_USER=ctfd
- MYSQL_PASSWORD=ctfd
- MYSQL_DATABASE=ctfd
volumes:
- .data/mysql:/var/lib/mysql
networks:
internal:
# This command is required to set important mariadb defaults
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --wait_timeout=28800, --log-warnings=0]
cache:
image: redis:4
restart: always
volumes:
- .data/redis:/data
networks:
internal:
networks:
default:
internal:
internal: true
在这里我封装成了6个容器,因为这样子编写需要重新build 6个主服务容器的镜像,所以最好是根据原来一个的镜像,执行docker tag命令,因为主服务都是相同的,只要有一个镜像搭建成功就可以了。
这样我们就可以通过6个端口来访问主服务了。(仅仅实现了端口分发)
配置Nginx实现负载均衡
主要的nginx配置内容为
upstream myserver{
server 127.0.0.1:81;
server 127.0.0.1:82;
server 127.0.0.1:83;
server 127.0.0.1:84;
server 127.0.0.1:85;
server 127.0.0.1:86;
}
server {
listen 80;
server_name www.myserver.org;
location / {
proxy_pass http://myserver;
}
}
执行 ./nginx -s reload 或者 重启服务即可实现负载均衡。因为条件有限,如果还需要提高用户的访问速度,可以考虑添加动静分离以及cdn分发,将网页中的js文件或者css文件采用cdn外链。
关于作者

联系方式 - 1290017556@qq.com
你也可以通过 github | csdn | @新浪微博 关注我的动态
欢迎点赞👍评论哟~