这个《Docker入门系列》文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成。主要是作为个人学习记录。有错误的地方,Robin欢迎大家指正。分为如下几个部分:

1 Docker入门:简介

2 Docker入门:安装运行

3 Docker入门:容器(Containers)

4 Docker入门:服务(Services)

5 Docker入门:Swarms

6 Docker入门:Stacks

7 Docker入门:部署app

8 Docker入门:稍高级的话题

6.1 引言

在第五部分,我们学习了如何搭建一个swarm。一个swarm就是运行着Docker的一组机器所组成的集群。然后学习了如何将app部署到swarm上,并让许多容器一致地运行在多个机器上。

在第六部分,我们将进入一个分布式应用程序层次结构的最高层:stack。

stack

service

container

一个stack就是一组相互关联的services,这些services之间相互依赖,并能够一起进行编排和scale。单个stack就能够定义和协调整个应用程序的功能(也存在一些复杂的应用程序,可能使用多个stacks)。

好消息是,我们从第四部分就已经接触stack了:创建一个Compose文件并使用docker stack deploy。但那只是一个单service的stack,运行在单个主机上,这种情况极少在产品部署中使用。下面,我们将使多个services相互关联,并将它们运行在多个机器上。

6.2 添加一个新的service并重新部署

向我们的docker-compose.yml文件中添加services很简单。首先,添加一个免费的visualizer service,该service用于查看swarm是如何调度容器的。

分为如下4个步骤。

6.2.1 重新编辑Compose文件

用编辑器打开文件docker-compose.yml,并输入如下内容,确保用你的映像信息替换uername/repo:tag部分。

version: ""

services:

  web:

    # replace username/repo:tag with your name and image details

    image: username/repo:tag

    deploy:

      replicas: 5

      restart_policy:

        condition: on-failure

      resources:

        limits:

          cpus: "0.1"

          memory: 50M

    ports:

      - "80:80"

    networks:

      - webnet

  visualizer:

    image: dockersamples/visualizer:stable

    ports:

      - "8080:8080"

    volumes:

      - "/var/run/docker.sock:/var/run/docker.sock"

    deploy:

      placement:

        constraints: [node.role == manager]

    networks:

      - webnet

networks:

  webnet:

在该.yml文件中,添加了一个和web平行的service,名称为visualizer。还有两个新的关键字。一个是关键字volumes,用于给visualizer提供权限,从而访问主机上的Docker socket文件。另一个关键字是placement,用于确保这个service只能运行在swarm manager上,而不能运行在worker节点上。因为这个容器构建自Docker开源项目,用来以图表方式展示一个swarm上运行的services。

6.2.2 配置和swarm manager对话的shell

确保你的shell已经配置好,能够和myvm1进行对话:

● 运行命令docker-machine ls,来列出所有的machines,并确保你已经连上myvm1了,能够发现myvm1旁边有星号。

● 如果需要,就重新运行命令docker-machine env myvm1,然后运行给出的命令来配置shell。

在MAC/LINUX系统里,这个命令是:

eval $(docker-machine env myvm1)

在WINDOWS系统里,这个命令是:

& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression

6.2.3 重新部署

在manager上重新运行命令docker stack deploy,更新需要更新的services:

$ docker stack deploy -c docker-compose.yml getstartedlab

Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm)

Updating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)

6.2.4 查看visualizer服务

在Compose文件里,visualizer运行在端口8080上。运行docker-machine ls来获得任一个节点的IP地址,进入该IP的8080端口来看看visulizer的运行情况:

和期望中的一样,visualizer的单个实例运行在manager上,web的5个实例分布在整个swarm上。你可以运行命令docker stack ps <stack>来佐证一下visualizer的展示结果:

docker stack ps getstartedlab

visualizer是一个独立的服务,在stack中,它可以运行在任何app里。它不依赖任何东西。下面我们创建一个具有依赖性的service:能够提供访客计数功能的Redis service.

6.3 数据持久化

