目录搜索
ComposeAbout versions and upgrading (Compose)ASP.NET Core + SQL Server on Linux (Compose)CLI environment variables (Compose)Command-line completion (Compose)Compose(组成)Compose command-line reference(组合命令行参考)Control startup order (Compose)Django and PostgreSQL (Compose)Docker stacks and distributed application bundles (Compose)docker-compose build(docker-compose构建)docker-compose bundledocker-compose configdocker-compose createdocker-compose downdocker-compose eventsdocker-compose execdocker-compose helpdocker-compose imagesdocker-compose killdocker-compose logsdocker-compose pausedocker-compose portdocker-compose psdocker-compose pulldocker-compose pushdocker-compose restartdocker-compose rmdocker-compose rundocker-compose scaledocker-compose startdocker-compose stopdocker-compose topdocker-compose unpausedocker-compose upEnvironment file (Compose)Environment variables in ComposeExtend services in ComposeFrequently asked questions (Compose)Getting started (Compose)Install ComposeLink environment variables (deprecated) (Compose)Networking in ComposeOverview of Docker ComposeOverview of docker-compose CLIQuickstart: Compose and WordPressRails and PostgreSQL (Compose)Sample apps with ComposeUsing Compose in productionUsing Compose with SwarmEngine.NET Core application (Engine)About images, containers, and storage drivers (Engine)Add nodes to the swarm (Engine)Apply custom metadata (Engine)Apply rolling updates (Engine)apt-cacher-ngBest practices for writing Dockerfiles (Engine)Binaries (Engine)Bind container ports to the host (Engine)Breaking changes (Engine)Build your own bridge (Engine)Configure container DNS (Engine)Configure container DNS in user-defined networks (Engine)CouchDB (Engine)Create a base image (Engine)Create a swarm (Engine)Customize the docker0 bridge (Engine)Debian (Engine)Default bridge networkDelete the service (Engine)Deploy a service (Engine)Deploy services to a swarm (Engine)Deprecated Engine featuresDocker container networking (Engine)Docker overview (Engine)Docker run reference (Engine)Dockerfile reference (Engine)Dockerize an applicationDrain a node (Engine)EngineFAQ (Engine)Fedora (Engine)Get started (Engine)Get started with macvlan network driver (Engine)Get started with multi-host networking (Engine)How nodes work (Engine)How services work (Engine)Image management (Engine)Inspect the service (Engine)Install Docker (Engine)IPv6 with Docker (Engine)Join nodes to a swarm (Engine)Legacy container links (Engine)Lock your swarm (Engine)Manage nodes in a swarm (Engine)Manage sensitive data with Docker secrets (Engine)Manage swarm security with PKI (Engine)Manage swarm service networks (Engine)Migrate to Engine 1.10Optional Linux post-installation steps (Engine)Overview (Engine)PostgreSQL (Engine)Raft consensus in swarm mode (Engine)Riak (Engine)Run Docker Engine in swarm modeScale the service (Engine)SDKs (Engine)Select a storage driver (Engine)Set up for the tutorial (Engine)SSHd (Engine)Storage driver overview (Engine)Store service configuration data (Engine)Swarm administration guide (Engine)Swarm mode key concepts (Engine)Swarm mode overlay network security model (Engine)Swarm mode overview (Engine)Understand container communication (Engine)Use multi-stage builds (Engine)Use swarm mode routing mesh (Engine)Use the AUFS storage driver (Engine)Use the Btrfs storage driver (Engine)Use the Device mapper storage driver (Engine)Use the OverlayFS storage driver (Engine)Use the VFS storage driver (Engine)Use the ZFS storage driver (Engine)Engine: Admin GuideAmazon CloudWatch logs logging driver (Engine)Bind mounts (Engine)Collect Docker metrics with Prometheus (Engine)Configuring and running Docker (Engine)Configuring logging drivers (Engine)Control and configure Docker with systemd (Engine)ETW logging driver (Engine)Fluentd logging driver (Engine)Format command and log output (Engine)Google Cloud logging driver (Engine)Graylog Extended Format (GELF) logging driver (Engine)Journald logging driver (Engine)JSON File logging driver (Engine)Keep containers alive during daemon downtime (Engine)Limit a container's resources (Engine)Link via an ambassador container (Engine)Log tags for logging driver (Engine)Logentries logging driver (Engine)PowerShell DSC usage (Engine)Prune unused Docker objects (Engine)Run multiple services in a container (Engine)Runtime metrics (Engine)Splunk logging driver (Engine)Start containers automatically (Engine)Storage overview (Engine)Syslog logging driver (Engine)tmpfs mountsTroubleshoot volume problems (Engine)Use a logging driver plugin (Engine)Using Ansible (Engine)Using Chef (Engine)Using Puppet (Engine)View a container's logs (Engine)Volumes (Engine)Engine: CLIDaemon CLI reference (dockerd) (Engine)dockerdocker attachdocker builddocker checkpointdocker checkpoint createdocker checkpoint lsdocker checkpoint rmdocker commitdocker configdocker config createdocker config inspectdocker config lsdocker config rmdocker containerdocker container attachdocker container commitdocker container cpdocker container createdocker container diffdocker container execdocker container exportdocker container inspectdocker container killdocker container logsdocker container lsdocker container pausedocker container portdocker container prunedocker container renamedocker container restartdocker container rmdocker container rundocker container startdocker container statsdocker container stopdocker container topdocker container unpausedocker container updatedocker container waitdocker cpdocker createdocker deploydocker diffdocker eventsdocker execdocker exportdocker historydocker imagedocker image builddocker image historydocker image importdocker image inspectdocker image loaddocker image lsdocker image prunedocker image pulldocker image pushdocker image rmdocker image savedocker image tagdocker imagesdocker importdocker infodocker inspectdocker killdocker loaddocker logindocker logoutdocker logsdocker networkdocker network connectdocker network createdocker network disconnectdocker network inspectdocker network lsdocker network prunedocker network rmdocker nodedocker node demotedocker node inspectdocker node lsdocker node promotedocker node psdocker node rmdocker node updatedocker pausedocker plugindocker plugin createdocker plugin disabledocker plugin enabledocker plugin inspectdocker plugin installdocker plugin lsdocker plugin pushdocker plugin rmdocker plugin setdocker plugin upgradedocker portdocker psdocker pulldocker pushdocker renamedocker restartdocker rmdocker rmidocker rundocker savedocker searchdocker secretdocker secret createdocker secret inspectdocker secret lsdocker secret rmdocker servicedocker service createdocker service inspectdocker service logsdocker service lsdocker service psdocker service rmdocker service scaledocker service updatedocker stackdocker stack deploydocker stack lsdocker stack psdocker stack rmdocker stack servicesdocker startdocker statsdocker stopdocker swarmdocker swarm cadocker swarm initdocker swarm joindocker swarm join-tokendocker swarm leavedocker swarm unlockdocker swarm unlock-keydocker swarm updatedocker systemdocker system dfdocker system eventsdocker system infodocker system prunedocker tagdocker topdocker unpausedocker updatedocker versiondocker volumedocker volume createdocker volume inspectdocker volume lsdocker volume prunedocker volume rmdocker waitUse the Docker command line (Engine)Engine: ExtendAccess authorization plugin (Engine)Docker log driver pluginsDocker network driver plugins (Engine)Extending Engine with pluginsManaged plugin system (Engine)Plugin configuration (Engine)Plugins API (Engine)Volume plugins (Engine)Engine: SecurityAppArmor security profiles for Docker (Engine)Automation with content trust (Engine)Content trust in Docker (Engine)Delegations for content trust (Engine)Deploying Notary (Engine)Docker security (Engine)Docker security non-events (Engine)Isolate containers with a user namespace (Engine)Manage keys for content trust (Engine)Play in a content trust sandbox (Engine)Protect the Docker daemon socket (Engine)Seccomp security profiles for Docker (Engine)Secure EngineUse trusted imagesUsing certificates for repository client verification (Engine)Engine: TutorialsEngine tutorialsNetwork containers (Engine)Get StartedPart 1: OrientationPart 2: ContainersPart 3: ServicesPart 4: SwarmsPart 5: StacksPart 6: Deploy your appMachineAmazon Web Services (Machine)Digital Ocean (Machine)docker-machine activedocker-machine configdocker-machine createdocker-machine envdocker-machine helpdocker-machine inspectdocker-machine ipdocker-machine killdocker-machine lsdocker-machine provisiondocker-machine regenerate-certsdocker-machine restartdocker-machine rmdocker-machine scpdocker-machine sshdocker-machine startdocker-machine statusdocker-machine stopdocker-machine upgradedocker-machine urlDriver options and operating system defaults (Machine)Drivers overview (Machine)Exoscale (Machine)Generic (Machine)Get started with a local VM (Machine)Google Compute Engine (Machine)IBM Softlayer (Machine)Install MachineMachineMachine CLI overviewMachine command-line completionMachine concepts and helpMachine overviewMicrosoft Azure (Machine)Microsoft Hyper-V (Machine)Migrate from Boot2Docker to MachineOpenStack (Machine)Oracle VirtualBox (Machine)Provision AWS EC2 instances (Machine)Provision Digital Ocean Droplets (Machine)Provision hosts in the cloud (Machine)Rackspace (Machine)VMware Fusion (Machine)VMware vCloud Air (Machine)VMware vSphere (Machine)NotaryClient configuration (Notary)Common Server and signer configurations (Notary)Getting started with NotaryNotary changelogNotary configuration filesRunning a Notary serviceServer configuration (Notary)Signer configuration (Notary)Understand the service architecture (Notary)Use the Notary client
文字

