专栏名称: 云技术实践
关注云计算,云技术,云运维,云存储,存储,分布式,OpenStack,SDN,Ceph,虚拟化,运维,分享在云计算/虚拟化/运维项目实施中的资讯、经验、技术,坚持干货。
目录
相关文章推荐
架构师之路  ·  你的提示词根本只是在浪费算力,如何让deep ... ·  18 小时前  
架构师之路  ·  你的提示词根本只是在浪费算力,让deepse ... ·  昨天  
架构师之路  ·  90%的用户不知道!触发DeepSeek深度 ... ·  2 天前  
架构师之路  ·  你的提示词根本只是在浪费算力,能让deeps ... ·  3 天前  
51好读  ›  专栏  ›  云技术实践

Docker Swarm在生产环境中的进阶指南

云技术实践  · 公众号  · 架构  · 2017-06-08 07:44

正文

当在本地开发环境中使用Docker,或者已经在单台生产服务器上部署Docker,却发现它不足以支撑更多的流量。应该如何解决?本文将给出若干提示,如何在生产环境中使用Docker Swarm。


附:如果对Swarm不熟悉,请查看之前的文章 《你可能需要知道的关于Docker Swarm的经验分享》


阅读官方文档


这里不重复官方Swarm的入门教程和文档。入门教程很简短,它会让你明白Swarm是如何工作的。这里也不讲解设置和部署Swarm环境,网上有很多初级的教程,可供参考如——


