Docker Swarm(十一)生产环境使用的一些建议
一、Docker Swarm上的容器选择
并非所有服务都应该部署在Swarm集群内。数据库以及其他有状态服务就不适合部署在Swarm集群内。
理论上,你可以通过使用labels将容器部署到特定节点上,但是这样的话,Swarm集群外的节点就很难访问它们了(Docker 1.12没有很好的方法,但是1.13之后可以使用attachable network)。
如果你允许集群外的节点访问数据库,则所有节点都可以访问它,这显然不符合你的需求。
另外,Docker Swarm的跨节点数据卷(cross-host mounted volumes)并不可靠,一个简单的文件上传都可能引起问题。
无状态的容器就非常适合部署在Swarm集群中,它们可以由环境变量进行配置(使用ENV指令)。建议为开源工具构建镜像,例如,可以将Nginx的配置文件放到Docker镜像中。
在Swarm集群中的服务:
- Django channels (网页应用)
- Nginx(代理)
- Celery(周期性任务)
- Sensu(监控)
在Swarm集群之外的容器:
- Mysql(数据库)
- Redis(缓存)
由于一个获取真正IP的问题,我很可能会将Nginx运行在Swarm集群之外,或者采用host模式。
二、设置资源限制
就经验而言,可以为所有服务设置CPU使用限制。当某一个容器应用占用掉所有主机资源时,此限制可以避免这种情况发生。
当想把所有容器均匀地发布在所有主机上或是想确保有足够的资源来响应操作时,需使用Reserve-cpu这个参数。
例如:
# 限制服务占用的CPU资源
docker service update
--limit-cpu 0.25
--reserve-cpu 0.1
webapp
三、将半无状态的服务变得完全无状态
所谓半无状态服务,就是容器需要依赖一些不太重要的外部文件。你可以使用数据卷(volume),但是更好的选择是使用S3或者其他云存储服务。
记住,想要获得扩展性,云是最好的选择。
例如,我不得不构建Nginx镜像,将配置文件放到镜像中。使用数据卷挂载Nginx配置文件不是很方便。
四、创建可附加的网络
network是一个非常重要的特性。你最好使用它,否则docker run
创建的容器将无法接入Swarm集群的网络,特别是跨宿主机通讯时。
这是Docker 1.13之后的版本才有的功能,也许你需要升级。
创建network的命令如下:
docker network create --driver=overlay --attachable core
五、增加环境变量
如果创建Docker镜像的时候,遵循了最佳实践原则(https://rock-it.pl/how-to-wri...),允许在运行的时候通过环境变量设置一切配置项,那么把应用迁到Swarm的过程完全没有问题。
相关命令:
# 创建服务时指定环境变量
docker service create \ --env VAR=VALUE \ --env-file FILENAME \ ...
# 增加、删除环境变量 docker service update \ --env-add VAR=NEW_VALUE \ --env-rm VAR \ ..
六、设置适当实例和批量更新
保持适当数量的实例,以应对高流量和实例或者节点不可用的情况。同时太多的实例数也会占用CPU和内存,并且导致争抢CUP资源。
update-parallelism的默认值是1,默认只有一个实例在运行。但这个更新速度太慢了,建议是 replicas / 2。
相关命令:
# 将同时更新的容器数设为10 docker service update \ --update-parallelism 10 \ webapp # 同时增加多个服务的容器数 docker service scale redis=1 nginx=4 webapp=20 # 查看服务状态 docker service ls # 查看服务的详情(排除关闭的容器) docker service ps webapp | grep -v "Shutdown"
七、把Swarm配置保存为代码
最好使用Docker Compose v3版本的语法(https://docs.docker.com/compo...)。
他允许使用代码指定几乎所有的服务选项。作者在开发的时候使用 Docker-compose.yml,在生产环境(swarm)配置使用 Docker-compose.prod.yml . 部署Docker-compose文件中所描述的服务,需要Docker stack deploy 命令(属于新版本 Stack命令集合中的一部分[https://docs.docker.com/engin...)
Docker compose v3例子:
version: '3' services: webapp: image: registry.example.com/webapp networks: - ingress deploy: replicas: ${WEBAPP_REPLICAS} mode: replicated restart_policy: condition: on-failure proxy: image: registry.example.com/webapp-nginx-proxy networks: - ingress ports: - 80:80 - 443:443 deploy: replicas: ${NGINX_REPLICAS} mode: replicated restart_policy: condition: on-failure networks: ingress: external: true
部署的例子(创建或者更新服务):
export NGINX_REPLICAS=2 WEBAPP_REPLICAS=5 docker login registry.example.com docker stack deploy \ -c docker-compose.prod.yml\ --with-registry-auth \ frontend
提示:Docker-compose文件支持环境变量 (${VARIABLE}), 所以,可以动态调整配置作为测试等。
八、配置日志收集服务
使用分布式系统时,集中管理日志是非常必要的。我们有很多方案,包括开源工具或者SaaS服务,比如ELK,Grafana, Graylog…自己搭建完整的系统是非常复杂的,所以我建议搭建先使用SaaS服务(比如Loggly, Logentries ),当费用太高时,则自己搭建一个系统。ELK可以这样配置:
docker service update \
--log-driver gelf \
--log-opt gelf-address=udp://monitoring.example.com:12201 \
--log-opt tag=example-tag \
example-service
参考:https://www.cnblogs.com/fundebug/p/6823897.html