Swarm服务使用声明性模型,这意味着您可以定义所需的服务状态,并依靠Docker来维护此状态。该州包括诸如(但不限于)的信息:

  • 服务容器应该运行的映像名称和标记

  • 有多少个容器参与服务

  • 是否有任何端口暴露给群体外的客户

  • 当Docker启动时服务是否应该自动启动

  • 服务重新启动时发生的特定行为(例如是否使用滚动重启)

  • 服务可以运行的节点的特性(例如资源约束和布局偏好)

有关群体模式的概述,请参阅群体模式关键概念。有关服务如何工作的概述,请参阅服务如何工作。

创建一个服务

要创建没有额外配置的单副本服务,只需提供映像名称即可。该命令启动一个带有随机生成名称并且没有发布端口的Nginx服务。这是一个较为理想的例子,因为您将无法与Nginx服务交互。

$ docker service create nginx

该服务安排在可用节点上。要确认服务已成功创建并启动,请使用以下docker service ls命令:

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE                                                                                             PORTS
a3iixnklxuem        quizzical_lamarr    replicated          1/1                 docker.io/library/nginx@sha256:41ad9967ea448d7c2b203c699b429abe1ed5af331cd92533900c6d77490e0268

创建的服务并不总是立即运行。如果服务的图像不可用,如果没有节点满足您为服务配置的要求或其他原因,服务可能处于挂起状态。有关更多信息,请参阅待定服务。