Digitalocean上的教程 :( https://www.digitalocean.com/community/tutorials/how-to-create-a-cluster-of-docker-containers-with-docker-swarm-and-digitalocean-on-ubuntu-16-04


或者google搜索相关教程。


附:一个牛X的: Ansible role (

https://galaxy.ansible.com/atosatto/docker-swarm/)


Docker Swarm用法实例



就观察而言,用于Swarm内部信息共享和调度的Cpu开销确实很低。得益于此,管理节点同时也可以是工作节点。如果要跑一个1000+个节点的大集群,管理节点开销需要非常多的资源,但当集群是小规模到中等规模时,这种资源消耗和开销是可以忽略不计的。参考这里——

https://sematext.com/blog/2016/11/14/docker-swarm-lessons-from-swarm3k/ Swarm3k , 一个运行4700个节点的集群实验。


  • 路由匹配(服务发现、负载均衡、跨容器通讯)非常可靠。在单个端口上运行一个服务,Swarm节点的任意主机都可以访问,负载均衡完全在后台实现。之前遇到过一些难题,但使用Docker1.13版本后,问题得到解决。


  • 在配置初始化完成后,只需要几行命令作为日常运维。下面是日常使用的命令:


# let's create new service  创建一个新的服务

docker service create \

--image nginx \

--replicas 2 \

nginx


# ... update service ...   更新服务

docker service update \

--image nginx:alpine \

nginx


# ... and remove   删除服务

docker service rm nginx


# but usually it's better to scale down 但是更好的办法是缩容,而不是直接删除服务

docker service scale nginx=0


# you can also scale up   扩容

docker service scale nginx=5


# show all services 列出所有的服务

docker service ls


# show containers of service with status   列出一个服务的所有实例(包括服务的健康状况)

docker service ps nginx


# detailed info  服务的详细信息

docker service inspect nginx

  • 服务零宕机,完美的持续部署方案。


# lets build new version and push to the registry 创建新版本的镜像,并且推送到registry

docker build -t hub.docker.com/image .

docker push hub.docker.com/image


# and now just update (on a master node) 现在更新服务(在master节点上)

docker service update --image hub.docker.com/image service

  • 易于启动:分布式系统本身就很复杂。相比于其他解决方案(Mesos, Kubernetes), Swarm简单易学,即便无任何Swarm的知识,从单台服务器Docker-compose方式的部署,扩展到20台服务器,分布式可伸缩的解决方案,也只需要大约一周。


  • 无需修改。容器实例同时跑在多台服务器上。修改任何东西,都需要打包一个新的镜像,适当的测试和部署是成功的关键。



Docker Swarm上的容器选择



不是所有的应用都适合跑在Docker swarm上 ,比如,数据库和一些有状态的服务。


从理论上而言,可以使用标签的方式固定某个容器跑在某个特定的资源上,但是,更难的是从Swarm集群外部来访问这个容器提供的服务。(在Docker1.12版本里面没有简单的方式来实现,在Docker1.13+版本可以使用附加的Overlay 网络模式)。


比如,想开放一个数据库服务给外部访问,让外部所有节点都可以访问数据库,但是这不是真正想要实现的结果(只想让特定节点访问数据库)


又如,Swarm里面的跨主机存储卷挂载Docker1.13之前还不可靠,用户上传文件这样简单的操作也会引发问题。


适用于容器化的是那些由环境变量驱动无状态的应用容器。是时候准备Docker镜像了,例如配置完善的Nginx镜像。


跑在Swarm上的服务

  • web服务器(Django channels - Daphne and workers)

  • 反向代理(Nginx)

  • Periodic workers (Celery)

  • 指标收集器 (Sensu)


不跑在Swarm上的服务

  • 数据库(Postgres)

  • Redis


由于获取真实IP的问题(https://github.com/moby/moby/issues/25526),也会把Sginx单独移出来不跑在Swarm模式下,至少应该使用Nost网络模式,但在Docker 1.12版本下,这是唯一的选择。


设置好Docker仓库

Docker仓库或是自己的服务器,也许是Dockerhub、 Gitlab.com(作者选择这个)此类。在服务器上创建镜像已经不适用了,因为有太多服务器且在创建服务时( Docker service create)要指明镜像。 如果仓库是私有仓库,记得增加--with-registry-auth 这个参数 ,否则其他节点无法拉取镜像。同时应该使用Tag来标明发布的版本号,这样发现问题时可以快速回滚。


改造无状态化应用容器



“部分有状态”是指有一些共享而不重要的文件。可以尝试使用共享存储卷挂载,更好的方法是迁移到亚马逊S3或者其他云存储。记住,扩张的时候,云是最佳选择。


如例子中,不得不创建自己有合适参数的Nginx镜像。

准备日志收集服务


集中式的日志和指标是使用分布式文件系统的必须项,如ELK,Graphana,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


创建可附加的网络



记得使用它,否则无法在Docker Swarm下一条命令跑起一个容器。 这是Docker1.13+新功能。如果使用旧版本的Docker, 最好升级下。


代码:

docker network create --driver=overlay --attachable core  


增加环境变量


如果创建Docker镜像的时候,遵循了最佳实践原则(https://rock-it.pl/how-to-write-excellent-dockerfiles/),允许在运行的时候通过环境变量设置一切配置项,那么把应用迁到Swarm的过程完全没有问题。


例,有用的命令:


docker service create \

--env VAR=VALUE \

--env-file FILENAME \

...


docker service update \

--env-add VAR=NEW_VALUE \

--env-rm VAR \

..


下一个级别就是使用非公开的API 。简而言之,在容器内,它允许挂载文件像挂载秘钥那样( Authorized keys, SSL certs 等 )。作者暂时还未使用此功能,不能详述,但这个功能特性绝对值得思考和使用。


设置适当实例和批量更新


保持适当数量的实例,以应对高流量和实例或者节点不可用的情况。同时太多的实例数也会占用CPU和内存,并且导致争抢CPU资源。


update-parallelism的默认值是1,默认只有一个实例在运行。但这个更新速度太慢了,建议是 replicas / 2。


相关命令:


docker service update \

--update-parallelism 10 \

webapp


# You can scale multiple services at once

docker service scale redis=1 nginx=4 webapp=20


# Check scaling status

docker service ls


# Check details of a service (without stopped containers)

docker service ps webapp | grep -v "Shutdown"


把Swarm配置保存为代码



最好使用 Docker Compose v3 版本的语法(https://docs.docker.com/compose/compose-file/#deploy)。它允许使用代码指定几乎所有的服务选项。作者在开发的时候使用 Docker-compose.yml,在生产环境(swarm)配置使用 Docker-compose.prod.yml  .  部署Docker-compose文件中所描述的服务,需要Docker stack deploy 命令(属于新版本 Stack命令集合中的 一部分[https://docs.docker.com/engine/reference/commandline/stack/])


Docker compose v3例子:


# docker-compose.prod.yml

version: '3'

services:

webapp:

image: registry.example.com/webapp

networks:

- ingress

deploy:

replicas: ${WEBAPP_REPLICAS}

mode: replicated

restart_policy:

condition: on-failure







请到「今天看啥」查看全文