返回介绍

四、Docker 服务

发布于 2025-11-02 16:55:27 字数 51264 浏览 0 评论 0 收藏

Docker 容器包含运行应用所需的所有二进制文件和依赖项。用户只需要运行 Docker 容器来启动和访问应用。CoreOS Linux 操作系统安装了 Docker,甚至可以在不安装 Docker 的情况下运行 Docker 命令。

问题

默认情况下,Docker 容器仅在单个节点上启动。然而,对于正常运行时间和冗余很重要的生产环境,您需要在多台主机上运行您的应用。

当使用 docker run 命令启动 Docker 容器时,该容器仅在单个主机上启动,如图 4-1 所示。软件通常不被设计成仅在单个主机上运行。例如,生产环境中的 MySQL 数据库可能需要跨主机集群运行,以实现冗余和高可用性。为单个主机设计的应用应该能够根据需要扩展到多个主机。但是分布式 Docker 应用不能在单个 Docker 引擎上运行。

A454123_1_En_4_Fig1_HTML.gif

图 4-1。

Docker container on a single host

解决方案

Docker Swarm 模式使 Docker 应用能够跨由覆盖网络连接的分布式 Docker 引擎集群运行,如图 4-2 所示。Docker 服务可以用特定数量的副本来创建,每个副本可能在集群中的不同主机上运行。群由一个或多个管理节点组成,由一个领导者负责群管理和协调。工作节点运行实际的服务任务,默认情况下,管理节点是工作节点。停靠服务只能从领导者节点启动。因此,在工作节点上调度的服务副本运行分布式应用。分布式应用提供了一些好处,例如容错、故障转移、增加容量和负载均衡等。

A454123_1_En_4_Fig2_HTML.gif

图 4-2。

Docker service tasks and containers spread across the nodes

本章涵盖以下主题:

  • 设置环境
  • Docker 服务命令
  • 服务类型
  • 创建服务
  • 列出服务的任务
  • 在命令行上调用 Hello World 服务任务
  • 获取关于服务的详细信息
  • 在浏览器中调用 Hello World 服务
  • 为 MySQL 数据库创建服务
  • 扩展服务
  • 列出服务任务
  • 在 Docker 容器中访问 MySQL 数据库
  • 更新服务
  • 更新副本
  • 更新 Docker 映像标签
  • 更新放置约束
  • 更新环境变量
  • 更新 Docker 映像
  • 更新容器标签
  • 更新资源设置
  • 移除服务

设置环境

使用第 3 章中讨论的过程,创建一个由一个管理者和两个工作者节点组成的 Docker 群。首先,启动三个 CoreOS 实例 - 一个用于群管理器,两个用于群工作者。获取群管理器的公共 IP 地址,如图 4-3 中 EC2 控制台所示。

A454123_1_En_4_Fig3_HTML.jpg

图 4-3。

EC2 instances for Swarm

以 docker 用户身份 SSH 登录 Swarm manager 实例。

[root@localhost ∼]# ssh -i   "docker.pem"  docker@34.200.225.39
Welcome to Docker!

使用 docker node ls 命令应该会在群中列出三个节点 - 一个管理节点和两个工作节点。

∼ $ docker node ls
ID                          HOSTNAME                       STATUS  AVAILABILITY  MANAGER STATUS
ilru4f0i280w2tlsrg9hglwsj   ip-172-31-10-132.ec2.internal  Ready   Active              
w5to186ipblpcq390625wyq2e   ip-172-31-37-135.ec2.internal  Ready   Active              
zkxle7kafwcmt1sd93kh5cy5e * ip-172-31-13-155.ec2.internal  Ready   Active        Leader

可以使用 docker node promote <node ip> 命令将工作节点提升为管理节点。

∼ $ docker node promote ilru4f0i280w2tlsrg9hglwsj
Node ilru4f0i280w2tlsrg9hglwsj promoted to a manager in the swarm.

如果再次列出节点,应该会列出两个管理器节点。管理器节点由 管理器状态 列中的值标识。一个节点的管理器状态为 Reachable ,另一个节点的状态为 Leader

∼ $ docker node ls
ID                          HOSTNAME                       STATUS  AVAILABILITY  MANAGER STATUS
ilru4f0i280w2tlsrg9hglwsj   ip-172-31-10-132.ec2.internal  Ready   Active        Reachable
w5to186ipblpcq390625wyq2e   ip-172-31-37-135.ec2.internal  Ready   Active              
zkxle7kafwcmt1sd93kh5cy5e * ip-172-31-13-155.ec2.internal  Ready   Active        Leader

作为领导者的管理节点执行所有的群管理和协调。可到达的管理者节点加入 raft 共识仲裁,并且如果当前领导者节点变得不可用,则有资格被选举为新的领导者。

拥有多个管理器节点增加了群的容错性,但是一个或两个群管理器提供了相同的容错性。如果需要,还可以将一个或多个工作节点提升为管理节点,以提高容错能力。

对于到 Swarm 实例的连接,修改与 Swarm manager 和 worker 实例相关联的安全组的入站规则,以允许所有流量。与群组节点相关联的安全组的入站规则如图 4-4 所示。

A454123_1_En_4_Fig4_HTML.jpg

图 4-4。

Setting inbound rules on a security group to allow all traffic

与群组管理器相关联的安全组的出站规则如图 4-5 所示。

A454123_1_En_4_Fig5_HTML.jpg

图 4-5。

Setting outbound rules on a security group to allow all traffic

docker 服务命令

docker service 命令用于管理 Docker 服务。 docker service 命令提供了表 4-1 中列出的子命令。

表 4-1。

The docker service Sub-Commands

| 命令 | 描述 | | --- | --- | | `docker service create` | 创建新服务。 | | `docker service inspect` | 显示一项或多项服务的详细信息。 | | `docker service logs` | 获取服务的日志。Docker 17.0.6 中添加了该命令。 | | `docker service ls` | 列出服务。 | | `docker service ps` | 列出一个或多个服务的任务。 | | `docker service rm` | 删除一个或多个服务。 | | `docker service scale` | 扩展一个或多个复制服务。 | | `docker service update` | 更新服务。 |

要运行 docker service 命令,必须满足以下要求。

  • 必须启用 Docker 群组模式
  • 命令必须从作为领导者的群管理器节点运行

docker service 命令仅在群组模式下可用,不能在群组模式外运行。

不能从工作节点运行 docker service 命令。工作节点不能用于查看或修改群集群状态。

服务类型

Docker Swarm 模式支持两种类型的服务,也称为服务模式 - 复制服务和全局服务。全局服务只在 Docker 集群中的每个节点上运行一个任务。复制服务作为配置数量的任务运行,这些任务也称为副本,默认为一个。副本的数量可以在创建新服务时指定,并且可以在以后更新。默认服务类型是复制服务。全局服务要求将 --mode 选项设置为 global 。只有复制的服务可以扩展;全球服务无法扩展。