要为您的服务提供名称,请使用以下--name标志:

$ docker service create --name my_web nginx

就像使用独立容器一样,您可以通过在映像名称后面添加它来指定服务容器应该运行的命令。此示例启动一个名为helloworld使用alpine图像并运行以下命令的服务ping docker.com

$ docker service create --name helloworld alpine ping docker.com

您也可以指定要使用的服务的图像标记。这个例子修改了前一个使用alpine:3.6标签:

$ docker service create --name helloworld alpine:3.6 ping docker.com

有关图像标签分辨率的更多详细信息,请参阅指定服务应使用的图像版本。

更新服务

您可以使用该docker service update命令更改有关现有服务的几乎所有内容。当您更新服务时,Docker会停止其容器并使用新配置重新启动它们。

由于Nginx是一个Web服务,如果您将端口80发布到群集外部的客户端,它将会更好。您可以在创建服务时使用-p--publish标志来指定。更新现有服务时,该标志是--publish-add。还有一个--publish-rm标志可以删除以前发布的端口。

假设my_web来自上一节的服务仍然存在,请使用以下命令将其更新为发布端口80。

$ docker service update --publish-add 80 my_web

要验证它是否有效,请使用docker service ls

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE                                                                                             PORTS
4nhxl7oxw5vz        my_web              replicated          1/1                 docker.io/library/nginx@sha256:41ad9967ea448d7c2b203c699b429abe1ed5af331cd92533900c6d77490e0268   *:0->80/tcp

有关发布端口如何工作的更多信息,请参阅发布端口。

您可以更新有关现有服务的几乎每个配置详细信息,包括其运行的图像名称和标记。请参阅创建后更新服务的图像。

删除服务

要删除服务,请使用该docker service remove命令。您可以通过其ID或名称来删除服务,如docker service ls命令的输出中所示。以下命令将删除该my_web服务。

$ docker service remove my_web

服务配置细节

以下各节提供有关服务配置的详细信息。本主题不包括每个标志或方案。在几乎所有可以在服务创建时定义配置的情况下,您也可以用类似的方式更新现有服务的配置。

看命令行的引用为docker service createdocker service update,或运行与所述那些命令中的一个--help标志。

配置运行时环境

您可以在容器中为运行时环境配置以下选项:

  • 使用--env标志的环境变量

  • 使用该--workdir标志的容器内的工作目录

  • 使用该--user标志的用户名或UID

以下服务的容器将有一个环境变量$MYVAR设置为myvalue,将从该/tmp/目录运行,并将作为my_user用户运行。

$ docker service create --name helloworld \  --env MYVAR=myvalue \  --workdir /tmp \  --user my_user \
  alpine ping docker.com

更新现有服务运行的命令

要更新现有服务运行的命令,可以使用该--args标志。下面的示例更新一个已调用的现有服务,helloworld以便它运行命令ping docker.com而不是之前运行的任何命令:

