文档章节

生产环境中使用Docker Swarm的一些建议

Fundebug
 Fundebug
发布于 2017/05/09 10:41
字数 2670
阅读 46
收藏 0

译者按: 实践中会发现,生产环境中使用单个Docker节点是远远不够的,搭建Docker集群势在必行。然而,面对Kubernetes, Mesos以及Swarm等众多容器集群系统,我们该如何选择呢?它们之中,Swarm是Docker原生的,同时也是最简单,最易学,最节省资源的,至少值得我们多了解一下。本文将介绍一些非常实用的建议。

<!-- more -->

原文: Tips for using Docker Swarm mode in production

译者: Fundebug

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习

如果你在单个生产节点上用过Docker,然后发现单个节点的资源不够用,那么你会怎么做呢?我也遇到过这种情况! 关于在生产环境中使用Docker Swarm,我会为你提供一些建议,也许能够帮到你。这些都是我一年来积累的一些经验。

另外,如果你对Docker Swam不熟悉的话,可以参考我之前的博客My experience with Docker Swarm - when you may need it?

1. 阅读官方文档

我并不打算重复官方文档。尽管文档非常短,但是通过它可以了解Swarm的基本知识。另外,我也不会写如何搭建Swarm集群,这方面的资料太多了,你可以查看 Digital Ocean或者自己谷歌。PS: 我是使用Ansible搭建Swarm集群的。

2. Docker Swarm要点

Swarm的负载非常低。据我观察,Swarm进行调度和通信的CPU负载非常低。因此,Swarm的管理节点(Manager)可以同时作为工作节点(Worker)。如果你需要搭建一个非常大的集群(1000+ 节点),管理节点需要更多资源,但是对于中小型集群来说,管理节点需要的资源可以忽略不计。另外,这篇博客介绍了Swarm3k(一个4700节点的Swarm集群的实验),不妨了解一下。

Swarm集群的网络通信(服务发现,负载均衡以及容器间通信)非常可靠。当你开启一个服务的端口之后,在Swarm集群中的任何一个节点都可以访问它。负载均衡也是由Swarm提供的。后文会提到一些之前遇到的问题,但是Docker 1.13之后,这些问题都解决了。

**使用Swarm只需要掌握少量命令。**下面是我每天需要用到的所有命令:

# 创建服务
docker service create \  
  --image nginx \
  --replicas 2 \
  nginx 

# 更新服务
docker service update \  
  --image nginx:alpine \
  nginx 

# 删除服务
docker service rm nginx

# 减少服务实例(这比直接删除服务要好)
docker service scale nginx=0

# 增加服务实例
docker service scale nginx=5

# 查看所有服务
docker service ls

# 查看服务的容器状态
docker service ps nginx

# 查看服务的详细信息。
docker service inspect nginx  

**实现零宕机部署也非常简单。**这样也可以方便地实现持续部署:

# 构建新镜像
docker build -t hub.docker.com/image . 

# 将新镜像上传到Docker仓库
docker push hub.docker.com/image

# 更新服务的镜像
docker service update --image hub.docker.com/image service  

Swarm非常容易入门。分布式系统通常是非常复杂的。与其他容器集群系统(Mesos, Kubernetes)相比,Swarm的学习曲线最低。在没有任何Swarm知识的情况下,我只花了一周时间,就把服务从单个Docker主机迁移到20个节点的Docker集群上。

更新服务要慎重。 你的容器同时运行在多个主机上。更新服务时,只需要更新Docker镜像。合理的测试和部署流程是保证成功的关键。

3. 决定哪些容器部署在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集群之外的容器:

  • Postgres(数据库)
  • Redis(缓存)

由于一个获取真正IP的问题,我很可能会将Nginx运行在Swarm集群之外,或者采用host模式。

4. 配置Docker仓库

Docker仓库,你值得拥有!你可以自己搭建一个,或者使用Docker仓库服务,比如DockerHub或者GitLab Container Registry。不要在服务器上直接构建Docker镜像,因为你有多个节点(在每个节点上构建镜像非常麻烦),而且在创建服务的时候你需要指定镜像(这个镜像所有节点都应该可以下载)。如果你配置了私有Docker仓库,则需要指定--with-registry-auth,否则这些节点将无法下载镜像。

另外,你应该为Docker镜像设置版本,这样更加易于回滚。

5. 将半无状态的服务变得完全无状态

所谓半无状态服务,就是容器需要依赖一些不太重要的外部文件。你可以使用数据卷(volume),但是更好的选择是使用S3或者其他云存储服务。记住,想要获得扩展性,云是最好的选择。

例如,我不得不构建Nginx镜像,将配置文件放到镜像中。使用数据卷挂载Nginx配置文件不是很方便。

6. 配置日志收集服务

使用分布式系统时,集中管理日志是非常必要的。我们有很多方案,包括开源工具或者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

7. 创建attachable network

attachable network是一个非常重要的特性。你最好使用它,否则docker run创建的容器将无法接入Swarm集群的网络。这是Docker 1.13之后的版本才有的功能,也许你需要升级。

创建attachable network的命令如下:

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

8. 先使用环境变量,再考虑Secrets API

如果你按照How to write excellent Dockerfiles构建Docker镜像,你很可能会使用环境变量去配置很多东西。如果你这样做的话,则迁移到Swarm集群时问题会少很多。示例命令如下:

# 创建服务时指定环境变量
docker service create \  
  --env VAR=VALUE \
  --env-file FILENAME \
  ...

# 增加、删除环境变量
docker service update \  
  --env-add VAR=NEW_VALUE \
  --env-rm VAR \
  ..