我们从创建一个复制服务开始。在本章的后面,我们还将讨论创建一个全局服务。

创建服务

创建 Docker 服务的命令语法如下。

docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]

表 4-2 中列出了一些支持的选项。

表 4-2。

Supported Options for Creating a Service

| [计]选项 | 描述 | | --- | --- | | `--constraint` | 位置约束。 | | `--container-label` | 容器标签。 | | `--env, -e` | 设置环境变量。 | | `--env-file` | 读入环境变量文件。直到 Docker 1.13 才添加选项。 | | `--host` | 设置一个或多个自定义主机到 IP 的映射。直到 Docker 1.13 才添加选项。格式为`host:ip`。 | | `--hostname` | 容器主机名。直到 Docker 1.13 才添加选项。 | | `--label, -l` | 服务标签。 | | `--limit-cpu` | 限制 CPU。默认值为 0.000。 | | `--limit-memory` | 限制记忆。默认值为 0。 | | `--log-driver` | 服务的日志驱动程序。 | | `--log-opt` | 日志驱动程序选项。 | | `--mode` | 服务模式。值可以是复制的或全局的。默认为`replicated`。 | | `--mount` | 将文件系统挂载附加到服务。 | | `--name` | 服务名称。 | | `--network` | 网络附件。默认情况下,使用 入口 覆盖网络。 | | `--publish, -p` | 将端口发布为节点端口。 | | `--read-only` | 以只读方式挂载容器的根文件系统。直到文件 17.03 才添加选项。默认为`false`。 | | `--` `replicas` | 任务数量。 | | `--reserve-cpu` | 保留 CPU。默认值为 0.000。 | | `--reserve-memory` | 保留记忆。默认值为 0。 | | `--restart-condition` | 满足条件时重新启动。值可以是无、失败时或任何。 | | `--restart-delay` | 重新启动尝试之间的延迟(ns|us|ms|s|m|h)。 | | `--restart-max-attempts` | 放弃前重新启动的最大次数。 | | `--tty, -t` | 是否分配一个伪 TTY。直到 Docker 1.13 才添加选项。默认为`false`。 | | `--update-delay` | 更新之间的延迟(ns|us|ms|s|m|h)。默认值为 0s。 | | `--update-failure-action` | 更新失败时的操作。值可以是`pause`或`continue`。默认值是`pause`。 | | `--update-monitor` | 每次任务更新后监视失败的持续时间(ns|us|ms|s|m|h)。默认值为 0s。 | | `--update-parallelism` | 同时更新的最大任务数。值为 0 表示一次更新所有内容。默认值为`1`。 | | `--user, -u` | 用户名或 UID 格式:`[:]`。 | | `--workdir, -w` | 容器内的工作目录。 |

例如,创建一个名为 hello-world 的服务,其 Docker 映像 tutum/hello-world 由两个副本组成。公开主机端口 8080 上的服务。如果成功, docker service create 命令输出一个服务 ID。

∼ $ docker service create \
>   --name hello-world \
>   --publish 8080:80 \
>   --replicas 2 \
>   tutum/hello-world
vyxnpstt351124h12niqm7s64

服务被创建。

列出服务的任务

您可以使用以下命令列出服务任务,在复制服务的上下文中也称为副本。

docker service ps hello-world

列出了两项服务任务。

∼ $ docker service ps hello-world
ID              NAME           IMAGE                      NODE                     DESIRED STATE   CURRENT STATE            ERROR               PORTS
zjm03bjsqyhp    hello-world.1  tutum/hello-world:latest   ip-172-31-10-132.ec2.internal Running         Running 41 seconds ago                       
kezidi82ol5c    hello-world.2  tutum/hello-world:latest   ip-172-31-13-155.ec2.internal Running         Running 41 seconds ago                       

ID 列列出了任务 ID。任务名称的格式为 servicename.nhello-world.1hello-world.2 为两个复制品。Docker 映像也会列出。 NODE 列列出了调度任务的节点的私有 dn。 DESIRED STATE 是服务定义中定义的期望状态。 CURRENT STATE 是任务的实际状态。有时,由于缺乏 CPU 和内存方面的资源容量,任务可能处于挂起状态。

服务任务是运行 Docker 容器的插槽。在运行任务的每个节点上,Docker 容器也应该在运行。Docker 容器可以用 docker ps 命令列出。

∼ $ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED        STATUS              PORTS                          NAMES
0ccdcde64e7d        tutum/hello-world:latest      "/bin/sh -c 'php-f..."   2 minutes agoUp 2 minutes        80/tcp                         hello-world.2.kezidi82ol5ct81u59jpgfhs1

在命令行上调用 Hello World 服务任务

<hostname>:8080 使用 curl 调用 hello-world 服务。 curl 命令输出是服务的 HTML 标记。

∼ $ curl ec2-34-200-225-39.compute-1.amazonaws.com:8080
<html>
<head>
        <title>Hello world!</title>
        <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
        <style>
        body {
                background-color: white;
                text-align: center;
                padding: 50px;
                font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
        }

        #logo {
                margin-bottom: 40px;
        }
        </style>
</head>
<body>
        <img id="logo" src="logo.png" />
        <h1>Hello world!</h1>
        <h3>My hostname is 20b121986df6</h3>
</body>
</html>

获取关于服务的详细信息

要获得关于 hello-world 服务的详细信息,请运行 docker service inspect 命令。

docker service inspect  hello-world

详细信息包括容器规格、资源、重启策略、位置、模式、更新配置、端口(目标端口和发布端口)、虚拟 IPs 和更新状态。

∼ $ docker service inspect  hello-world
[
    {
        "ID": "vyxnpstt351124h12niqm7s64",
        "Version": {
            "Index": 30
        },
        "CreatedAt": "2017-07-23T19:00:09.98992017Z",
        "UpdatedAt": "2017-07-23T19:00:09.993001487Z",
        "Spec": {
            "Name": "hello-world",
            "Labels": {},
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "tutum/hello-world:latest@sha256:0d57def8055178aafb4c7669cbc25ec17f0acdab97cc587f30150802da8f8d85",
                    "StopGracePeriod": 10000000000,
                    "DNSConfig": {}
                },
                "Resources": {
                    "Limits": {},
                    "Reservations": {}
                },
                "RestartPolicy": {
                    "Condition": "any",
                    "Delay": 5000000000,
                    "MaxAttempts": 0
                },
                "Placement": {
                    "Platforms": [
                        {
                            "Architecture": "amd64",
                            "OS": "linux"
                        }
                    ]
                },
                "ForceUpdate": 0,
                "Runtime": "container"
            },
            "Mode": {
                "Replicated": {
                    "Replicas": 2
                }
            },
            "UpdateConfig": {
                "Parallelism": 1,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "RollbackConfig": {
                "Parallelism": 1, 

                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "EndpointSpec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 80,
                        "PublishedPort": 8080,
                        "PublishMode": "ingress"
                    }
                ]
            }
        },
        "Endpoint": {
            "Spec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 80,
                        "PublishedPort": 8080,
                        "PublishMode": "ingress"
                    }
                ]
            },
            "Ports": [
                {
                    "Protocol": "tcp",
                    "TargetPort": 80,
                    "PublishedPort": 8080,
                    "PublishMode": "ingress"
                }
            ],
            "VirtualIPs": [
                {
                    "NetworkID": "y3k655bdlp3x102a2bslh4swh",
                    "Addr": "10.255.0.5/16"
                }
            ]
        }
    }

]

在浏览器中调用 Hello World 服务

Hello World 服务可以在浏览器中使用托管群节点的 EC2 实例的公共 DNS 来调用。服务副本不一定要在节点上运行才能从该节点调用服务。你从 EC2 控制台获取一个 manager 节点的公共 DNS,如图 4-3 所示。使用 <Public DNS>:<Published Port> URL 调用 Hello World 服务。随着 Hello World 服务在端口 8080 上公开或发布,浏览器中要调用的 URL 变成了 <Public DNS>:8080 。服务被调用,服务输出显示在浏览器中,如图 4-6 所示。

A454123_1_En_4_Fig6_HTML.jpg

图 4-6。

Invoking a service in a browser

类似地,您可以获得一个托管有 Swarm worker 节点的 EC2 实例的公共 DNS,如图 4-7 所示。

A454123_1_En_4_Fig7_HTML.jpg

图 4-7。

Obtaining the public DNS for a EC2 instance on which a Swarm worker node is hosted

在浏览器中使用 PublicDNS:8080 URL 调用服务,如图 4-8 所示。

A454123_1_En_4_Fig8_HTML.jpg

图 4-8。

Invoking a service in a browser using public DNS for a EC2 instance on which a Swarm worker node is hosted

默认情况下,manager 节点也是 worker 节点,服务任务也在 manager 节点上运行。

为 MySQL 数据库创建服务

接下来,我们为 MySQL 数据库创建一个服务。使用 mysql Docker 映像与使用 tutum/hello-world Docker 映像在两个方面有所不同。

  • mysql Docker 映像有一个名为 MYSQL_ROOT_PASSWORD 的强制环境变量。
  • mysql Docker 镜像基于一个 Debian Linux,启动 Docker 容器中的 MySQL 数据库服务器,而 tutum/hello-world 镜像基于 Alpine Linux,启动 Apache 服务器运行 PHP 应用。

运行下面的 docker service create 命令来创建 MySQL 数据库服务的一个副本。使用环境变量 MYSQL_ROOT_PASSWORD 提供一个 root 密码。包括重启条件、重启最大尝试次数、更新延迟和更新失败操作的一些其他选项。用 docker service rm mysql 命令删除任何以前运行的名为 mysql 的 Docker 服务。

∼ $ docker service create \
   --env MYSQL_ROOT_PASSWORD='mysql'\
   --replicas 1 \
   --restart-condition none \
   --restart-max-attempts 5 \
   --update-failure-action continue \
   --name mysql \
   --update-delay 10s \
  mysql

为 MySQL 数据库创建一个服务,并输出服务 ID。

∼ $ docker service create \
>   --env MYSQL_ROOT_PASSWORD='mysql'\
>   --replicas 1 \
>   --restart-condition none \
>   --restart-max-attempts 5 \

>   --update-failure-action continue \
>   --name mysql \

>   --update-delay 10s \
>  mysql
gzl8k1wy8kf3ms1nu5zwlfxm6

docker service ls 命令列出服务;应该会列出 mysql 服务。

∼ $ docker service ls
ID             NAME         MODE        REPLICAS  IMAGE                      PORTS
gzl8k1wy8kf3   mysql        replicated  1/1       mysql:latest               
vyxnpstt3511   hello-world  replicated  2/2       tutum/hello-world:latest   *:8080->80/tcp

docker service ps mysql 命令列出服务任务/副本。一个任务正在管理器工作节点上运行。

∼ $ docker service ps mysql
ID              NAME        IMAGE               NODE          DESIRED STATE   CURRENT STATE                                      ERROR               PORTS
mfw76m4rxbhp    mysql.1     mysql:latest        ip-172-31-37-135.ec2.internalRunning         Running 16 seconds ago   

如何调度服务任务,包括基于节点排序的节点选择,将在第 8 章中讨论,该章涵盖了调度。

扩展服务

接下来,我们扩展 mysql 服务。只有复制的服务可以扩展,扩展一个或多个服务的命令语法如下。

docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...]

要将 mysql 服务扩展到三个任务,运行以下命令。

docker service scale mysql=3

如命令输出所示, mysql 服务扩展到三个。

∼ $ docker service scale mysql=3
mysql scaled to 3

列出服务任务

列出服务任务的 docker service ps 命令语法如下。

docker service ps [OPTIONS] SERVICE [SERVICE...]

该命令支持表 4-3 中列出的选项。

表 4-3。

Options for the docker service ps Command

| [计]选项 | 描述 | | --- | --- | | `--filter, -f` | 根据提供的条件过滤输出。支持以下滤镜:`id=` `name=` `node=` `desired-state=(running | shutdown | accepted)` | | `--no-resolve` | 是否将 id 映射到名称。默认值为`false`。 | | `--no-trunc` | 是否截断输出。直到 Docker 1.13 才添加选项。默认值为`false`。 | | `--quiet, -q` | 是否只显示任务标识号。直到 Docker 1.13 才添加选项。默认值为`false`。 |

例如,您可以仅列出正在运行的服务任务。

docker service ps –f desired-state=running mysql

仅列出正在运行的任务。

∼ $ docker service ps -f desired-state=running mysql
ID                  NAME                     IMAGE          NODE            DESIRED STATE       CURRENT STATE            ERROR          PORTS
mfw76m4rxbhp        mysql.1                  mysql:latest   ip-172-31-37-135.ec2.internal Running             Running 46 seconds ago                  
s4flvtode8od        mysql.2                  mysql:latest   ip-172-31-13-155.ec2.internal Running             Running 8 seconds ago                    
j0jd92p5dmd8        mysql.3                  mysql:latest   ip-172-31-10-132.ec2.internal Running             Running 9 seconds ago                          

所有任务都在运行;所以使用滤镜的效果不是很明显。但是,在随后的示例中,当一些任务没有运行时,您将列出正在运行的服务任务。

如果节点的数量大于任务的数量,则不是所有的工作节点都用于运行服务任务,例如当 hello-worldmysql 服务运行的任务少于三个时。如果副本的数量大于群中节点的数量,则一个节点可以运行多个服务任务。扩展到五个复制副本会在两个节点上启动多个复制副本。

∼ $ docker service scale mysql=5
mysql scaled to 5
∼ $ docker service ps mysql
ID                  NAME                        IMAGE          NODE           DESIRED STATE       CURRENT STATE               ERROR          PORTS
mfw76m4rxbhp        mysql.1                     mysql:latest   ip-172-31-37-135.ec2.internal Running             Running about a minute ago                       
s4flvtode8od        mysql.2                     mysql:latest   ip-172-31-13-155.ec2.internal Running             Running 44 seconds ago                           
j0jd92p5dmd8        mysql.3                     mysql:latest   ip-172-31-10-132.ec2.internal Running             Running 45 seconds ago                       
vh9qxhm452pt        mysql.4                     mysql:latest   ip-172-31-37-135.ec2.internal Running             Running 26 seconds ago                       
6jtkvstssnkf        mysql.5                     mysql:latest   ip-172-31-10-132.ec2.internal Running             Running 26 seconds ago                           

管理器节点上仅运行一个 mysql 服务副本;因此,只有一个用于 mysql 服务的 Docker 容器在 manager 节点上运行。

∼ $ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                 NAMES
6bbe40000874        mysql:latest        "docker-entrypoint..."About a minute ago  Up About a minute   3306/tcp               mysql.2.s4flvtode8odjjere2zsi9gdx

扩展到 10 个任务会在每个群节点上启动多个任务。

∼ $ docker service scale mysql=10
mysql scaled to 10
∼ $ docker service ps -f desired-state=running mysql
ID                  NAME               IMAGE            NODE            DESIRED STATE       CURRENT STATE                       ERROR               PORTS
s4flvtode8od        mysql.2            mysql:latest     ip-172-31-13-155.ec2.internal Running             Running about a minute ago                       
j0jd92p5dmd8        mysql.3            mysql:latest     ip-172-31-10-132.ec2.internalRunning             Running 2 minutes ago                            
6jtkvstssnkf        mysql.5            mysql:latest     ip-172-31-10-132.ec2.internalRunning             Running about a minute ago                       
jxunbdec3fnj        mysql.6            mysql:latest     ip-172-31-37-135.ec2.internalRunning             Running 14 seconds ago                           
t1nz59dyoi2s        mysql.7            mysql:latest     ip-172-31-10-132.ec2.internalRunning             Running 14 seconds ago                         
lousvchdirn9        mysql.8            mysql:latest     ip-172-31-13-155.ec2.internalRunning             Running 14 seconds ago                           
94ml0f52344d        mysql.9            mysql:latest     ip-172-31-37-135.ec2.internalRunning             Running 14 seconds ago                           
pd40sd7qlk3j        mysql.10           mysql:latest     ip-172-31-13-155.ec2.internalRunning             Running 14 seconds ago                           

对于在管理器节点上运行的三个任务,管理器节点上的 mysql 服务的 Docker 容器的数量增加到三个。

∼ $ docker ps
CONTAINER ID        IMAGE              COMMAND                  CREATED         STATUS              PORTS                         NAMES
15e3253f69f1        mysql:latest       "docker-entrypoint..."   50 seconds ago      Up 49 seconds       3306/tcp                      mysql.8.lousvchdirn9fv8wot5vivk6d
cca7ab20c914        mysql:latest       "docker-entrypoint..."   50 seconds ago      Up 49 seconds       3306/tcp                      mysql.10.pd40sd7qlk3jc0i73huop8e4r
6bbe40000874        mysql:latest       "docker-entrypoint..."   2 minutes ago       Up 2 minutes        3306/tcp                      mysql.2.s4flvtode8odjjere2zsi9gdx

因为您将在后面的部分通过 MySQL 数据库服务示例了解更多关于 Docker 服务的内容,并且为了完整性,接下来我们将讨论使用 MySQL 数据库的 Docker 容器来创建数据库表。

在 Docker 容器中访问 MySQL 数据库

接下来,我们访问 Docker 容器中的 MySQL 数据库。在每个实例上运行时, docker ps 命令会列出实例上 mysql 服务的 Docker 容器。用 docker exec –it <containerid> bash 命令启动 Docker 容器的 bash shell。为 Docker 容器显示 root 提示符。

∼ $ docker exec -it 15e3253f69f1 bash
root@15e3253f69f1:/#

以用户 root 的身份使用 mysql 命令启动 MySQL CLI。出现提示时指定密码;使用环境变量 MYSQL_ROOT_PASSWORDdocker service create 命令的 --env 选项中指定了用于创建服务的密码。显示 mysql> CLI 命令提示符。

root@15e3253f69f1:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.19 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>

使用 use mysql 命令将数据库设置为 mysql

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

用下面的 SQL 脚本创建一个数据库表。

CREATE  TABLE  wlslog(time_stamp VARCHAR(45) PRIMARY KEY,category VARCHAR(25),type VARCHAR(25),servername VARCHAR(25),code VARCHAR(25),msg VARCHAR(45));

创建了 wlslog 表。

mysql> CREATE  TABLE  wlslog(time_stamp VARCHAR(45) PRIMARY KEY,category VARCHAR(25),type VARCHAR(25),servername VARCHAR(25),code VARCHAR(25),msg VARCHAR(45));
Query OK, 0 rows affected (0.06 sec)

从 MySQL CLI 运行以下 SQL 命令,向 wlslog 表添加一些数据。

mysql> INSERT INTO wlslog VALUES('Apr-8-2014-7:06:16-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to STANDBY');
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO wlslog VALUES('Apr-8-2014-7:06:17-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to STARTING');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO wlslog VALUES('Apr-8-2014-7:06:18-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to ADMIN');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO wlslog VALUES('Apr-8-2014-7:06:19-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to RESUMING');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO wlslog VALUES('Apr-8-2014-7:06:20-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000331','Started WebLogic AdminServer');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO wlslog VALUES('Apr-8-2014-7:06:21-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to RUNNING');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO wlslog VALUES('Apr-8-2014-7:06:22-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000360','Server started in RUNNING mode');
Query OK, 1 row affected (0.00 sec)

运行 SQL 查询以列出数据库表数据。

mysql> SELECT * FROM wlslog;
+---------------------------+----------+----------------+-------------+------------+---------------------------------+
| time_stamp                | category | type           | servername  | code       | msg                             |
+---------------------------+----------+----------------+-------------+------------+---------------------------------+
| Apr-8-2014-7:06:16-PM-PDT | Notice   | WebLogicServer | AdminServer | BEA-000365 | Server state changed to STANDBY |
| Apr-8-2014-7:06:17-PM-PDT | Notice   | WebLogicServer | AdminServer | BEA-000365 | Server state changed to STARTING|
| Apr-8-2014-7:06:18-PM-PDT | Notice   | WebLogicServer | AdminServer | BEA-000365 | Server state changed to ADMIN   |
| Apr-8-2014-7:06:19-PM-PDT | Notice   | WebLogicServer | AdminServer | BEA-000365 | Server state changed to RESUMING|
| Apr-8-2014-7:06:20-PM-PDT | Notice   | WebLogicServer | AdminServer | BEA-000331 | Started WebLogic AdminServer    |
| Apr-8-2014-7:06:21-PM-PDT | Notice   | WebLogicServer | AdminServer | BEA-000365 | Server state changed to RUNNING |
| Apr-8-2014-7:06:22-PM-PDT | Notice   | WebLogicServer | AdminServer | BEA-000360 | Server started in RUNNING mode  |
+---------------------------+----------+----------------+-------------+------------+---------------------------------+
7 rows in set (0.00 sec)

使用 exit 命令退出 MySQL CLI 和 bash shell。

mysql> exit
Bye
root@15e3253f69f1:/# exit
exit

更新服务

服务可以在使用 docker service update 命令创建后更新,其语法如下:

docker service update [OPTIONS] SERVICE

表 4-4 中列出了一些支持的选项。

表 4-4。

Options for the docker service update Command

| [计]选项 | 描述 | | --- | --- | | `--args` | 命令的参数。 | | `--constraint-add` | 添加或更新放置约束。 | | `--constraint-rm` | 删除放置约束。 | | `--container-label-add` | 添加或更新 Docker 容器标签。 | | `--container-label-rm` | 通过关键字移除容器标签。 | | `--env-add` | 添加或更新环境变量。 | | `--env-rm` | 删除环境变量。 | | `--` `force` | 是否强制更新,即使没有需要更新的更改。Docker 1.13 中增加了选项。默认为`false`。 | | `--group-add` | 向容器中添加额外的补充用户组。Docker 1.13 中增加了选项。 | | `--group-rm` | 从容器中删除以前添加的补充用户组。Docker 1.13 中增加了选项。 | | `--host-add` | 添加或更新自定义主机到 IP 的映射(`host:ip`)。Docker 1.13 中增加了选项。 | | `--host-rm` | 删除自定义主机到 IP 的映射(`host:ip`)。Docker 1.13 中增加了选项。 | | `--hostname` | 更新容器主机名。Docker 1.13 中增加了选项。 | | `--image` | 更新服务映像标签。 | | `--label-add` | 添加或更新服务标签。 | | `--label-rm` | 通过标签的键移除标签。 | | `--limit-cpu` | 更新极限 CPU。默认值为 0.000。 | | `--limit-memory` | 更新极限内存。默认值为 0。 | | `--log-driver` | 更新服务的日志记录驱动程序。 | | `--log-opt` | 更新日志记录驱动程序选项。 | | `--mount-add` | 在服务上添加或更新装载。 | | `--mount-rm` | 按装载的目标路径删除装载。 | | `--publish-add` | 添加或更新发布的端口。 | | `--publish-rm` | 通过目标端口删除发布的端口。 | | `--read-only` | 以只读方式挂载容器的根文件系统。在 Docker 17.06 中添加了选项。默认为`false`。 | | `--replicas` | 更新任务数量。 | | `--reserve-cpu` | 更新备用 CPU。默认值为 0.000。 | | `--reserve-memory` | 更新保留内存。默认值为 0。 | | `--restart-condition` | 满足条件时更新重启(无、失败时或任何)。 | | `--restart-delay` | 更新重新启动尝试之间的延迟(ns|us|ms|s|m|h)。 | | `--restart-max-attempts` | 放弃前更新最大重启次数。 | | `--` `rollback` | 是否回滚到以前的规范。Docker 1.13 中增加了选项。默认为`false`。 | | `--tty, -t` | 是否分配一个伪 TTY。Docker 1.13 中增加了选项。默认为`false`。 | | `--update-delay` | 更新之间的更新延迟(ns|us|ms|s|m|h)。默认值为 0s。 | | `--update-failure-action` | 更新失败时的更新操作(暂停|继续)。默认为`pause`。 | | `--update-monitor` | 每次任务更新后监视失败的持续时间(ns|us|ms|s|m|h)。Docker 1.13 中增加了选项。默认 0s。 | | `--update-parallelism` | 更新同时更新的最大任务数(0 表示一次更新所有任务)。默认为`1`。 | | `--user, -u` | 添加用户名或 UID(格式:`[:]`)。 | | `--workdir, -w` | 更新容器内的工作目录。 |

接下来,我们更新已部署服务的一些参数。

更新副本

首先,创建一个要更新的 mysql 服务。

docker service create \
  --env MYSQL_ROOT_PASSWORD='mysql'\
  --replicas 1 \
  --restart-condition on-failure \
  --restart-max-attempts 5 \
  --update-failure-action continue \
  --name mysql \
  --update-delay 10s \
 mysql:5.6

来自 Docker 映像 mysql:5.6 的服务被创建,并且服务 ID 被输出。

∼ $ docker service rm mysql

mysql

∼ $ docker service create \
>   --env MYSQL_ROOT_PASSWORD='mysql'\
>   --replicas 1 \
>   --restart-condition on-failure \
>   --restart-max-attempts 5 \
>   --update-failure-action continue \
>   --name mysql \
>   --update-delay 10s \
>  mysql:5.6
mecdt3zluvlvxqc3hdpw8edg1

使用 docker service update 命令将副本数量更新为五个。如果命令成功,将从命令中输出服务名。

∼ $ docker service update --replicas 5 mysql
mysql

将副本设置为五个并不只是启动四个新任务,从而使任务总数达到五个。当更新服务以更改副本数量时,所有服务任务都将关闭,并启动新任务。随后列出的服务任务中,第一个任务被关闭,五个新任务被启动。

∼ $ docker service ps mysql
ID                  NAME                IMAGE               NODE          DESIRED STATE       CURRENT STATE                     ERROR                         PORTS
jen0fmkjj13k        mysql.1             mysql:5.6           ip-172-31-37-135.ec2.internalRunning             Starting less than a second ago                                 
r616gx588opd         \_ mysql.1         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 5 seconds ago              "task: non-zero exit (137)"   
y350n4e8furo        mysql.2             mysql:5.6           ip-172-31-13-155.ec2.internalRunning             Running 7 seconds ago                                           
ktrwxnn13fug        mysql.3             mysql:5.6           ip-172-31-37-135.ec2.internalRunning             Running 14 seconds ago                                          
2t8j1zd8uts1        mysql.4             mysql:5.6           ip-172-31-10-132.ec2.internalRunning             Running 10 seconds ago                                          
8tf0uuwb8i31        mysql.5             mysql:5.6           ip-172-31-10-132.ec2.internalRunning             Running 10 seconds ago                                          

更新 Docker 映像标签

从针对 Docker image mysql:5.6 的名为 mysql 的 MySQL 数据库服务开始,接下来我们将该服务更新为一个不同的 Docker image 标签 - mysql:latest Docker image。运行以下命令来更新 Docker 映像;输出服务名以表明更新成功。

∼ $ docker service update --image mysql:latest mysql
mysql

您可以使用 docker service inspect 命令列出服务的详细信息。 ContainerSpec 中列出的映像是 mysql:latestPreviousSpec 也在列。

∼ $ docker service inspect  mysql
[
    {
         "Spec": {
            "Name": "mysql",
            "Labels": {},
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": 

"mysql:latest@sha256:75c563c474f1adc149978011fedfe2e6670483d133b22b07ee32789b626f8de3",
                    "Env": [
                        "MYSQL_ROOT_PASSWORD=mysql"
                    ],
        "PreviousSpec": {
            "Name": "mysql",
            "Labels": {},
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "mysql:5.6@sha256:6ad5bd392c9190fa92e65fd21f6debc8b2a76fc54f13949f9b5bc6a0096a5285",
]

即使 docker service update 命令完成了,更新也不会立即完成。当服务正在更新时,服务的 UpdateStatus 被列出, State 被设置为 "updating""update in progress"Message

"UpdateStatus": {
            "State": "updating",
            "StartedAt": "2017-07-23T19:24:15.539042747Z",
            "Message": "update in progress"
               }

更新完成后, UpdateStatus State 变为 "completed"Message 变为 "update completed"

        "UpdateStatus": {
            "State": "completed",
            "StartedAt": "2017-07-23T19:24:15.539042747Z",
            "CompletedAt": "2017-07-23T19:25:25.660907984Z",
            "Message": "update completed"
        }

当服务正在更新时,服务任务正在关闭,新的服务任务正在启动。当更新开始时,一些正在运行的任务可能基于先前的映像 mysql:5.6 ,而其他的可能基于新的映像 mysql:latest

∼ $ docker service ps mysql
ID                  NAME                IMAGE               NODE                  DESIRED STATE       CURRENT STATE            ERROR                         PORTS
jen0fmkjj13k        mysql.1             mysql:5.6           ip-172-31-37-135.ec2.internalRunning             Running 38 seconds ago                                 
r616gx588opd         \_ mysql.1         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 43 seconds ago    "task: non-zero exit (137)"   
y350n4e8furo        mysql.2             mysql:5.6           ip-172-31-13-155.ec2.internalRunning             Running 45 seconds ago                                 
bswz4sm8e3vj        mysql.3             mysql:5.6           ip-172-31-37-135.ec2.internalRunning             Running 6 seconds ago                                  
ktrwxnn13fug         \_ mysql.3         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 12 seconds ago    "task: non-zero exit (1)"     
wj1x26wvp0pt        mysql.4             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 7 seconds ago                                  
2t8j1zd8uts1         \_ mysql.4         mysql:5.6           ip-172-31-10-132.ec2.internalShutdown            Shutdown 7 seconds ago                                 
hppq840ekrh7        mysql.5             mysql:latest        ip-172-31-10-132.ec2.internalRunning             Running 2 seconds ago                                  
8tf0uuwb8i31         \_ mysql.5         mysql:5.6           ip-172-31-10-132.ec2.internalShutdown            Failed 8 seconds ago     "task: non-zero exit (1)"     

映像为 mysql:5.6 的任务的期望状态被设置为 Shutdown 。渐渐地,所有基于新形象 mysql:latest 的新服务任务都开始了。

∼ $ docker service ps mysql
ID                  NAME                IMAGE               NODE                         DESIRED STATE       CURRENT STATE               ERROR                         PORTS
2uafxtcbj9qj        mysql.1             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 30 seconds ago                                    
jen0fmkjj13k         \_ mysql.1         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 36 seconds ago       "task: non-zero exit (137)"   
r616gx588opd         \_ mysql.1         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed about a minute ago   "task: non-zero exit (137)"   
mkv95bvx3sl1        mysql.2             mysql:latest        ip-172-31-13-155.ec2.internalReady               Ready 3 seconds ago                                       
y350n4e8furo         \_ mysql.2         mysql:5.6           ip-172-31-13-155.ec2.internalShutdown            Failed 4 seconds ago        "task: non-zero exit (137)"   
yevunzer12vm        mysql.3             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 12 seconds ago                                    
bswz4sm8e3vj         \_ mysql.3         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Shutdown 12 seconds ago                                   
ktrwxnn13fug         \_ mysql.3         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 48 seconds ago       "task: non-zero exit (1)"     
wj1x26wvp0pt        mysql.4             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 44 seconds ago                                    
2t8j1zd8uts1         \_ mysql.4         mysql:5.6           ip-172-31-10-132.ec2.internalShutdown            Shutdown 44 seconds ago                                   
hppq840ekrh7        mysql.5             mysql:latest        ip-172-31-10-132.ec2.internalRunning             Running 39 seconds ago                                    
8tf0uuwb8i31         \_ mysql.5         mysql:5.6           ip-172-31-10-132.ec2.internalShutdown            Failed 44 seconds ago       "task: non-zero exit (1)"     

前面介绍了使用 –f 选项过滤服务任务。要查找在特定节点上调度了哪些任务(如果有的话),可以运行 docker service ps 命令,并将过滤器设置为该节点。然后列出过滤后的任务,包括 RunningShutdown

∼ $ docker service ps  -f node=ip-172-31-13-155.ec2.internal mysql
ID                  NAME                IMAGE               NODE                  DESIRED STATE       CURRENT STATE                ERROR                         PORTS
mkv95bvx3sl1        mysql.2             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running about a minute ago                                 
y350n4e8furo         \_ mysql.2         mysql:5.6           ip-172-31-13-155.ec2.internalShutdown            Failed about a minute ago    "task: non-zero exit (137)"   
oksssg7gsh79        mysql.4             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 50 seconds ago                                     
wj1x26wvp0pt         \_ mysql.4         mysql:latest        ip-172-31-13-155.ec2.internalShutdown            Failed 55 seconds ago        "task: non-zero exit (1)"     

服务任务也可以通过期望的状态来过滤。要仅列出正在运行的任务,请将 desired-state 过滤器设置为 running

∼ $ docker service ps -f desired-state=running mysql
ID                  NAME                IMAGE               NODE                     
DESIRED STATE       CURRENT STATE           ERROR               PORTS
2uafxtcbj9qj        mysql.1             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 3 minutes ago                       
mkv95bvx3sl1        mysql.2             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 2 minutes ago                       
yevunzer12vm        mysql.3             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 2 minutes ago                       
oksssg7gsh79        mysql.4             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 2 minutes ago                       
hppq840ekrh7        mysql.5             mysql:latest        ip-172-31-10-132.ec2.internalRunning             Running 3 minutes ago                       

同样,通过将 desired-state 过滤器设置为 shutdown ,仅列出关闭任务。

∼ $ docker service ps -f desired-state=shutdown mysql
ID                  NAME                IMAGE               NODE                 DESIRED STATE       CURRENT STATE            ERROR                         PORTS
jen0fmkjj13k        mysql.1             mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 3 minutes ago     "task: non-zero exit (137)"   
r616gx588opd         \_ mysql.1         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 3 minutes ago     "task: non-zero exit (137)"   
y350n4e8furo        mysql.2             mysql:5.6           ip-172-31-13-155.ec2.internalShutdown            Failed 2 minutes ago     "task: non-zero exit (137)"   
bswz4sm8e3vj        mysql.3             mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Shutdown 2 minutes ago                                 
ktrwxnn13fug         \_ mysql.3         mysql:5.6           ip-172-31-37-135.ec2.internalShutdown            Failed 3 minutes ago     "task: non-zero exit (1)"     
wj1x26wvp0pt        mysql.4             mysql:latest        ip-172-31-13-155.ec2.internalShutdown            Failed 2 minutes ago     "task: non-zero exit (1)"     
2t8j1zd8uts1         \_ mysql.4         mysql:5.6           ip-172-31-10-132.ec2.internalShutdown            Shutdown 3 minutes ago                                 
8tf0uuwb8i31        mysql.5             mysql:5.6           ip-172-31-10-132.ec2.internalShutdown            Failed 3 minutes ago     "task: non-zero exit (1)"     

更新放置约束

可通过 --constraint-add--constraint-rm 选项添加/删除布局约束。我们从一个由三个节点组成的集群开始 - 一个管理节点和两个工作节点。然后,我们将一个工作节点提升为管理节点,从而形成一个包含两个管理节点和一个工作节点的集群。。

从跨群节点运行的服务副本开始,可以使用以下命令将副本限制为仅在工作节点上运行。如果成功, docker service update 命令输出服务名。

∼ $ docker service update --constraint-add  "node.role==worker" mysql
mysql

可能需要一段时间(几秒或几分钟) 来协调服务的期望状态,在此期间,即使 node.role 被设置为 worker 或者运行的任务少于所需的数量,任务也可以在管理器节点上运行。当更新完成时(更新状态可以从 docker service inspect 命令中找到),列出 mysql 服务正在运行的任务表明这些任务只在工作节点上运行。

∼ $ docker service ps -f desired-state=running mysql
ID                  NAME                IMAGE               NODE                  DESIRED STATE       CURRENT STATE                ERROR               PORTS
smk5q4nhu1rw        mysql.1             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running about a minute ago                       
wzmou8f6r2tg        mysql.2             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 23 seconds ago                           
byavev89hukv        mysql.3             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 23 seconds ago                           
erx409p0sgcc        mysql.4             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 53 seconds ago                           
q7eqw8jlqig8        mysql.5             mysql:latest        ip-172-31-37-135.ec2.internalRunning             Running 46 seconds ago                           

作为另一个例子, mysql 服务的服务任务可以被限制为仅在管理器节点上运行。从运行在 manager 和 worker 节点上的服务任务开始,并且没有添加其他约束,运行以下命令将所有任务放置在 manager 节点上。

∼ $ docker service update --constraint-add 'node.role==manager' mysql
mysql

任务不会在工作者节点上关闭,而是立即在管理器节点上启动,并且最初可能会继续在工作者节点上运行。

过一会儿再列出服务副本。您将看到所有的任务都在管理器节点上列为 running

∼ $ docker service ps -f desired-state=running mysql
ID                  NAME                IMAGE               NODE                     DESIRED STATE       CURRENT STATE                ERROR               PORTS
7tj8bck4jr5n        mysql.1             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 14 seconds ago                           
uyeu3y67v2rt        mysql.2             mysql:latest        ip-172-31-10-132.ec2.internalRunning             Running about a minute ago                       
lt9p7479lkta        mysql.3             mysql:latest        ip-172-31-10-132.ec2.internalRunning             Running 1 second ago                             
t7d9c4viuo5y        mysql.4             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 40 seconds ago                           
8xufz871yx1x        mysql.5             mysql:latest        ip-172-31-13-155.ec2.internalRunning             Running 27 seconds ago                           

更新环境变量

--env-add--env-rm 选项用于在服务中添加/删除环境变量。我们创建的 mysql 服务只包含一个环境变量 - 强制的 MYSQL_ROOT_PASSWORD 变量。您可以使用 docker service update 命令添加环境变量 MYSQL_DATABASEMYSQL_PASSWORDMYSQL_ALLOW_EMPTY_PASSWORD ,并在同一个命令中将 MYSQL_ROOT_PASSWORD 更新为空密码。如果成功,该命令将输出服务名称。

∼ $ docker service update --env-add 'MYSQL _DATABASE=mysql'   --env-add 'MYSQL_PASSWORD=mysql'  --env-add 'MYSQL_ALLOW_EMPTY_PASSWORD=yes'  --env-add 'MYSQL_ROOT_PASSWORD=yes'  mysql
mysql

当更新完成后, docker service inspect 命令列出添加的环境变量。

∼ $ docker service inspect mysql
[...
        "Spec": {
            "Name": "mysql",
...
                    "Env": [
                        "MYSQL_ROOT_PASSWORD=yes",
                        "MYSQL _DATABASE=mysql",
                        "MYSQL_PASSWORD=mysql",
                        "MYSQL_ALLOW_EMPTY_PASSWORD=yes"
                    ],
...
]

更新环境变量会导致容器重新启动。因此,简单地添加环境变量不会导致在同一个容器中创建新的数据库。使用更新后的环境变量启动一个新容器。

更新 Docker 映像

Docker 映像也可以被更新,而不仅仅是映像标签。例如,更新 MySQL 数据库服务的 Docker 映像,以使用用于 PostgreSQL 数据库的 postgres Docker 映像。如果更新成功,该命令将输出服务名称。

∼ $ docker service update --image postgres mysql
mysql

更新完成后,显示正在运行的服务任务会列出 postgres 映像的新任务。服务名保持不变,Docker 映像更新为 postgres

∼ $ docker service ps -f desired-state=running mysql
ID                  NAME                IMAGE               NODE                          DESIRED STATE       CURRENT STATE                ERROR               PORTS
hmk7128ls19a        mysql.1             postgres:latest     ip-172-31-13-155.ec2.internalRunning             Running 18 seconds ago                           
5ofbkc82gp0i        mysql.2             postgres:latest     ip-172-31-10-132.ec2.internalRunning             Running about a minute ago                       
v0gfc65lhw62        mysql.3             postgres:latest     ip-172-31-13-155.ec2.internalRunning             Running 31 seconds ago                           
miscjf9n66qq        mysql.4             postgres:latest     ip-172-31-13-155.ec2.internalRunning             Running 45 seconds ago                           
g5viy8jyzpi1        mysql.5             postgres:latest     ip-172-31-10-132.ec2.internalRunning             Running about a minute ago                 

更新 Docker 映像并不会删除与 mysql Docker 映像相关联的环境变量,这些变量仍然列在服务细节中。

∼ $ docker service inspect mysql
[
 ...
        "Spec": {
            "Name": "mysql",
...
                "ContainerSpec": {
                    "Env": [
                        "MYSQL_ROOT_PASSWORD=yes",
                        "MYSQL _DATABASE=mysql",
                        "MYSQL_PASSWORD=mysql",
                        "MYSQL_ALLOW_EMPTY_PASSWORD=yes"
                    ],
...
]

需要删除为 MySQL 数据库添加的环境变量,因为 PostgreSQL 数据库 Docker 映像 postgres 不使用相同的环境变量。使用 docker service update 命令的 --env-rm 选项删除 mysql 服务中的所有环境变量。要仅删除 env 变量,需要指定名称,而不是 env 值。

docker service update --env-rm 'MYSQL_DATABASE'   --env-rm 'MYSQL_PASSWORD'  --env-rm 'MYSQL_ALLOW_EMPTY_PASSWORD'  --env-rm 'MYSQL_ROOT_PASSWORD'  mysql

更新容器标签

--container-label - add--container-label-rm 选项用于更新服务的 Docker 容器标签。要将容器标签添加到 mysql 服务中,运行一个 docker service update 命令,如果成功,它将输出服务名。

∼ $ docker service update --container-label-add 'com.docker.swarm.service.version=latest' mysql
mysql

在列出服务的详细信息时,添加的标签会在 ContainerSpec 标签中列出。

∼ $ docker service inspect mysql

[
...
                "ContainerSpec": {
                    "Labels": {
                        "com.docker.swarm.service.version": "latest"
                    },
...
]

添加的标签可通过 --container-label-rm 选项移除。要仅删除标签,需要指定键,而不是标签值。

∼ $ docker service update --container-label-rm  'com.docker.swarm.service.version' mysql
mysql

更新资源设置

docker service update 命令的 --limit-cpu--limit-memory--reserve-cpu--reserve-memory 选项用于更新服务的资源设置。例如,更新资源限制和储量。如果成功,该命令将输出服务名称。

∼ $ docker service update --limit-cpu 0.5  --limit-memory 1GB --reserve-cpu "0.5"  --reserve-memory "1GB" mysql
mysql

资源设置已更新。服务细节列出了 Resources JSON 对象中更新的资源设置。

∼ $ docker service inspect mysql
[
   ...
                "ContainerSpec": {
                "Resources": {
                    "Limits": {
                        "NanoCPUs": 500000000,
                        "MemoryBytes": 1073741824
                    },
                    "Reservations": {
                        "NanoCPUs": 500000000,
                        "MemoryBytes": 1073741824
                    }
                },
...
]

移除服务

docker service rm 命令删除一个服务。如果该命令的输出是服务名,则该服务已被删除。所有相关的服务任务和 Docker 容器也被删除。

∼ $ docker service rm mysql
mysql

创建全球服务

如前所述,服务有两种模式 - 复制模式或全局模式。默认模式是复制。该模式也可通过 docker service create 命令的 --mode 选项明确设置为复制。创建服务后,不能更新服务模式,例如使用 docker service update 命令。使用 --mode 选项为 nginx 创建一个复制服务。

∼ $ docker service create --mode replicated  --name nginx nginx
no177eh3gxsyemb1gfzc99mmd

复制模式服务是使用默认的副本数量 1 创建的。用 docker service ls 命令列出服务。 nginx 服务与一个副本一起列出。

∼ $ docker service ls
ID               NAME          MODE          REPLICAS        IMAGE        PORTS
no177eh3gxsy     nginx         replicated    1/1             nginx:latest               

默认情况下,全局服务在集群中的每个节点上运行一个任务。有时可能需要全局服务,例如需要在每个节点上运行的代理(日志/监控)。全局服务用于第 11 章 中的登录。接下来,我们创建一个全球性的 nginx Docker 基于映像的服务。用 docker service rm nginx 命令删除复制的服务 nginx 。即使不同的服务具有不同的模式,服务名也必须是唯一的。接下来,使用与复制服务相同的命令创建一个全局模式 nginx 服务,除了将 --mode 选项设置为 global 而不是 replicated

∼ $ docker service create --mode global  --name nginx  nginx
5prj6c4v4be6ga0odnb22qa4n

创建全局模式服务。 docker service ls 命令列出了服务。全局服务的 REPLICAS 列没有列出副本的数量,因为没有创建副本。相反, global 被列在 REPLICAS 栏中。

∼ $ docker service ls
ID                  NAME            MODE        REPLICAS          IMAGE          PORTS
5prj6c4v4be6        nginx           global      3/3               nginx:latest               

在任务可以运行的群中的每个节点上为全局服务创建服务任务。调度约束可以与全局服务一起使用,以防止在每个节点上运行任务。第 章和第 章讨论了时间安排。全球服务无法扩展。

摘要

本章介绍了在 Docker 集群上运行的 Docker 服务。服务由服务任务或副本组成。Docker Swarm 支持两种类型的服务 - 复制服务和全局服务。复制的服务具有指定数量的副本,并且是可伸缩的。全局服务在群中的每个节点上都有一个任务。术语 副本 在复制服务的上下文中用来指在群中的节点上运行的服务任务。复制的服务可以为一个服务运行指定数量的任务,这可能意味着在特定节点上不运行任何任务或运行多个任务。术语 副本 通常不在全局服务的上下文中使用,全局服务在集群中的每个节点上只运行一个任务。每个任务(副本) 与一个 Docker 容器相关联。我们从 Hello World 服务开始,并在命令行和浏览器中使用 curl 调用该服务。随后,我们讨论了 MySQL 数据库的服务。我们为 MySQL 服务容器启动了一个 bash shell,并创建了一个数据库表。扩展、更新和删除服务是本章介绍的其他一些服务功能。本章最后创建了一个全球服务。下一章将详细介绍 Docker Swarm scaling 服务。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。