优秀的编程知识分享平台

网站首页 > 技术文章 正文

Docker入门教程(5):堆栈(堆栈 堆 栈)

nanyue 2024-09-26 15:11:40 技术文章 4 ℃
  • 安装Docker版本1.13或更高版本

  • 获取Docker Compose工具,正如本系列教程第三部分的前提条件所述。

  • 获取Docker Machine工具,正如本系列教程第四部分的前提条件所述。

  • 阅读本系列教程第一部分的技术方向。

  • 阅读本系列教程第二部分,学习如何创建容器。

  • 确保你已经将先前创建的friendlyhello镜像发布至镜像仓库。我们将在本文中使用这个共享镜像。

  • 确保Docker能够将你先前创建的镜像部署为容器。运行以下命令,指定你的个人信息(包括用户名、镜像仓库和标签):docker run -p 80:80 username/repo:tag,然后访问http://localhost/页面。

  • 为了操作方便,需要为本系列教程第三部分的docker-compose.yml文件创建一份副本。

  • 确保你在本系列教程第四部分设置的主机正在运行,并且随时准备投入使用。可以运行docker-machine ls命令进行验证。如果主机停止运行,那么运行docker-machine start myvm1命令便可启动管理节点,然后运行docker-machine start myvm2命令便可启动工作节点。

  • 确保你在本系列教程第四部分创建的swarm正在运行,并且随时准备投入使用。可以运行docker-machine ssh myvm1 "docker node ls"命令进行验证。如果swarm运行正常,那么两个节点都会返回ready状态。如果swarm停止运行,那么可以按照本系列教程第四部分介绍的方法,重新初始化swarm,然后将工作节点加入swarm。

简介

在第四部分中,你已经学会如何创建一个swarm,它其实就是一个由多台运行Docker的主机组成的集群,你已经将一个应用程序部署至该集群,并且在多台主机中同时运行若干个容器。

在本文中,你将会学习分布式应用程序的最顶层:堆栈。堆栈是一组相互关联的服务,它们共享依赖关系,并且可以一同被编排和伸缩。单个堆栈就已经能够定义和协调整个应用程序的功能(某些非常复杂的应用程序可能需要使用多个堆栈)。

有一个好消息,你已经在第三部分学会如何使用堆栈了,例如:创建编排文件和运行docker stack deploy命令。但是,你只是在单台主机中运行单个服务堆栈,这种情况在生产环境中非常少见。此时,你将会用到你已经学会的知识,将多个服务互相关联起来,然后使用多台主机运行这些服务。

你做的太棒了,我们已经到冲刺阶段了!

添加新服务和重新部署

向我们的docker-compose.yml文件中添加服务配置是非常简单的。首先,我们会添加一个免费的可视化服务,这样我们便能观察swarm是如何调度容器的。

1. 在文本编辑器中打开docker-compose.yml文件,然后替换下文所述的内容。确保将username/repo:tag替换为你的镜像的真实名称。

version: "3"
services:
 web:
 # 将username/repo:tag替换为实际的镜像名称
 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服务。在visualizer服务的配置中,你会看到两个新配置项:volumes配置项,使得可视化服务能够访问宿主机的docker.sock文件,该文件是Docker服务的套接字文件;placement配置项,确保这个服务只会作为swarm的管理节点运行,它不会成为工作节点。因为可视化服务的容器是在Docker创建的一个开源项目的基础之上构建的,所以它会以图表的方式显示swarm包含的Docker服务的运行状态。

我们稍后会详细介绍placement配置项和volumes配置项。

2. 将上述新建的docker-compose.yml文件拷贝至swarm管理节点,也就是myvm1虚拟机:

docker-machine scp docker-compose.yml myvm1:~

3. 在管理节点中重新运行docker stack deploy命令,swarm将会对所有需要更新配置的服务执行更新操作:

docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"

若服务配置更新成功,返回信息如下图所示:

更新服务堆栈的配置

4. 查看可视化服务的页面

你在编排文件中可以看到,visualizer服务是在8080端口运行的。运行docker-machine ls命令,获取swarm的其中一个节点的IP地址。在浏览器中访问任意节点的IP地址和8080端口,你将会看到可视化服务的页面,如下图所示:

通过可视化服务检查堆栈状态

正如你能够预料的,visualizer服务只会在管理节点中运行一个容器,而web服务则有五个容器分散在swarm的每个节点中运行。如果你想要确证这种可视化服务的状态,那么可以运行docker stack ps <stack>命令:

docker-machine ssh myvm1 "docker stack ps getstartedlab"

上述命令的运行结果,如下图所示:

通过命令行检查服务堆栈状态

可视化服务是一个单机服务,它可以在任何应用程序中运行,只要在堆栈中包含该服务即可。它不会依赖于任何其他东西。现在,我们可以创建一个确实具有依赖关系的服务:Redis服务,它会提供访问者计数器的功能。

持久化数据

我们可以再次重复一遍相同的工作流程,添加一个用于存储应用数据的Redis数据库。

1. 保存这个新建的docker-compose.yml文件,它最后会添加一个Redis服务。确保将username/repo:tag替换为你的镜像的真实名称。

version: "3"
services:
 web:
 # 将username/repo:tag替换为实际的镜像名称
 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:
 - ./data:/data
 deploy:
 placement:
 constraints: [node.role == manager]
 networks:
 - webnet
networks:
 webnet:

在Docker的镜像库中,Redis有一个官方镜像,它使用一个简短的image名称(也就是redis),因此不必指定自己的username/repo标记。Redis使用6379端口,Docker已经对redis镜像进行预先配置,将基于这个镜像的容器的6379端口向宿主机开放。在我们的编排文件之中,我们会将宿主机的6379端口向外界开放。因此,实际上你可以在Redis Desktop Manager中输入任意节点的IP地址,然后就可以管理这个Redis实例了。

最为重要的是,在redis镜像的使用说明之中,有两个注意事项使得两次堆栈部署期间能够实现数据持久化:

  • redis的容器总是在管理节点中运行,因此它总是使用相同的文件系统。

  • redis的容器会将宿主机文件系统的任意目录作为容器内部的/data目录来访问,这个目录可用于存储Redis的数据。

上述两个注意事项结合起来,便会在宿主机的物理文件系统之中创建一个“真实数据源”,它可用于存储Redis数据。如果不这么做,Redis便会将数据存储在容器内部文件系统的/data目录之中,如果这个容器被删除或重新部署,那么这些数据全都会丢失。

这种真实数据源具有两个组成部分:

  • 你为Redis服务设置的placement配置项,确保它总是使用相同的主机。

  • 你为Redis服务设置的volumes配置项,使得容器能够将宿主机的./data目录作为Redis容器内部的/data目录来访问。虽然容器变化不断,但是存储在指定宿主机的./data目录中的文件将会持久化保存,能够确保数据的连续性。

现在,你已经可以部署使用Redis数据库的新服务堆栈了。

2. 在管理结点中创建一个名为./data的目录:

docker-machine ssh myvm1 "mkdir ./data"

3. 使用docker-machine scp命令,拷贝新建的docker-compose.yml文件:

docker-machine scp docker-compose.yml myvm1:~

4. 再次运行docker stack deploy命令:

docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"

5. 在浏览器中访问swarm的任意节点的网页(例如:http://192.168.99.101),然后你便能看到访问者计数器的结果。现在,示例swarm已经能够正常运行了,并且会将数据存储在Redis之中,页面如下图所示:

查看访问者计数器页面

除此之外,你还可以访问任意节点的IP地址,查看运行于8080端口的可视化服务的页面,你将会看到redis服务伴随着webvisualizer服务一起运行,如下图所示:

查看具有Redis服务的堆栈状态

回顾

正如你知道的,堆栈是相互关联的服务,它们会同时运行。你不用感到吃惊,其实你在本系列教程的第三部分就已经使用堆栈了。你已经学会如何向堆栈添加更多的服务,你可以将新服务的配置信息插入编排文件。最后,你还学会了placement配置项和volumes配置项的使用方法,你可以创建一个用于持久化数据的永久目录。因此,当容器被删除或重新部署时,你的应用程序的数据就不会丢失了。

最近发表
标签列表