我们再一次使用之前的工作流程,来添加一个Redis数据库service,用以存储app的数据。分为如下六个步骤。

6.3.1 修改Compose文件

修改docker-compose.yml文件,内容如下面所示,这将添加一个Redis service。确保用你自己的映像信息来取代username/repo:tag部分。

version: ""

services:

  web:

    # replace username/repo:tag with your name and image details

    image: username/repo:tag

    deploy:

      replicas: 5

      restart_policy:

        condition: on-failure

      resources:

        limits:

          cpus: "0.1"

          memory: 50M

    ports:

      - "80:80"

    networks:

      - webnet

  visualizer:

    image: dockersamples/visualizer:stable

    ports:

      - "8080:8080"

    volumes:

      - "/var/run/docker.sock:/var/run/docker.sock"

    deploy:

      placement:

        constraints: [node.role == manager]

    networks:

      - webnet

  redis:

    image: redis

    ports:

      - "6379:6379"

    volumes:

      - /home/docker/data:/data

    deploy:

      placement:

        constraints: [node.role == manager]

    command: redis-server --appendonly yes

    networks:

      - webnet

networks:

  webnet:

Redis在Docker库中有一个官方的映像,所以可以使用简写的映像名称redis,这里就不需要username/repo了。Redis已经将端口6379从容器暴露到主机,在Compose文件里,我们将该端口从主机暴露到外面的世界,所以你可以通过任一个节点的IP来访问Redis桌面管理器,从而管理这个Redis实例。

还有一些重要的Redis规范,用于指导stack多次部署时的数据持久化:

  • Redis总是运行在manager上,所以它总是可以使用相同的文件系统;
  • 通过访问容器中的目录/data,redis能够访问主机文件系统中的任何目录,Redis在该目录中存储数据。

  以上两点结合在一起,就可以在主机的物理文件系统中为Redis数据创建一个事实上的源(source of truth)。如果没有这个机制,Redis就会在容器的文件系统中的/data目录下存储数据,一旦容器重新部署,这些数据就会丢失。

“source of truth”包含两个部分:

  • Placement: 放置在Redis service上的这个约束,保证了Redis service总是使用相同的主机。
  • volume: 这个关键字的配置,使得容器通过访问Redis容器中的/data目录,来间接访问主机上的/data目录。换句话说,这让容器的数据访问透明化,虽然容器逻辑上访问的是Redis容器中的/data目录,而实际上容器访问的是主机上的/data目录。

6.3.2 在manager上创建目录

在manager上创建一个./data目录:

docker-machine ssh myvm1 "mkdir ./data"

6.3.3 配置和swarm manager对话的shell

确保你的shell已经配置好,能够和myvm1进行对话:

● 运行命令docker-machine ls,来列出所有的machines,并确保你已经连上myvm1了,能够发现myvm1旁边有星号。

● 如果需要,就重新运行命令docker-machine env myvm1,然后运行给出的命令来配置shell。

  在MAC/LINUX系统里,这个命令是:

eval $(docker-machine env myvm1)

  在WINDOWS系统里,这个命令是:

& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression

6.3.4 重新部署

再一次运行命令docker stack deploy:

$ docker stack deploy -c docker-compose.yml getstartedlab

6.3.5 确认service运行状况

运行命令docker service ls,来确认3个services是否正常运行:

$ docker service ls

ID                       NAME                               MODE         REPLICAS           IMAGE                                                 PORTS

x7uij6xb4foj       getstartedlab_redis           replicated     1/1                       redis:latest                                            *:6379->6379/tcp

n5rvhm52ykq7   getstartedlab_visualizer   replicated     1/1                       dockersamples/visualizer:stable           *:8080->8080/tcp

mifd433bti1d      getstartedlab_web           replicated     5/5                        orangesnap/getstarted:latest                *:80->80/tcp

6.3.6 网页验证