$ docker service update --args "ping docker.com" helloworld

指定服务应使用的映像版本

当您创建服务时未指定要使用的图像版本的任何详细信息时,该服务将使用带有latest标签标记的版本。您可以强制该服务以几种不同的方式使用特定版本的图像,具体取决于您想要的结果。

图像版本可以用几种不同的方式表达:

  • 如果您指定了一个标签,那么管理器(或Docker客户端,如果您使用内容信任)将该标签解析为摘要。当在工作节点上接收到创建容器任务的请求时,工作节点只会看到摘要,而不是标签。$ docker service create --name =“myservice”ubuntu:16.04一些标签代表离散版本,例如ubuntu:16.04。像这样的标签几乎总是会随着时间的推移逐渐形成稳定的摘要。建议您尽可能使用这种标签。其他类型的标签(如latestnightly)可能经常会解析为新的摘要,具体取决于图像作者更新标签的频率。建议不要使用经常更新的标签来运行服务,以防止使用不同映像版本的不同服务副本任务。

  • 如果您完全不指定版本,则按照惯例,图像的latest标记将被解析为摘要。创建服务任务时,工作人员使用此摘要中的图像。因此,以下两个命令是等价的:$ docker service create --name =“myservice”ubuntu $ docker service create --name =“myservice”ubuntu:latest

  • 如果直接指定摘要,则在创建服务任务时始终使用图像的确切版本。$ docker service create \ --name =“myservice”\ ubuntu:16.04@sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1

当你创建一个服务时,图像的标签被解析为特定消化的标记点,在服务创建的时间。该服务的工作者节点将永久使用该特定的摘要,除非该服务被明确更新。如果您使用经常更改的标签(例如,latest),此功能尤其重要,因为它可确保所有服务任务使用相同版本的图像。

注意:如果启用了内容信任,客户端实际上会在联系swarm管理器之前将图像的标签解析为摘要,以验证图像是否已签名。因此,如果您使用内容信任,swarm管理器会收到预先解决的请求。在这种情况下,如果客户端无法将图像解析为摘要,则请求失败。

如果管理者无法将标签解析为摘要,则每个工作者节点负责将标签解析为摘要,并且不同节点可以使用不同版本的图像。如果发生这种情况,将会记录下面的警告,用占位符代替真实信息。

unable to pin image <IMAGE-NAME> to digest: <REASON>

要查看图像的当前摘要,请发出命令docker检查<IMAGE>:<TAG>并查找RepoDigests行。 以下是Ubuntu的最新摘要:最新的内容写入时。 为了清晰起见,输出被截断。

$ docker inspect ubuntu:latest
"RepoDigests": [    "ubuntu@sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1"],

在创建服务之后,除非您使用--image标志显式运行docker服务更新,否则其映像永远不会更新,如下所述。 其他更新操作(如扩展服务,添加或删除网络或体积,重命名服务或任何其他类型的更新操作)不会更新服务的映像。

创建后更新服务的图像

每个标签代表一个摘要,类似于Git哈希。 一些标签,如最新的,经常更新以指向新的摘要。 其他的,比如ubuntu:16.04,代表一个已发布的软件版本,如果有的话,预计不会更新以指向新的摘要。 在Docker 1.13及更高版本中,当您创建服务时,它将被限制为使用图像的特定摘要创建任务,直到您使用带有--image标志的服务更新来更新服务。 如果您使用较旧版本的Docker Engine,则必须删除并重新创建该服务以更新其映像。

当您将service update使用该--image标志运行时,swarm管理器会查询Docker Hub或您的私人Docker注册中心以获取标记当前指向的摘要并更新服务任务以使用该摘要。

注意:如果您使用内容信任,Docker客户端解析图像,swarm管理器接收图像和摘要,而不是标签。

通常,管理员能够将标签解析为新的摘要和服务更新,重新部署每个任务以使用新图像。如果经理无法解决标签或发生其他问题,则接下来的两节概述了期望的内容。

如果管理者解析标签

如果swarm manager可以将image标签解析为摘要,它会指示工作节点重新部署任务并使用该摘要中的图像。

  • 如果工作人员在该摘要中缓存了图像,则会使用该图像。

  • 如果不是,它会尝试从Docker Hub或私有注册表中提取图像。

-  If it succeeds, the task is deployed using the new image.
-  If the worker fails to pull the image, the service fails to deploy on that worker node. Docker tries again to deploy the task, possibly on a different worker node.

如果管理者无法解析标签

如果swarm manager无法将图像解析为摘要,则全部不会丢失:

  • 管理员指示工作节点使用该标签处的图像重新部署任务。

  • 如果工作人员拥有解析为该标记的本地缓存图像,则它会使用该图像。

  • 如果工作人员没有解析为标签的本地高速缓存映像,则工作人员会尝试连接到Docker Hub或私有注册表以在该标签处拉取图像。

