Docker入门(六):Stacks
这个《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的更多相关文章
- Docker入门(三):容器(Containers)
这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...
- Docker入门(七):部署app
这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...
- Docker入门(五):Swarms
这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...
- Docker入门(四):服务(Services)
这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...
- Docker入门(二):安装/卸载
这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...
- Docker入门(一):简介
这个<Docker入门>系列文档,是我根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家 ...
- Docker入门教程(六)另外的15个Docker命令
Docker入门教程(六)另外的15个Docker命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第六篇,继续介绍Docker命令.之前的第二篇文章 ...
- Docker 入门 第六部分:部署app
目录 Docker 入门 第六部分:部署app 先决条件 介绍 选择一个选项 Docker CE(Cloud provider) Enterprise(Cloud provider)这里不做介绍 En ...
- Docker 入门 第五部分:Stacks
目录 Docker 入门 第五部分:Stacks 先决条件 介绍 添加一个新的服务并重新部署 保存数据 回顾 Docker 入门 第五部分:Stacks 先决条件 安装 Docker 1.13 或更高 ...
随机推荐
- 【WPF学习笔记】[转]周银辉之WPF中的动画 && 晓风影天之wpf动画——new PropertyPath属性链
(一)WPF中的动画 动画无疑是WPF中最吸引人的特色之一,其可以像Flash一样平滑地播放并与程序逻辑进行很好的交互.这里我们讨论一下故事板. 在WPF中我们采用Storyboard(故事板)的方式 ...
- JavaScrip函数与声明表达式
首先我们看下函数的两种命名方式 1.函数声明,声明一个函数 function test1(){ var a=0; console.log(a); //左一些操作... } 执行结果如下 我们看一下,无 ...
- oracle角色(role)概念
一个角色是一组特权,它可以授权给用户或其它角色. 特权有:create table,select on boss ,create session,insert on boss,update on bo ...
- oracle 存储过程(1)
说明 创建一个存储过程与编写一个普通的PL/SQL程序快有很多相似地方,比如:包括生命部分,执行部分和异常部分.但是两者之间实现细节还是有很多差别的,比如:创建存储过程需要使用procedure关键字 ...
- Mysql代码建外键问题
用下面代码建外键 运行之后 没有提示错误 但是打开建好的表格 外键并没有建立上 打开外键栏 里面并没有外键 在从表设置了外键列里面输入东西没有任何限制 成功建立应该是下面这样 什么情况???????? ...
- OpenFileDialog对话框Filter属性(转)
OpenFileDialog对话框的Filter属性说明: 首先说明一个示例,分析一下Filter属性的构成:“ Excel文件|*.xls ”,前面的“Excel文件”成为标签,是一个可读的字符串, ...
- 【题解】T54037 最开始
传送门 题目大意: 对于\(a+ \frac 1{a^{}}=n\)求$a^{m}+ \frac 1{a^{m}} $,对\(10^9+7\)取模. 题目做法: 乍看此题,没有思路,但是如果用数学办法 ...
- Android实现下拉导航选择菜单效果
本文介绍在Android中如何实现下拉导航选择菜单效果. 关于下拉导航选择菜单效果在新闻客户端中用的比较多,当然也可以用在其他的项目中,这样可以很方便的选择更多的菜单.我们可以让我们的应用顶部有左 ...
- Swift 烧脑体操(二) - 函数的参数
前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...
- nginx负载均衡设置
在nginx的配置文件[./conf/nginx.conf]中加入: upstream test.balance123.com { server 192.168.1.223:80; server 19 ...