这个《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入门:稍高级的话题

4.1 引言

本节将scale(伸缩扩展,后面直接用该单词)我们的应用程序,并启用负载均衡。为了实现这个目标,我们必须在分布式程序的架构层级中,升格一个层次,进入service层:

stack

service

container

4.2 关于service

在分布式应用程序中,一个app有多个部分组成,每个部分可称为一个service。例如,对于一个视频分享网站,它很可能包括多个服务:一个服务用于将应用程序数据保存到数据库中;一个服务用于将用户上传的数据在后台进行视频转码;一个服务用于前端;等等。

Services只是”containers in production”。一个服务只能运行一个映像。它使对映像的运行方式进行规范:比如,应该使用的端口号;比如,为了使这个service满足特定的性能,它需要运行的容器的副本数,等等。Scale一个service,改变了运行这个软件部分的容器实例的数量,并在进程中为这个service分配了更多的计算资源。

幸运的是,在Docker平台上,定义、运行和scale一个service非常简单,你要做的,只是写一个docker-compose.yml文件。

4.3 第一个docker-compose.yml文件

一个docker-compose.yml文件时一个YAML文件,它定义了Docker容器在产品中的行为方式(A docker-compose.yml file defines how Docker containers should behave in production.)。

创建文件docker-compose.yml文件,内容如下。确保上一节上你所创建的映像已经推送到registry中了。根据你的映像信息,修改.yml中的username/repo:tag部分。

version: ""

services:

  web:

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

    image: username/repo:tag

    deploy:

      replicas: 5

      resources:

        limits:

          cpus: "0.1"

          memory: 50M

      restart_policy:

        condition: on-failure

    ports:

      - "80:80"

    networks:

      - webnet

networks:

  webnet:

这个docker-compose.yml文件告诉Docker要做以下事情:

(1)从registry中拉取映像(该映像上一节已经上传到registry中了);

(2)运行这个映像的5个实例,并把它们作为一个service,这个service的名字叫web。限制每个映像实例最多使用10%的CPU以及50MB的RAM;

(3)如果某一个实例运行失败,则重新启动容器;

(4)将主机的80端口映射到web的80端口;

(5)命令web的所有容器通过负载均衡网络来共享80端口,这个负载均衡网络的名称为webnet(而在内部,这些容器会在一个临时端口上发布web的80端口)。

(6)使用默认配置来定义webnet网络(这是一个负载均衡网络)。

◆ 想知道Compose文件的版本、名称和命令?

在上面的.yml文件中,设置该Compose文件的版本为version:”3”。这主要是为了让它和swarm mode相兼容。在使用负载均衡或优化每个service(如web)的性能时,我们可以使用deploy key(要求Compose的文件版本至少为3.x)及其子选项。我们可以使用命令docker stack deploy来运行该文件(求Compose的文件版本至少为3.x)。我们也可以使用docker-compose up来运行版本为3的文件(使用non swarm配置),但是我们主要集中在stack部署上,因为我们要构建一个swarm示例。

另外,你可以选择任何有意义的名字来命名这个Compose文件。Docker-compose.yml只是一个标准的名字。如果你愿意,你也可以修改这个文件的名字为docker-stack.yml。

4.4 运行这个可负载均衡的app

在运行docker stack deploy命令之前,要先运行如下命令:

[root@localhost stackapp]# docker swarm init

Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses on interface ens33 (2002:de00:9d8:13:e5bd:c0f4:4442:2f01 and fec0::13:c1ed:f7ca:7553:ac46) - specify one with --advertise-addr

[root@localhost stackapp]# docker swarm init --advertise-addr 192.168.137.100

Swarm initialized: current node (wb84qmjkg6a5fcjyctwu1w9bm) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-2artmf0hhoogqfr4vyedfb70mtzweuzl1xpmt2i30ucu4u7dem-37vux6r0nqwq5srf9b2ls73tl 192.168.137.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

◆ 注意:下一节我们将讲解这个命令。如果不首先运行命令docker swarm init,将会出现错误”this node is not a swarm manager”。

现在可以运行了,运行时需要提供一个程序名称,比如getstartedlab:

[root@localhost stackapp]# docker stack deploy -c docker-compose.yml getstartedlab

Creating network getstartedlab_webnet

Creating service getstartedlab_web

这个service stack将在主机上运行映像的5个容器实例。

运行如下命令获取应用程序中这个service的信息:

[root@localhost stackapp]# docker service ls

ID            NAME           MODE         REPLICAS       IMAGE                  PORTS