选择一个节点的IP地址(比如:http://192.18.99.101)进入其网页,就可以看到访客的统计数量,这个数据会一直更新并存储在Redis上。

同样,选择任一个节点的IP地址,在其端口8080上访问visulizer,就可以看到web、redis、visualizer三种服务一起运行。

6.4 总结

Stacks就是一组一致运行的、相互关联的services。通过修改Compose文件,可以向stack中添加更多的services。最后,通过使用placement和volumes两个关键字的组合,为持久化数据创建了一个永久的港湾,无论容器关闭或重新部署,app的数据会一直保存下来。

Docker入门(六):Stacks的更多相关文章

  1. Docker入门(三):容器(Containers)

    这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...

  2. Docker入门(七):部署app

    这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...

  3. Docker入门(五):Swarms

    这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...

  4. Docker入门(四):服务(Services)

    这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...

  5. Docker入门(二):安装/卸载

    这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...

  6. Docker入门(一):简介

    这个<Docker入门>系列文档,是我根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家 ...

  7. Docker入门教程(六)另外的15个Docker命令

    Docker入门教程(六)另外的15个Docker命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第六篇,继续介绍Docker命令.之前的第二篇文章 ...

  8. Docker 入门 第六部分:部署app

    目录 Docker 入门 第六部分:部署app 先决条件 介绍 选择一个选项 Docker CE(Cloud provider) Enterprise(Cloud provider)这里不做介绍 En ...

  9. Docker 入门 第五部分:Stacks

    目录 Docker 入门 第五部分:Stacks 先决条件 介绍 添加一个新的服务并重新部署 保存数据 回顾 Docker 入门 第五部分:Stacks 先决条件 安装 Docker 1.13 或更高 ...

随机推荐

  1. ios美颜 调研 GPUImage GPUImageBeautifyFilter BeautifyFaceDemo

    最近需要给直播项目中添加美颜的功能,调研了很多SDK和开源代码(视决,涂图,七牛,金山云,videoCore等),综合成本/效果/对项目侵入性,最后决定使用一款基于GPUImage实现的 Beauti ...

  2. 13-redis主从复制

    一:redis主从复制 (1)配置要求 一台主maste 二台从slave (2)架构图 (3)配置流程 1:分配拷贝2份redis.conf 分别命名为 redis6380.conf redis63 ...

  3. VxWorks启动过程具体解释(下)

    上一节主要是从映像的分类和各种映像的大致载入流程上看VxWorks的启动过程,这一节让我们从函数级看一下VxWorks的启动过程: 1. Boot Image + Loadable Images: 以 ...

  4. ABAP 弹出框 函数

    POPUP_GET_VALUES_USER_HELP 是一个和用户交互信息的函数,用户能够填写信息,并且我们还能够依据实际的需求对弹出框进行F1 F4 以及用户的需求进行增强.具体的实现能够參考系统标 ...

  5. Grails 简要

    一.什么是Grails? Grails is an Open Source, full stack, web application framework for the JVM. It takes a ...

  6. 开始使用gradle

    前提配置gradle环境 每个gradle构建都是以一个脚本开始的.gradle构建默认的名称为build.gradle.当在shell中执行gradle命令时,gradle会去寻找为build.gr ...

  7. 广播、多播和IGMP的一点记录

    广播和多播:仅应用于UDP 广播分为: 1.受限的广播(255.255.255.255) 2.指向网络的广播(eg:A类网络 netid.255.255.255)主机号为全1的地址 3.指向子网的广播 ...

  8. 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂

    [BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...

  9. WebApi 传参详解(转)

    一.无参数Get请求 一般的get请求我们可以使用jquery提供的$.get() 或者$.ajax({type:"get"}) 来实现: 请求的后台Action方法仍为上篇文章中 ...

  10. iOS 流布局 UICollectionView使用(使用FlowLayout进行更灵活布局)

    在UICollectionView的布局中,如果每个item的大小都一样那么是十分简单的事情,但是,如果我们想要的每个item大小不一样呢,这个时候,就要对UICollectionViewFlowLa ...