-  If this succeeds, the worker uses that image.
-  If this fails, the task fails to deploy and the manager tries again to deploy the task, possibly on a different worker node.

发布端口

在创建群集服务时,可以通过两种方式将该服务的端口发布到群集外的主机:

  • 你可以依靠路由网格。当您发布服务端口时,无论在该节点上运行的服务是否有任务,群集都可以在每个节点上的目标端口上访问该服务。这并不复杂,是许多类型服务的正确选择。

  • 您可以直接在运行该服务的群集节点上发布服务任务的端口。此功能在Docker 1.13和更高版本中可用。这绕过了路由网格,并提供了最大的灵活性,包括您开发自己的路由框架的能力。但是,您有责任跟踪每个任务的运行位置,并将请求路由到任务,并在各个节点之间进行负载平衡。

请继续阅读以获取更多信息和每种方法的用例。

使用路由网格发布服务的端口

要从外部向群发布服务的端口,请使用该--publish <TARGET-PORT>:<SERVICE-PORT>标志。群集使服务可以在每个群集节点的目标端口访问。如果外部主机连接到任何群集节点上的该端口,则路由网格会将其路由到任务。外部主机不需要知道服务任务的IP地址或内部使用端口与服务交互。当用户或进程连接到服务时,任何运行服务任务的工作节点都可能会响应。有关群集服务网络的更多详细信息,请参阅管理群集服务网络。

示例:在10节点群上运行三任务Nginx服务

假设您有一个10节点的群集,并且您部署了一个在10节点群集上运行三个任务的Nginx服务:

$ docker service create --name my_web \                        --replicas 3 \                        --publish 8080:80 \
                        nginx

三个任务将在最多三个节点上运行。您不需要知道哪些节点正在运行任务; 在10个节点中的任何节点上连接到端口8080 都会将您连接到三项nginx任务之一。你可以使用测试curl。以下示例假定这localhost是群集节点之一。如果情况并非如此,或者localhost无法解析到主机上的IP地址,请使用主机的IP地址或可解析的主机名称。

HTML输出被截断:

$ curl localhost:8080<!DOCTYPE html><html><head><title>Welcome to nginx!</title>...truncated...</html>

后续连接可能会路由到同一个群集节点或不同的节点。

直接在swarm节点上发布服务的端口

如果您需要根据应用程序状态做出路由决策,或者需要完全控制将请求路由到服务任务的流程,则使用路由网格可能不是您的应用程序的正确选择。 要直接在正在运行的节点上发布服务的端口,请使用mode = host选项指定--publish标志。

注意:如果您使用mode = host直接在群集节点上发布服务的端口,并设置published = <PORT>,则会创建隐式限制,您只能在给定群集节点上为该服务运行一个任务。 另外,如果您使用mode = host,并且您在docker service create上不使用--mode = global标志,则很难知道哪些节点正在运行该服务,以便将工作路由到它们。

示例:在每个群集节点上运行nginx Web服务器服务

nginx是一个开源的反向代理,负载均衡器,HTTP缓存和一个Web服务器。如果您使用路由网格将nginx作为服务运行,则连接到任何swarm节点上的nginx端口将显示(有效)运行该服务的随机群集节点的网页。

以下示例在群集中的每个节点上运行nginx作为服务,并在每个群集节点上本地公开nginx端口。

$ docker service create \  --mode global \  --publish mode=host,target=80,published=8080 \  --name=nginx \
  nginx:latest

您可以在每个群集节点的端口8080上访问nginx服务器。如果您将一个节点添加到swarm中,则会启动一个nginx任务。您不能在任何绑定到端口8080的群集节点上启动另一个服务或容器。

注意:这是一个理想的例子。为多层服务创建应用程序层路由框架非常复杂,超出了本主题的范围。

将服务连接到覆盖网络

您可以使用覆盖网络连接群中的一个或多个服务。

首先,使用docker network create带有--driver overlay标志的命令在管理器节点上创建覆盖网络。

$ docker network create --driver overlay my-network

在群集模式下创建覆盖网络后,所有管理节点都可以访问网络。

您可以创建新服务并传递该--network标志以将服务附加到覆盖网络:

$ docker service create \  --replicas 3 \  --network my-network \  --name my-web \
  nginx

群体扩展my-network到运行服务的每个节点。

您还可以使用该--network-add标志将现有服务连接到覆盖网络。

$ docker service update --network-add my-network my-web

要断开正在运行的服务与网络的连接,请使用该--network-rm标志。

$ docker service update --network-rm my-network my-web

