本文参考使用Docker打造自己的云平台编写
本文基于 Docker Swarm Mode 实现容器化,虽然目前 k8s 更火一些,但实在是太重了,以后再折腾。
使用 traefik 来实现反向代理、负载均衡,traefik 还自带了服务发现、后端断路器、健康检查等,相当于是自带服务发现的 nginx。当然它还支持其他的容器编排工具如,服务发现工具如 Consul。
使用 Portainer 来管理 Docker 容器,可以兼容 Docker Swarm 模式。
Docker 的安装就不说了。装完初始化 Swarm 模式。
先设置一下环境变量。
1
| $ export DOCKER_DEV_PATH=/usr/local/src/docker-dev
|
日志文件都会统一存到 ${DOCKER_DEV_PATH}/logs。
traefik
新建一个编排文件 traefik.yml。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| version: '3.3' services: reverse-proxy: image: traefik:1.7-alpine command: --web --docker --docker.domain=cloud-labs.io --docker.watch --docker.swarmmode=true --loglevel=INFO --accesslog --accesslog.filepath=/logs/access.log --traefiklog --traefiklog.filepath=/logs/traefik.log deploy: mode: replicated replicas: 1 labels: - traefik.enable=true - traefik.backend=traefik - traefik.frontend.rule=Host:monitor.cloud-labs.io - traefik.port=8080 - traefik.docker.network=traefik_proxy networks: - proxy ports: - 8081:80 volumes: - /var/run/docker.sock:/var/run/docker.sock - ${DOCKER_DEV_PATH}/logs/traefik:/logs - /dev/null:/traefik.toml networks: proxy:
|
简单解释下 labels 中配置的含义
1 2 3 4
| traefik.backend 后端 traefik.frontend.rule 前端规则,满足此规则转发给后端 traefik.port 后端端口 8080 是 traefik web 后台端口 traefik.docker.network 指定网络
|
更多可用 labels 可用看该Traefik 文档
因为在腾讯云上做的测试没有域名备案,映射了8081端口到80。
部署traefik
1
| $ docker stack deploy -c traefik.yml traefik
|
完成后访问 monitor.cloud-labs.io:8081 就可以进入 traefik 的后台界面了(当然这个域名是要绑host的)。
Portainer
Portainer是一个轻量级的Docker环境管理UI。
新建一个编排文件 portainer.yml。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| version: '3.3' services: server: image: portainer/portainer command: -H unix:///var/run/docker.sock networks: - traefik_proxy deploy: labels: - traefik.enable=true - traefik.backend=portainer - traefik.frontend.rule=Host:console.cloud-labs.io - traefik.docker.network=traefik_proxy - traefik.port=9000 volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer:/data networks: traefik_proxy: external: true volumes: portainer:
|
部署
1
| $ docker stack deploy -c portainer.yml portainer
|
访问 console.cloud-labs.io:8081 就可以管理 Docker 了。
部署一个PHP服务
php服务部署其实还是有些麻烦的。一般前端起nginx将php请求转发到php-fpm,这个时候用的是FastCGI协议。但是目前traefik不支持FastCGI协议,估计以后也不会支持,所以php和nginx要一块部署。如下配置文件。
新建一个编排文件 nginx_php_web.yml,其中包含nginx和php。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| version: '3.3' services: nginx: image: nginx:latest volumes: - ${DOCKER_DEV_PATH}/logs/nginx:/data/logs/nginx - ${DOCKER_DEV_PATH}/test_code/php:/code - ./site.conf:/etc/nginx/conf.d/default.conf depends_on: - php networks: - traefik_proxy deploy: mode: replicated replicas: 2 labels: - traefik.backend=nginx - traefik.frontend.passHostHeader=true - traefik.frontend.rule=Host:domain.cloud-labs.io - traefik.docker.network=traefik_proxy - traefik.port=80 php: image: php:5.5.38-fpm volumes: - ./php.ini:/usr/local/etc/php/php.ini - ./php-fpm.conf:/usr/local/etc/php-fpm.conf - ./www.conf:/usr/local/etc/php-fpm.d/www.conf - ${DOCKER_DEV_PATH}/test_code/php:/code - ${DOCKER_DEV_PATH}/logs/php:/data/logs/php networks: - traefik_proxy deploy: mode: replicated replicas: 3 labels: - traefik.enable=false networks: traefik_proxy: external: true
|
部署
1
| $ docker stack deploy -c nginx_php_web.yml nginx_php_web
|
访问 domain.cloud-labs.io:8081 可以看到服务已经起来了。
但是这种方式会有问题
- 因为请求是从traefik直接到nginx,做健康检查的话只能在nginx上写规则,这样会有问题。除非将nginx和php构建到一个镜像中,但是这又违反了docker的初衷。
- 经过traefik->nginx->php 性能也会应该有所损耗。
另一种方式通过php的swoole扩展起一个http服务,直接将请求转发过去。
建一个Dockerfile,build一个带swoole的php镜像。这里用了最新的php版本。
1 2 3 4 5
| FROM php:7.3.8-cli RUN pecl channel-update pecl.php.net
RUN pecl install swoole-4.4.0 \ && docker-php-ext-enable swoole
|
1
| $ docker build -t php7.3.8_swoole4.4.0 . > build.log &
|
很简单没有遇见任何问题。
再建一个编排文件 php_web.yml。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| version: '3.3' services: swoole_http: image: php7.3.8_swoole4.4.0:latest command: php /code/httpServ.php 8888 volumes: - ${DOCKER_DEV_PATH}/test_code/php:/code - ${DOCKER_DEV_PATH}/logs/swoole:/data/logs/swoole networks: - traefik_proxy deploy: mode: replicated replicas: 2 labels: - traefik.backend=swoole_http - traefik.frontend.passHostHeader=true - traefik.frontend.rule=Host:domain.cloud-labs.io - traefik.docker.network=traefik_proxy - traefik.port=8888 - traefik.backend.healthcheck.hostname=domain.cloud-labs.io - traefik.backend.healthcheck.port=8888 - traefik.backend.healthcheck.path=/healthcheck.php - traefik.backend.healthcheck.interval=5s networks: traefik_proxy: external: true
|
其中做了健康检查每五秒一次。httpServ.php的内容整理完发到github上了,文末有说明。
部署起来。
1 2
| $ docker stack rm nginx_php_web $ docker stack deploy -c php_web.yml php_web
|
效果
traefik 界面
Portainer 界面
跑是跑起来了,但还有些问题。
- docker swarm目前只是单节点
- 容器日志、监控处理的不太好
- 压力测试也没有做
- 没有关联CI/CD
坑挖的有点多慢慢填吧。。
文中所有配置文件都整理完发到github上了,地址 https://github.com/zyh94946/docker-dev