下一步是使用Secrets API 。简单地说,你可以将私密数据(比如密码,SSL证书等)以文件的形式挂载到容器中。虽然我还没有用过Secrets API,但是我觉得值得尝试一下。

9. 设置合理的服务容器个数以及并行更新的容器个数

一方面,你需要保证足够多的容器数来处理负载以及作为灾备,另一方面,太多的容器会导致CPU和内存资源不足。因此,你需要配置合理的服务容器个数,也就是说,某个服务,需要运行合理个数的容器。

另外,默认的update-parallelism 值是1,这就意味着更新服务时,每次只更新1个容器。通常,这个值太小了。我的建议是将它设为 服务容器数 / 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"  

10. 将Swarm配置代码化

最佳方式是使用Docker Compose v3 语法,这样可以将服务的所有配置选项代码化。我将 docker-compose.yml用于开发环境, docker-compose.prod.yml用于生产环境。使用docker-compose文件部署服务的话,需要使用 docker stack deploy 命令(参考docker stack

docker-compose文件示例

# 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

  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-compse文件支持环境变量(${VARIABLE}),这样你可以动态地调整配置。

11. 设置资源限制

根据我的经验,你需要限制所有服务的CPU使用。这样可以防止单个容器占用主机的所有的CPU资源。

reserve-cpu 选项也非常有用。当我希望平均地将所有容器部署到各个主机时,我会使用reserve-cpu ,它可以保证每个容器都有足够地资源。示例:

# 限制服务占用的CPU资源
docker service update  
  --limit-cpu 0.25
  --reserve-cpu 0.1
  webapp

12. 监控网络连接

我遇到过Swarm网络方面的问题。有时候所有的请求都被转发到某一个容器,然而还有9个其他容器正在运行。这时,可以尝试减少/增加实例个数,或者改变路由类型(使用--endpoint-mode选项)

如果没有监控日志的话,这样的问题很难被发现。因此,搭建监控系统是非常必要的。

欢迎加入我们FundebugDocker技术交流群: 305097057

输入图片说明

版权声明:

转载时请注明作者Fundebug以及本文地址:

https://blog.fundebug.com/2017/05/08/docker-swarm-suggestion/

© 著作权归作者所有

共有 人打赏支持
Fundebug
粉丝 6
博文 126
码字总数 193991
作品 0
厦门
私信 提问
微软宣布改进了 Docker 和 Azure 的集成

在近日结束的DockerCon 2016西雅图大会上,微软宣布了一些Azure特性,展示了对于企业内Docker容器支持的改进,包括在Azure Marketplace中提供Docker数据中心以及Docker数据中心对管理混合容器...

oschina
2016/07/07
3.8K
13
docker swarm集群及其UI部署

一、规划 ①swarm01作为manager节点,swarm02和swarm03作为worker节点。 # cat /etc/hosts127.0.0.1 localhost192.168.139.175 swarm01 192.168.139.176 swarm02 192.168.139.177 swarm03 ②......

心远何方
06/27
0
0
docker swarm相关(2):在生产环境中,使用Docker Swarm一些建议

1. 前言 在生产环境实践中,我们发现使用单个docker节点是远远不够的,搭建docker集群势在必行。然而,面对Kubernetes、Mesos以及Swarm等众多容器集群系统(或者叫容器编排工具),我们该如何...

yjk13703623757
04/13
0
0
使用Docker swarm构建wordpress集群

最近都在忙,久不更新博客了,今天更新下Docker swarm集群和集群容错测试: 1、如下拓扑: 2、环境说明: Master/nfs服务器:192.168.63.217Worker:192.168.63.217Worker:192.168.63.216 3、创...

小罗ge11
06/29
0
0
使用Docker Swarm搭建分布式爬虫集群

在爬虫开发过程中,你肯定遇到过需要把爬虫部署在多个服务器上面的情况。此时你是怎么操作的呢?逐一SSH登录每个服务器,使用git拉下代码,然后运行?代码修改了,于是又要一个服务器一个服务...

微笑向暖wx
10/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

easyui tree

<tr> <th><spring:message code="wf.borrow.examiner"/></th> <td> <input id="inp-examiner1" type="text" name="examiner1" style="width:197px;height:20px;" data-options="required:tru......

小兵胖胖
10分钟前
0
0
内存性能的正确解读

一台服务器,不管是物理机还是虚拟机,必不可少的就是内存,内存的性能又是如何来衡量呢。 1. 内存与缓存 现在比较新的CPU一般都有三级缓存,L1 Cache(32KB-256KB),L2 Cache(128KB-2MB)...

阿里云云栖社区
13分钟前
0
0
微服务架构:Zuul 1.0 和 2.0 我们该如何选择?

在今年5月中,Netflix终于开源了它的支持异步调用模式的Zuul网关2.0版本,真可谓千呼万唤始出来。从Netflix的官方博文[附录1]中,我们获得的信息也比较令人振奋: The Cloud Gateway team a...

大木老师故事的小黄花
14分钟前
0
0
基础掌握

哪些是基础功呢?我觉得包括: 数据结构和算法:链表、队列、栈、堆、树(RBT, B/B+)、跳表、哈希、图;查找(二分、bst)、排序(冒泡、插入、快排、归并、堆排、希尔)、递归、归并、回溯、...

边鹏_尛爺鑫
15分钟前
0
0
Android APP的安装路径

一. Android应用安装路径有两种情况: system/app 系统自带的应用程序,无法删除。root后可以删除,注意可能造成系统崩溃,不过有的垃圾捆绑软件只能这么删除了 data/app 用户程序安装的目录,...

天王盖地虎626
18分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部