有关覆盖网络和服务发现的更多信息,请参阅将服务附加到覆盖网络和Docker群集模式覆盖网络安全模型。

授予对秘密的服务访问权限

要创建一个访问Docker管理的机密的服务,请使用该--secret标志。有关更多信息,请参阅管理Docker服务的敏感字符串(机密)

控制服务规模和布局

Swarm模式有两种类型的服务:复制和全局。对于复制服务,您指定swarm管理器调度到可用节点的副本任务数。对于全局服务,调度程序在每个可用节点上放置一个任务。

您可以使用--mode标志来控制服务的类型。如果您未指定模式,则该服务默认为replicated。对于复制服务,您可以指定要使用该--replicas标志开始的副本任务数。例如,要使用3个副本任务启动复制的nginx服务:

$ docker service create \  --name my_web \  --replicas 3 \
  nginx

要在每个可用节点上启动全局服务,请传递--mode globaldocker service create。每当新节点变为可用时,调度程序就将全局服务的任务放置在新节点上。例如,要开始在群中每个节点上运行阿尔派的服务:

$ docker service create \  --name myservice \  --mode global \
  alpine top

通过服务约束,您可以在调度程序将服务部署到节点之前设置节点的条件。您可以根据节点属性和元数据或引擎元数据将约束应用于服务。有关约束的更多信息,请参阅docker service createCLI参考。

使用布置首选项将任务均匀分配到不同类别的节点上。一个可能有用的例子是在多个数据中心或可用区域之间平衡任务。在这种情况下,您可以使用展示位置首选项将任务分散到多个数据中心,并使面向本地中断时的服务更具弹性。您可以使用其他布局偏好设置来进一步将任务分成多组节点。例如,您可以在每个数据中心内的多个机架上平衡它们。有关约束的更多信息,请参阅docker service createCLI参考。

为服务预留内存或CPU

要为服务保留给定数量的内存或CPU数量,请使用--reserve-memory--reserve-cpu标志。如果没有可用的节点能够满足要求(例如,如果请求4个CPU并且群中没有节点具有4个CPU),则服务保持挂起状态,直到节点可用于运行其任务。

内存异常(OOME)

如果您的服务尝试使用比swarm节点更多的内存,则可能会遇到内存异常(OOME),并且容器或Docker守护进程可能会被内核OOM杀手所杀。要防止发生这种情况,请确保您的应用程序在具有足够内存的主机上运行,并且请参阅了解耗尽内存的风险。

Swarm服务允许您使用资源约束,布局首选项和标签来确保将您的服务部署到适当的群集节点。

指定服务布局偏好(-placement-pref)

您可以设置服务,将任务均匀分配到不同类别的节点上。可以有用的一个例子是在一组数据中心或可用区域上平衡任务。下面的例子说明了这一点:

$ docker service create \  --replicas 9 \  --name redis_2 \  --placement-pref 'spread=node.labels.datacenter' \
  redis:3.0.6

这使用带有扩展策略(当前唯一支持的策略)的--placement-pref来将任务均匀分布在数据中心节点标签的值上。 在这个例子中,我们假设每个节点都附有一个数据中心节点标签。 如果群体中的节点之间存在三个不同的标签值,则三分之一的任务将被放置在与每个值相关的节点上。 即使有更多的节点具有一个值而不是另一个值,情况也是如此。 例如,请考虑以下一组节点:

  • Three nodes with node.labels.datacenter=east

  • Two nodes with node.labels.datacenter=south

  • One node with node.labels.datacenter=west

由于我们正在传播数据中心标签的值,并且该服务有9个副本,因此每个数据中心将有3个副本。 有三个节点与east的值相关联,所以每个节点都会为这个值保留三个副本中的一个。 有两个值为南的节点,这个值的三个副本将在它们之间分配,一个接收两个副本,另一个接收一个副本。 最后,西部有一个节点,它可以将所有三个副本保留给西部。

如果某个类别中的节点(例如那些带有node.labels.datacenter=south的节点)由于约束或资源限制而无法处理其公平份额的任务,则可能会将其他任务分配给其他节点。

布局首选项支持引擎标签和节点标签。上面的示例使用节点标签,因为标签是以引用的node.labels.datacenter。要分布引擎标签的值,请使用--placement-pref spread=engine.labels.<labelname>

可以向服务添加多个展示位置偏好设置。这建立了偏好的层次结构,因此任务首先被划分为一个类别,然后进一步划分为其他类别。这可能有用的一个例子是在数据中心之间公平地分配任务,然后将每个数据中心内的任务分成多个机架。要添加多个展示位置首选项,请--placement-pref多次指定标志。顺序非常重要,布置首选项将按进行排定决策时的顺序应用。