zpirjxrx0a2k getstartedlab_web replicated  5/5 robin/get-started:part2   *:80->80/tcp

可以看到该命令输出了web这个service,以app名称开头。同时列出了service ID,副本数量,映像名称以及暴露的端口号。

Docker swarms运行许多任务,这些任务用于生成容器。任务拥有状态和ID,下面命令可以查看一个service的所有任务:

[root@localhost stackapp]# docker service ps getstartedlab_web

ID                              NAME                        IMAGE                         NODE     DESIRED STATE    CURRENT STATE    ERROR      PORTS

u8mloe2aazxm        getstartedlab_web.1   robin/get-started:part2   localhost.localdomain   Running             Running 9 minutes ago

ymqip7d7609n        getstartedlab_web.2   robin/get-started:part2   localhost.localdomain   Running             Running 9 minutes ago

nt6jz4ve6g25        getstartedlab_web.3   robin/get-started:part2   localhost.localdomain   Running             Running 9 minutes ago

r2vab9f056x6        getstartedlab_web.4   robin/get-started:part2   localhost.localdomain   Running             Running 9 minutes ago

u0uo3p4f5cgy        getstartedlab_web.5   robin/get-started:part2   localhost.localdomain   Running             Running 9 minutes ago

接下来进一步窥探这些任务,通过如下命令输出该任务的container ID:

docker inspect --format='{{.Status.ContainerStatus.ContainerID}}' <task>

具体运行结果为:

[root@localhost stackapp]# docker inspect --format='{{.Status.ContainerStatus.ContainerID}}' ymqip7d7609n

17cf23c88c62a88885d42d8c3abf966bb4252591f726db708e694daf70cfae67

反过来,你也可以通过容器ID,来获取到任务ID,命令如下:

docker inspect --format="{{index .Config.Labels \"com.docker.swarm.task.id\"}}" <container>

命令运行结果如下:

[root@localhost stackapp]# docker inspect --format="{{index .Config.Labels \"com.docker.swarm.task.id\"}}" 17cf23c88c62a88885d42d8c3abf966bb4252591f726db708e694daf70cfae67

ymqip7d7609n8erb6jln555r8

下面列出所有的容器:

[root@localhost stackapp]# docker container ls -q

8a2580dc2365

17cf23c88c62

39d373308296

3ce07d66e7ef

a6f5914f3ead

下面在浏览器中输入URL,并多次刷新:

每次刷新,可以看到容器ID变化了,从而演示了负载均衡功能。浏览器每次请求时,采用round-robin的方式来选择5个副本中的一个,来响应请求。

  ◆ 注意:在这里,响应一个HTTP请求可能需要30秒,这并不能说明Docker或者swarm的性能,因为Redis的依赖缺失导致响应较长。到现在,因为同样的原因,访客数量统计也没有实现,因为我们还没有添加用于持久化数据的服务。

4.5 Scale这个app

可以通过修改docker-compose.yml文件中的replicas数值来scale这个app,保存修改后,重新运行命令docker stack deploy:

[root@localhost stackapp]# docker stack deploy -c docker-compose.yml getstartedlab

Updating service getstartedlab_web (id: zpirjxrx0a2kkbcssry0hut9x)

将replicas的数值修改为8。运行上面命令后,Docker将会立即更新,不需要关闭stack或杀死任何容器。

然后在运行命令docker container ls –q来看看重新配置的实例。如果你增加了副本数量,相应的,就会增加更多的任务,增加更多的容器。

[root@localhost stackapp]# docker container ls -q

7b05af8ade35

1215e3c20797

9394135300ec

8a2580dc2365

17cf23c88c62

39d373308296

3ce07d66e7ef

a6f5914f3ead

4.6 关闭app和swarm

4.6.1 关闭app

使用命令docker stack rm来关闭app:

[root@localhost stackapp]# docker stack rm getstartedlab

Removing service getstartedlab_web

Removing network getstartedlab_webnet

[root@localhost stackapp]# docker container ls -q

[root@localhost stackapp]#

4.6.2 关闭swarm

命令docker stack rm只是移除了app,但是我们的单节点swarm还依然在运行:

[root@localhost stackapp]# docker node ls

ID                           HOSTNAME               STATUS  AVAILABILITY  MANAGER STATUS  wb84qmjkg6a5fcjyctwu1w9bm *  localhost.localdomain  Ready   Active        Leader

使用如下命令来关闭swarm:

[root@localhost stackapp]# docker swarm leave --force

Node left the swarm.

[root@localhost stackapp]# docker node ls

Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.

[root@localhost stackapp]#

