目录html
friendlyhello
镜像发布到registry。咱们会在这里用到这个镜像username
, repo
, 和 tag
: docker run -p 80:80 username/repo:tag
, 而后查看 http://localhost/
。docker-compose.yml
docker-machine ls
来验证。若是机器已经中止运行,运行docker-machine start myvm1
启动管理器,而后运行docker-machine start myvm2
来启动worker。docker-machine ssh myvm1 "docker node ls"
来验证。若是swarm已经运行,那两个节点都会报告一个ready
状态,若是没有,按照第四部分中的部署swarm中的内容从新初始化swarm并加入worker。在第四部分,咱们学习了如何部署一个swarm(swarm是一个运行Docker的机器集群),部署一个应用到swarm,其中容器在多台机器上运行。
在本节,你会了解到分布式程序层次结构的顶层:Stack。Stack一组相互关联的服务,他们共享依赖关系,并能够在一块儿被编排和扩展。单个Stack能够定义和协调整个应用程序的功能(虽然复杂度很高的应用可能须要使用多个Stack)。node
好消息是,在第三部分中当你建立Compose 文件并使用docker stack deploy
时,你就已经开始使用Stack技术。可是那只是运行在一台单独的主机上的一个单个的Stack,一般在生产环境里不会这么使用。在这里,你能够根据所学内容,使多个服务彼此关联,并运行在多台机器上。web
在docker-compose.yml
文件中添加一个服务很简单。首先,咱们先添加一个可视化服务,看看swarm是如何调度容器的。
1.编辑docker-compose.yml
文件,使用下面的内容替换原内容。确保使用你的镜像信息替换username/repo:tag
:redis
version: "3" 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:
这里惟一改变的地方是新增了和web同级的visualizer
服务。有两个事情须要注意: volumes
密钥让可视化工具能够拦截到Docker的主机套接字文件;placement
密钥,确保该服务只运行在swarm管理器上,而不是worker上。这是由于这个容器是由Docker建立的开源项目构建的,使用图示的方式显示swarm上运行的docker服务。
咱们如今就来看看placement约束和volumes。docker
2.确保你的shell已被配置为可与myvm1进行通讯。(完整的例子点这里)shell
docker-machine ls
列出机器,并确保你已经链接到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
3.在管理器上从新运行docker stack deploy
,并更新须要更新的服务。bash
$ docker stack deploy -c docker-compose.yml getstartedlab Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm) Creating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
4.在可视化工具中查看
从Compose文件中能够看出visualizer
运行在8080端口。运行docker-machine ls
获取其中一个节点
的IP地址。访问该IP地址的8080端口就能够看到正在运行的visualizer:app
visualizer
的其中一个副本正如咱们预期的同样运行在管理器上。咱们能够运行docker stack ps <stack>
来确认这个
docker stack ps getstartedlab
该可视化工具是一个独立的服务,能够在stack里任何包含它的app上运行。它不依赖任何其余内容。如今咱们建立一个具备依赖关系的服务:提供浏览器计数器的Redis服务。
咱们能够经过相同的步骤来添加一个Redis数据库来存储应用数据。
1.在docker-compose.yml文件末尾点击一个Redis服务,并保存这个新文件。确保使用你的镜像信息替换username/repo:tag
。
version: "3" 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:
Docker库中有一个Redis的官方镜像,使用了一个很短的镜像名字:redis
,所以这里没有使用username/repo
来表示。Redis的6379端口已经被预设为从容器暴露给主机,在咱们的compose文件中,咱们将其从主机暴露给公网,所以,若是你选择这样作,你就能够在任何节点链接Redis桌面管理器并管理该redis节点。
最重要的是,在该stack上部署redis期间,redis规范中有一些内容可使数据保持不变。
/data
目录,用来存储redis数据。总之,这会在主机的物理文件系统上为Redis数据建立一个”真实数据源(官方叫“source of truth”)“。若是没有这个,Redis会把数据保存在容器内的/data
目录,若是容器被从新部署,那么数据就会被删除。
真实的数据源有两部分组成:
./data
(主机上的)做为/data
(redis容器上)来进行访问。当容器建立删除时,在指定主机上的。/data
下存储的文件会一直存在,从而实现连续性。到这里,咱们就作好了部署Redis stack的准备。
2.在管理器上建立./data
目录
docker-machine ssh myvm1 "mkdir ./data"
3.确保你的shell已被配置为可与myvm1通讯(点此查看完成例子)
docker-machine ls
,列出机器,确保你已经连接上myvm1
,以下条所示。docker-machine env myvm1
,而后运行给定的命令来配置shell。# Mac 或 Linux上的命令: eval $(docker-machine env myvm1) # Winidows上的命令: & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
4.再次运行docker stack deploy
$ docker stack deploy -c docker-compose.yml getstartedlab
5.运行docker service ls
来验证三个服务是否按照预期运行。
$ 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 gordon/getstarted:latest *:80->80/tcp
6.在其中一个检点上检查web页面,例如http://192.168.99.101
,查看浏览计数器的结果,该计数器已存在并将信息存储在redis上。
另外,检查任意节点IP地址上的8080端口的可视化工具,注意redis
服务与web服务和visualizer服务都在运行,
下面是本节内容的回顾:
bash-3.2$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 - virtualbox Running tcp://192.168.99.104:2376 v17.04.0-ce myvm2 - virtualbox Running tcp://192.168.99.105:2376 v17.04.0-ce bash-3.2$ docker-machine ssh myvm1 "docker node ls" ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS fvenziy5o4xmziyzqxianzd65 myvm2 Ready Active x500bs7lrweto9chkg6xq2ybd * myvm1 Ready Active Leader bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS kjeymj6rp0y8 getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 15 minutes ago dehkjrmu0fxn getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 15 minutes ago acnejfyy1cmg getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 15 minutes ago 36lpsek707gj getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 15 minutes ago q5yb5uj97ef1 getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 Running Running 15 minutes ago bash-3.2$ ls docker-compose.yml bash-3.2$ more docker-compose.yml version: "3" services: web: image: johndmulhausen/get-started:part1 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: bash-3.2$ docker-machine scp docker-compose.yml myvm1:~ docker-compose.yml bash-3.2$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab" Creating service getstartedlab_visualizer Updating service getstartedlab_web (id: a3mhoq23ydyut4uje16slqum2) bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ts3ud4mdf9qi getstartedlab_visualizer.1 dockersamples/visualizer:stable myvm1 Running Running 34 seconds ago kjeymj6rp0y8 getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 20 minutes ago dehkjrmu0fxn getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 19 minutes ago acnejfyy1cmg getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 20 minutes ago 36lpsek707gj getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 19 minutes ago q5yb5uj97ef1 getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 bash-3.2$ more docker-compose-WITH-REDIS.yml version: "3" services: web: image: johndmulhausen/get-started:part1 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:6739" volumes: - ./data:/data deploy: placement: constraints: [node.role == manager] networks: - webnet networks: webnet: bash-3.2$ docker-machine scp docker-compose-WITH-REDIS.yml myvm1:~ docker-compose-WITH-REDIS.yml bash-3.2$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose-WITH-REDIS.yml getstartedlab" Updating service getstartedlab_web (id: a3mhoq23ydyut4uje16slqum2) Updating service getstartedlab_visualizer (id: uwd8tja3fpcpsy8kumk19orr8) Creating service getstartedlab_redis bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" PORTS o2xct1jotx55 getstartedlab_redis.1 redis:latest myvm1 Ready Rejected 1 second ago "invalid mount config for type… " tf1s212hfh9c \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 6 seconds ago "invalid mount config for type… " sizyxk5f0a5h \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 11 seconds ago "invalid mount config for type… " xd8s1ljsj9oq \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 16 seconds ago "invalid mount config for type… " 6h4wfo8nophs \_ getstartedlab_redis.1 redis:latest myvm1 Shutdown Rejected 21 seconds ago "invalid mount config for type… " ts3ud4mdf9qi getstartedlab_visualizer.1 dockersamples/visualizer:stable myvm1 Running Running 4 minutes ago kjeymj6rp0y8 getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 24 minutes ago dehkjrmu0fxn getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 23 minutes ago acnejfyy1cmg getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 24 minutes ago 36lpsek707gj getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 23 minutes ago q5yb5uj97ef1 getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 bash-3.2$ docker-machine ssh myvm1 "mkdir ./data" bash-3.2$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose-WITH-REDIS.yml getstartedlab" Updating service getstartedlab_web (id: a3mhoq23ydyut4uje16slqum2) Updating service getstartedlab_visualizer (id: uwd8tja3fpcpsy8kumk19orr8) Updating service getstartedlab_redis (id: oxlqkgq0vcmlzc5k1gk0rthdf) bash-3.2$ docker-machine ssh myvm1 "docker stack ps getstartedlab" ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS xl9qttm6cg7v getstartedlab_redis.1 redis:latest myvm1 Running Running 32 seconds ago ihuhl093b492 getstartedlab_visualizer.1 dockersamples/visualizer:stable myvm1 Running Running 33 seconds ago 3jpjjz6hdmex getstartedlab_web.1 johndmulhausen/get-started:part1 myvm2 Running Running 31 seconds ago q9w4v6g14bxm getstartedlab_web.2 johndmulhausen/get-started:part1 myvm1 Running Running 34 seconds ago w8z6vyae3cyb getstartedlab_web.3 johndmulhausen/get-started:part1 myvm2 Running Running 31 seconds ago xgpfmyhp2uub getstartedlab_web.4 johndmulhausen/get-started:part1 myvm1 Running Running 34 seconds ago jdkgknm7wlip getstartedlab_web.5 johndmulhausen/get-started:part1 myvm2 Running Running 31 seconds ago bash-3.2$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm1 - virtualbox Running tcp://192.168.99.104:2376 v17.04.0-ce myvm2 - virtualbox Running tcp://192.168.99.105:2376 v17.04.0-ce bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> cfc0b7af2d99<br/><b>Visits:</b> 1 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 8900768882f9<br/><b>Visits:</b> 2 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 3adb6b451c2e<br/><b>Visits:</b> 3 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 8398387efdb7<br/><b>Visits:</b> 4 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> 67e3e4c066ee<br/><b>Visits:</b> 5 bash-3.2$ curl http://192.168.99.105/ <h3>Hello World!</h3><b>Hostname:</b> cfc0b7af2d99<br/><b>Visits:</b> 6
本节了解到stack是所有一致运行的相互关联的服务,而且,从第三节就开始使用stack。还学习了想stakc中添加服务,将它们加氟Compose文件中。最后,学习了经过位置约束和卷组的组合,你能够建立一个永久的源来保存数据,通常在销毁并重部署容器时,app的数据仍会存在。