以下示例使用多个展示位置首选项设置服务。任务首先在各个数据中心上传播,然后在机架上传播(如各个标签所示):

$ docker service create \  --replicas 9 \  --name redis_2 \  --placement-pref 'spread=node.labels.datacenter' \  --placement-pref 'spread=node.labels.rack' \
  redis:3.0.6

此图说明了展示位置偏好的工作原理

在使用Docker服务更新更新服务时,--placement-pref-add会在所有现有展示位置首选项之后附加新的展示位置首选项。 --placement-pref-rm删除与参数匹配的现有展示位置偏好设置。

配置服务的更新行为

在创建服务时,您可以指定滚动更新行为,以便在运行docker服务更新时swarm应该如何将更改应用于服务。 您也可以将这些标志指定为更新的一部分,作为docker服务更新的参数。

--update-delay标志配置更新服务任务或多组任务之间的时间延迟。您可以将时间描述T为秒数Ts,分钟数Tm或小时数的组合Th。因此10m30s表示延迟10分30秒。

默认情况下,调度程序一次更新1个任务。 您可以传递--update-parallelism标志来配置调度程序同时更新的最大服务任务数。

当对单个任务的更新返回RUNNING状态时,调度程序通过继续执行另一个任务来继续更新,直到更新所有任务。 如果在更新期间任何时候任务返回FAILED,则调度程序会暂停更新。 您可以使用docker service create或docker service update的--update-failure-action标志来控制行为。

在下面的示例服务中,调度程序一次最多应用2个副本。当更新的任务返回RUNNING或者FAILED,调度程序在停止下一个任务更新之前等待10秒钟:

$ docker service create \  --replicas 10 \  --name my_web \  --update-delay 10s \  --update-parallelism 2 \  --update-failure-action continue \
  alpine

--update-max-failure-ratio标志控制在更新之前更新的整个过程中可能失败的部分任务可能失败。 例如,使用--update-max-failure-ratio 0.1 --update-failure-action暂停,10%的任务更新失败后,更新将暂停。

如果任务未启动,或者在--update-monitor标志指定的监视时间段内停止运行,则认为单个任务更新失败。 --update-monitor的默认值为30秒,这意味着任务在其开始后的前30秒内失败,将计入服务更新失败阈值,并且在此之后的失败将不计入。

回滚到服务的先前版本

如果更新版本的服务没有按预期运行,可以使用docker service update的 - 回滚标志手动回滚到服务的先前版本。 这会将服务恢复到最新的Docker服务更新命令之前的配置。

其他选项可以与--rollback; 例如,--update-delay 0s在任务之间执行回滚而没有延迟:

$ docker service update \  --rollback \  --update-delay 0s
  my_web

在Docker 17.04及更高版本中,如果服务更新未能部署,您可以将服务配置为自动回滚。如果更新失败,请参阅自动回滚。

与新的自动回滚功能相关,在Docker 17.04及更高版本中,如果守护程序运行Docker 17.04或更高版本,手动回滚将在服务器端而不是客户端进行处理。这允许手动启动的回滚来遵守新的回滚参数。客户端是版本感知的,所以它仍然会使用旧的守护进程的方法。

最后,在Docker 17.04及更高版本中, - rollback不能与其他标志一起用于docker服务更新。

如果更新失败,则自动回滚

您可以通过以下方式来配置服务:如果对服务的更新导致重新部署失败,则该服务可以自动回滚到以前的配置。这有助于保护服务可用性。您可以在创建或更新服务时设置以下一个或多个标志。如果您未设置值,则使用默认值。

默认

描述

--rollback延迟

0

在回滚下一个任务之前回滚任务之后要等待的时间量。值为0意味着在部署第一个回滚任务后立即回滚第二个任务。

--rollback故障影响的行动

暂停

当任务无法回滚时,是暂停还是继续尝试回滚其他任务。

--rollback-MAX-故障率

0

在回滚期间容忍的故障率,指定为介于0和1之间的浮点数。例如,给定5个任务,故障率为0.2将允许一个任务无法回滚。值为0表示不允许失败,值为1表示允许任意数量的失败。

--rollback显示器

5S

每个任务回滚之后的持续时间以监视失败。如果任务在此时间段过去之前停止,则认为回滚失败。

--rollback并行性

1

并行回滚的最大任务数。默认情况下,一次回滚一个任务。值为0将导致所有任务并行回滚。

以下示例将配置redis服务,以在Docker服务更新未能部署时自动回滚。 两个任务可以并行回滚。 任务在回滚后监视20秒,以确保它们不会退出,并且最大失败率为20%是可以接受的。 默认值用于--rollback-delay和--rollback-failure-action。