这就移除了swarm。重要的一点,你创建swarm所在的命令行shell,和运行swarm的虚拟“Docker machines”所在的命令行shell,是同一个命令行shell。所以,后面你就不会迷惑于究竟你使用的是哪个Dockerized host,或者你使用的是哪个swarm。

本节学习了在单个机器上运行swarm,下节将学习在机器集群上运行swarm。

◆ 注意:Compose文件用于在Docker下定义应用程序。通过使用Docker Cloud,可以将该文件上传到云上。

4.7 总结

产品中实现容器的方式就是将容器作为service来运行。Service使用Compose文件来规范一个容器的行为,这个文件可以scale、约束、重新部署我们的app。即便是service在运行中,改变该service也能够立即生效。

4.8 本节命令

本节命令列表:

docker stack ls                                            # List stacks or apps
docker stack deploy -c <composefile> <appname> # Run the specified Compose file
docker service ls # List running services associated with an app
docker service ps <service> # List tasks associated with an app
docker inspect <task or container> # Inspect task or container
docker container ls -q # List container IDs
docker stack rm <appname> # Tear down an application
docker swarm leave --force # Take down a single node swarm from the manager

Docker入门(四):服务(Services)的更多相关文章

  1. docker 入门3 - 服务 【翻译】

    入门,第 3 部分:服务 先决条件 安装 Docker 版本 1.13 或更高版本. 获取 Docker Compose.在适用于 Mac 和 Docker 桌面的 Windows 上,它已预安装,因 ...

  2. docker(三):服务services

    docker中services位于container上面,services可以控制image的运行方式,包括image运行时所需资源的大小 创建yml文件 yml文件定义了容器运行时的行为.我们先创建 ...

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

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

  4. Docker入门(六):Stacks

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

  5. Docker入门(五):Swarms

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

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

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

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

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

  8. Docker入门(一):简介

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

  9. Docker 入门 第四部分: Swarms

    目录 Docker 入门 第四部分: Swarms 先决条件 介绍 理解Swarm集群 部署swarm 创建一个集群 在swarm集群上部署你的app应用 为 swarm管理器配置一个docker-m ...

随机推荐

  1. zeroMQ研究(转)

    偶尔一个机会,了解了下zeroMQ消息队列. 1  ZeroMQ概述 ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型.连接处理.帧.甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接 ...

  2. opensearch空查询

    query子句不支持为空的查询,可以使用filter子句:filter=area=""   或者 filter=filedlen(area)=0 可以使用相关性函数实现:https ...

  3. struts2 环境建立(1)

    说明:以下操作都是以本机例 在java web 开发之前,应该具备开发环境.要搭建开发环境应该具备以下工作: 1 JDK,jdk是java开发不可缺少的开发工具包. 2. 开发工具本例使用Eclips ...

  4. 【BZOJ2476】战场的数目 矩阵乘法

    [BZOJ2476]战场的数目 Description Input 输入文件最多包含25组测试数据,每个数据仅包含一行,有一个整数p(1<=p<=109),表示战场的图形周长.p=0表示输 ...

  5. Darwin做直播时对ReflectorSession引用数的控制

    在之前的博客中,我们提到了如何用Darwin&live555实现直播过程,那么更进一步,当直播结束时,我们需要关闭所有正在收看的客户端,并且delete转发会话ReflectorSession ...

  6. toitorsegit and toitorstsvn文件夹icon冲突不显示

    Go to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer Add a new string value & ...

  7. cocos2d-js添加广点通插屏(通过jsb反射机制)

    1.把广点通的jar包加入libs文件夹 2.修改AndroidManifest.xml文件 添加权限: <uses-permission android:name="android. ...

  8. 洛谷 2868 [USACO07DEC]观光奶牛Sightseeing Cows

    题目戳这里 一句话题意 L个点,P条有向边,求图中最大比率环(权值(Fun)与长度(Tim)的比率最大的环). Solution 巨说这是0/1分数规划. 话说 0/1分数规划 是真的难,但貌似有一些 ...

  9. 关于JavaScript中prototype机制的理解

    最近几天一直在研究JavaScript中原型的机制,从开始的似懂非懂,到今天终于有所领悟.不敢说彻底理解,但是起码算知道怎么回事了. 为什么一开始似懂非懂 开始了解一遍原型机制后,感觉知其然但不知其所 ...

  10. opencv轮廓提取、轮廓识别相关要点

    1.轮廓提取 src = cv2.imread("***.jpg", cv2.IMREAD_COLOR) gray = cv2.cvtColor(src ,cv2.COLOR_BG ...