四、Docker 服务
Docker 容器包含运行应用所需的所有二进制文件和依赖项。用户只需要运行 Docker 容器来启动和访问应用。CoreOS Linux 操作系统安装了 Docker,甚至可以在不安装 Docker 的情况下运行 Docker 命令。
问题
默认情况下,Docker 容器仅在单个节点上启动。然而,对于正常运行时间和冗余很重要的生产环境,您需要在多台主机上运行您的应用。
当使用 docker run 命令启动 Docker 容器时,该容器仅在单个主机上启动,如图 4-1 所示。软件通常不被设计成仅在单个主机上运行。例如,生产环境中的 MySQL 数据库可能需要跨主机集群运行,以实现冗余和高可用性。为单个主机设计的应用应该能够根据需要扩展到多个主机。但是分布式 Docker 应用不能在单个 Docker 引擎上运行。

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

图 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 控制台所示。

图 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 所示。

图 4-4。
Setting inbound rules on a security group to allow all traffic
与群组管理器相关联的安全组的出站规则如图 4-5 所示。

图 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.n ; hello-world.1 和 hello-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 所示。

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

图 4-7。
Obtaining the public DNS for a EC2 instance on which a Swarm worker node is hosted
在浏览器中使用 PublicDNS:8080 URL 调用服务,如图 4-8 所示。

图 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 映像在两个方面有所不同。
mysqlDocker 映像有一个名为MYSQL_ROOT_PASSWORD的强制环境变量。mysqlDocker 镜像基于一个 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-world 和 mysql 服务运行的任务少于三个时。如果副本的数量大于群中节点的数量,则一个节点可以运行多个服务任务。扩展到五个复制副本会在两个节点上启动多个复制副本。
∼ $ 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_PASSWORD 在 docker 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:latest 。 PreviousSpec 也在列。
∼ $ 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 命令,并将过滤器设置为该节点。然后列出过滤后的任务,包括 Running 和 Shutdown 。
∼ $ 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_DATABASE 、 MYSQL_PASSWORD 和 MYSQL_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 服务。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论