$ docker service create --name=my_redis \                        --replicas=5 \                        --rollback-parallelism=2 \                        --rollback-monitor=20s \                        --rollback-max-failure-ratio=.2 \
                        redis:latest

提供服务访问卷或绑定挂载

为了获得最佳性能和可移植性,您应避免将重要数据直接写入容器的可写层,而应使用数据卷或绑定挂载。这一原则也适用于服务。

您可以为swarm中的服务创建两种类型的挂载,卷挂载或绑定挂载。 无论使用哪种类型的挂载,在创建服务时使用--mount标志进行配置,或在更新现有服务时使用--mount-add或--mount-rm标志进行配置。如果你没有指定类型,则默认值是数据卷

数据量

数据卷是在删除任务的容器后保持活动的存储。装入卷的首选方法是利用现有卷:

$ docker service create \  --mount src=<VOLUME-NAME>,dst=<CONTAINER-PATH> \  --name myservice \  <IMAGE>

有关如何创建卷的更多信息,请参阅volume createCLI参考。

以下方法在部署时在调度程序调度任务时创建卷,即在启动容器之前:

$ docker service create \  --mount type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=<DRIVER>,volume-opt=<KEY0>=<VALUE0>,volume-opt=<KEY1>=<VALUE1>  --name myservice \  <IMAGE>

重要说明:如果您的卷驱动程序接受逗号分隔列表作为选项,则必须从外部CSV分析程序中转义该值。 要转义卷-opt,请用双引号(“)括起来,并用单引号(')括住整个装入参数。

  例如,本地驱动程序接受挂载选项作为o参数中的逗号分隔列表。 此示例显示了转义列表的正确方法。

  $ docker service create \ --mount'type = volume,src = <VOLUME-NAME>,dst = <CONTAINER-PATH>,volume-driver = local,volume-opt = type = nfs,volume-opt = device = < nfs-server>:<nfs-path>,“volume-opt = o = addr = <nfs-address>,vers = 4,soft,timeo = 180,bg,tcp,rw”' - myservice \ <IMAGE>

绑定挂载

绑定挂载是调度程序为该任务部署容器的主机的文件系统路径。Docker将路径安装到容器中。文件系统路径必须在swarm为任务初始化容器之前存在。

以下示例显示了绑定挂载语法:

  • 要挂载一个读写绑定:$ docker service create \ --mount type = bind,src = <HOST-PATH>,dst = <CONTAINER-PATH> \ --name myservice \ <IMAGE>

  • 要装入一个只读绑定:$ docker service create \ --mount type = bind,src = <HOST-PATH>,dst = <CONTAINER-PATH>,只读\ --name myservice \ <IMAGE>

重要提示:绑定安装可能很有用,但它们也可能导致问题。在大多数情况下,建议您构建应用程序,以便不需要从主机安装路径。主要风险包括以下几点:

  • 如果将主机路径绑定到服务的容器中,则该路径必须存在于每个群集节点上。Docker群模式调度程序可以在满足资源可用性要求的任何机器上调度容器,并满足您指定的所有约束和位置偏好。

  • 如果Docker群模式调度程序变得不健康或无法访问,Docker群模式调度程序可能会随时重新安排正在运行的服务容器。

  • 主机绑定挂载是完全不可移植的。当您使用绑定挂载时,不能保证您的应用程序在开发过程中的运行方式与生产过程中的运行方式相同。

使用模板创建服务

您可以使用service createGo的文本/模板软件包提供的语法来为某些标志使用模板。

支持以下标志:

  • --hostname

  • --mount

  • --env

Go模板的有效占位符是:

占位符

描述

.Service.ID

服务ID

.Service.Name

服务名称

.Service.Labels

服务标签

.Node.ID

节点ID

.Task.Name

任务名称

.Task.Slot

任务槽

模板示例

本示例根据服务的名称和容器运行节点的ID来设置创建的容器的模板:

$ docker service create --name hosttempl \                        --hostname="{{.Node.ID}}-{{.Service.Name}}"\
                         busybox top

要查看使用模板的结果,请使用docker service psdocker inspect命令。

$ docker service ps va8ew30grofhjoychbr6iot8c

ID            NAME         IMAGE                                                                                   NODE          DESIRED STATE  CURRENT STATE               ERROR  PORTS
wo41w8hg8qan  hosttempl.1  busybox:latest@sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912  2e7a8a9c4da2  Running        Running about a minute ago
$ docker inspect --format="{{.Config.Hostname}}" hosttempl.1.wo41w8hg8qanxwjwsg4kxpprj

扩展内容

  • 群体管理指南

  • Docker引擎命令行参考

  • Swarm模式教程

上一篇:下一篇: