© Deepak Vohra 2017

Deepak Vohra, Docker Management Design Patterns, https://doi.org/10.1007/978-1-4842-2973-6_4

4. Docker Services

Deepak Vohra

(1)White Rock, British Columbia, Canada

A Docker container contains all the binaries and dependencies required to run an application. A user only needs to run a Docker container to start and access an application. The CoreOS Linux operating system has Docker installed and the Docker commands may be run without even installing Docker.

The Problem

A Docker container, by default, is started only on a single node. However, for production environments, where uptime and redundancy matters, you need to run your applications on multiple hosts.

When a Docker container is started using the docker run command, the container starts only on a single host, as illustrated in Figure 4-1. Software is usually not designed to run on a single host only. A MySQL database in a production environment, for example, may need to run across a cluster of hosts for redundancy and high availability. Applications that are designed for a single host should be able to scale up to multiple hosts as needed. But distributed Docker applications cannot run on a single Docker Engine.

A454123_1_En_4_Fig1_HTML.gif
Figure 4-1. Docker container on a single host

The Solution

Docker Swarm mode enables a Docker application to run across a distributed cluster of Docker Engines connected by an overlay network, as illustrated in Figure 4-2. A Docker service may be created with a specific number of replicas, with each replica potentially running on a different host in a cluster. A Swarm consists of one or more manager nodes with a single leader for Swarm management and orchestration. Worker nodes run the actual service tasks with the manager nodes being worker nodes by default. A Docker service may be started only from the leader node. Service replicas scheduled on the worker nodes, as a result, run a distributed application. Distributed applications provide several benefits, such as fault tolerance, failover, increased capacity, and load balancing, to list a few.

A454123_1_En_4_Fig2_HTML.gif
Figure 4-2. Docker service tasks and containers spread across the nodes

This chapter covers the following topics:

  • Setting the environment

  • The Docker service commands

  • Types of services

  • Creating a service

  • Listing the tasks of a service

  • Invoking a Hello World service task on the command line

  • Getting detailed information about a service

  • Invoking the Hello World service in a browser

  • Creating a service for a MySQL database

  • Scaling a service

  • Listing service tasks

  • Accessing a MySQL database in a Docker container

  • Updating a service

  • Updating the replicas

  • Updating the Docker image tag

  • Updating the placement constraints

  • Updating environment variables

  • Updating the Docker image

  • Updating the container labels

  • Updating resources settings

  • Removing a service

Setting the Environment

Create a Docker Swarm consisting of one manager and two worker nodes using the procedure discussed in Chapter 3. First, start three CoreOS instances—one for a Swarm manager and two for the Swarm workers. Obtain the public IP address of the Swarm manager, as shown in the EC2 console in Figure 4-3.

A454123_1_En_4_Fig3_HTML.jpg
Figure 4-3. EC2 instances for Swarm

SSH login to the Swarm manager instance with user as “docker”.

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

Three nodes should get listed in the Swarm with the docker node ls command—one manager node and two worker nodes.

∼ $ 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

A worker node may be promoted to a manager node using the docker node promote <node ip> command.

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

If you list the nodes again, two manager nodes should be listed. A manager node is identified by a value in the Manager Status column. One node has a Manager Status of Reachable and the other says 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

The manager node that is the Leader performs all the swarm management and orchestration. The manager node that is Reachable participates in the raft consensus quorum and is eligible for election as the new leader if the current leader node becomes unavailable.

Having multiple manager nodes adds fault tolerance to the Swarm, but one or two Swarm managers provide the same fault tolerance. If required, one or more of the worker nodes could also be promoted to a manager node to increase fault tolerance.

For connectivity to the Swarm instances, modify the inbound rules of the security groups associated with the Swarm manager and worker instances to allow all traffic. The inbound rules for the security group associated with a Swarm node are shown in Figure 4-4.

A454123_1_En_4_Fig4_HTML.jpg
Figure 4-4. Setting inbound rules on a security group to allow all traffic

The outbound rules for the security group associated with the Swarm manager are shown in Figure 4-5.

A454123_1_En_4_Fig5_HTML.jpg
Figure 4-5. Setting outbound rules on a security group to allow all traffic

The docker service Commands

The docker service commands are used to manage Docker services. The docker service command provides the sub-commands listed in Table 4-1.

Table 4-1. The docker service Sub-Commands

Command

Description

docker service create

Creates a new service.

docker service inspect

Displays detailed information on one or more services.

docker service logs

Fetches the logs of a service. The command was added in Docker 17.0.6.

docker service ls

Lists services.

docker service ps

Lists the tasks of one or more services.

docker service rm

Removes one or more services.

docker service scale

Scales one or multiple replicated services.

docker service update

Updates a service.

To run docker service commands, the following requirements must be met.

  • The Docker Swarm mode must be enabled

  • The docker service commands must be run from the Swarm manager node that is the Leader

The docker service commands are available only in Swarm mode and cannot be run outside the Swarm mode.

The docker service commands cannot be run from a worker node. Worker nodes cannot be used to view or modify Swarm cluster state.

Types of Services

Docker Swarm mode supports two types of services, also called service modes— replicated services and global services. Global services run one task only on every node in a Docker Swarm. Replicated services run as a configured number of tasks, which are also referred to as replicas, the default being one. The number of replicas may be specified when a new service is created and may be updated later. The default service type is a replicated service. A global service requires the --mode option to be set to global. Only replicated services may be scaled; global services cannot be scaled.

We start off by creating a replicated service. Later in the chapter, we also discuss creating a global service.

Creating a Service

The command syntax to create a Docker service is as follows.

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

Some of the supported options are listed in Table 4-2.

Table 4-2. Supported Options for Creating a Service

Option

Description

--constraint

Placement constraints.

--container-label

Container labels.

--env, -e

Sets environment variables.

--env-file

Reads in a file of environment variables. Option not added until Docker 1.13.

--host

Sets one or more custom host-to-IP mappings. Option not added until Docker 1.13. Format is host:ip.

--hostname

Container hostname. Option not added until Docker 1.13.

--label, -l

Service labels.

--limit-cpu

Limits CPUs. Default value is 0.000.

--limit-memory

Limits memory. Default value is 0.

--log-driver

Logging driver for service.

--log-opt

Logging driver options.

--mode

Service mode. Value may be replicated or global. Default is replicated.

--mount

Attaches a filesystem mount to the service.

--name

Service name.

--network

Network attachments. By default, the “ingress” overlay network is used.

--publish, -p

Publishes a port as a node port.

--read-only

Mounts the container’s root filesystem as read only. Option not added until Docker 17.03.

Default is false.

-- replicas

Number of tasks.

--reserve-cpu

Reserves CPUs. Default is 0.000.

--reserve-memory

Reserves memory. Default is 0.

--restart-condition

Restarts when condition is met. Value may be none, on-failure, or any.

--restart-delay

Delays between restart attempts (ns|us|ms|s|m|h).

--restart-max-attempts

Maximum number of restarts before giving up.

--tty, -t

Whether to allocate a pseudo-TTY. Option not added until Docker 1.13. Default is false.

--update-delay

Delays between updates (ns|us|ms|s|m|h). Default is 0s.

--update-failure-action

Action on update failure. Value may be pause or continue. Default value is pause.

--update-monitor

Duration after each task update to monitor for failure (ns|us|ms|s|m|h). Default is 0s.

--update-parallelism

Maximum number of tasks updated simultaneously. A value of 0 to updates all at once. Default value is 1.

--user, -u

Username or UID in format: <name|uid>[:<group|gid>].

--workdir, -w

Working directory inside the container.

As an example, create a service called hello-world with Docker image tutum/hello-world consisting of two replicas. Expose the service on port 8080 on the host. The docker service create command outputs a service ID if successful.

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

A service gets created .

Listing the Tasks of a Service

You can list the service tasks, also called replicas in the context of a replicated service, with the following command.

docker service ps hello-world

The two service tasks are listed.

∼ $ 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                       

The ID column lists the task ID. The task name is in the format servicename.n; hello-world.1 and hello-world.2 for the two replicas. The Docker image is also listed. The NODE column lists the private DNS of the node on which the task is scheduled. The DESIRED STATE is the state that is desired as defined in the service definition. The CURRENT STATE is the actual state of the task. At times, a task could be in a pending state because of lack of resource capacity in terms of CPU and memory.

A service task is a slot for running a Docker container. On each node on which a task is running, a Docker container should also be running. Docker containers may be listed with the docker ps command.

∼ $ 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

Invoking a Hello World Service Task on the Command Line

Invoke the hello-world service using curl at <hostname>:8080. The curl command output is the HTML markup for the service.

∼ $ 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>

Getting Detailed Information About a Service

To get detailed information about the hello-world service, run the docker service inspect command.

docker service inspect  hello-world

The detailed information includes the container specification, resources, restart policy, placement, mode, update config, ports (target port and published port), virtual IPs, and update status.

∼ $ 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"
                }
            ]
        }
    }
]

Invoking the Hello World Service in a Browser

The Hello World service may be invoked in a browser using the public DNS of a EC2 instance on which a Swarm node is hosted. A service replica does not have to be running on a node to invoke the service from the node. You obtain the public DNS of a manager node from the EC2 console, as shown in Figure 4-3. Invoke the Hello World service with <Public DNS>:<Published Port> URL. As the Hello World service is exposed or published on port 8080, the URL to invoke in a browser becomes <Public DNS>:8080. The service is invoked and the service output is displayed in the browser, as shown in Figure 4-6.

A454123_1_En_4_Fig6_HTML.jpg
Figure 4-6. Invoking a service in a browser

Similarly, you can obtain the public DNS of a EC2 instance on which a Swarm worker node is hosted, as shown in Figure 4-7.

A454123_1_En_4_Fig7_HTML.jpg
Figure 4-7. Obtaining the public DNS for a EC2 instance on which a Swarm worker node is hosted

Invoke the service using the PublicDNS:8080 URL in a browser, as shown in Figure 4-8.

A454123_1_En_4_Fig8_HTML.jpg
Figure 4-8. Invoking a service in a browser using public DNS for a EC2 instance on which a Swarm worker node is hosted

A manager node is also a worker node by default and service tasks also run on the manager node.

Creating a Service for a MySQL Database

Next, we create a service for a MySQL database. Using the mysql Docker image is different than using the tutum/hello-world Docker image in two respects.

  • The mysql Docker image has a mandatory environment variable called MYSQL_ROOT_PASSWORD.

  • The mysql Docker image is based on a Debian Linux and starts the MySQL database server in Docker container, while the tutum/hello-world image is based on Alpine Linux and starts Apache Server to run PHP applications.

Run the following docker service create command to create one replica of the MySQL database service. Supply a root password with the MYSQL_ROOT_PASSWORD environment variable. Include some other options for the restart condition, the restart max attempts, the update delay, and the update failure action. Remove any previously running Docker service called mysql with the docker service rm mysql command.

∼ $ 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

A service gets created for MySQL database and the service ID gets output.

∼ $ 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

List the services with the docker service ls command; the mysql service should be listed.

∼ $ 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

List the service tasks/replicas with the docker service ps mysql command. One task is running on the manager worker node.

∼ $ 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   

How service tasks are scheduled, including node selection based on node ranking, is discussed in Chapter 8, which covers scheduling.

Scaling a Service

Next, we scale the mysql service. Only replicated services can be scaled and the command syntax to scale one or more services is as follows.

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

To scale the mysql service to three tasks, run the following command.

docker service scale mysql=3

The mysql service gets scaled to three, as indicated by the command output.

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

Listing Service Tasks

The docker service ps command syntax to list service tasks is as follows.

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

The command supports the options listed in Table 4-3.

Table 4-3. Options for the docker service ps Command

Option

Description

--filter, -f

Filters output based on conditions provided. The following filters are supported:

id=<task id>

name=<task name>

node=<node id or name>

desired-state=(running | shutdown | accepted)

--no-resolve

Whether to map IDs to names. Default value is false.

--no-trunc

Whether to truncate output. Option not added until Docker 1.13. Default value is false.

--quiet, -q

Whether to only display task IDs. Option not added until Docker 1.13. Default value is false.

As an example, you can list only the service tasks that are running.

docker service ps –f desired-state=running mysql

Only the running tasks are listed.

∼ $ 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                          

All tasks are running; therefore, the effect of using the filter is not very apparent. But, in a subsequent example, you’ll list running service tasks when some tasks are not running.

Not all worker nodes are utilized for running service tasks if the number of nodes is more than the number of tasks, as when the hello-world and mysql services had fewer than three tasks running. A node could have more than one service task running if the number of replicas is more than the number of nodes in a Swarm. Scaling up to five replicas starts more than one replica on two of the nodes .

∼ $ 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                           

Only one mysql service replica is running on the manager node; therefore, only one Docker container for the mysql service is running on the manager node.

∼ $ 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

Scaling to 10 tasks starts multiple tasks on each of the Swarm nodes.

∼ $ 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                           

The number of Docker containers for the mysql service on the manager node increases to three for the three tasks running on the manager node .

∼ $ 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

Because you’ll learn more about Docker services with the MySQL database service example in later sections, and also for completeness, next we discuss using a Docker container for MySQL database to create a database table.

Accessing a MySQL Database in a Docker Container

Next, we access MySQL database in a Docker container . The docker ps command, when run on each instance, lists Docker containers for the mysql service on the instance. Start a bash shell for a Docker container with the docker exec –it <containerid> bash command. The root prompt gets displayed for the Docker container.

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

Start the MySQL CLI with the mysql command as user root. Specify the password when prompted; the password used to create the service was specified in the --env option to the docker service create command using environment variable MYSQL_ROOT_PASSWORD. The mysql> CLI command prompt is displayed.

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>

Set the database to use as mysql with the use mysql command.

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

Create a database table with the following SQL script.

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

The wlslog table is created.

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)

Add some data to the wlslog table with the following SQL commands run from the MySQL CLI.

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)

Run a SQL query to list the database table data.

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 the MySQL CLI and the bash shell using the exit command.

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

Updating a Service

A service may be updated subsequent to being created with the docker service update command, which has the following syntax:

docker service update [OPTIONS] SERVICE

Some of the supported options are listed in Table 4-4.

Table 4-4. Options for the docker service update Command

Option

Description

--args

Args for the command.

--constraint-add

Adds or updates a placement constraint.

--constraint-rm

Removes a placement constraint.

--container-label-add

Adds or updates a Docker container label.

--container-label-rm

Removes a container label by its key.

--env-add

Adds or updates an environment variable.

--env-rm

Removes an environment variable.

-- force

Whether to force an update even if no changes require it. Option added in Docker 1.13. Default is false.

--group-add

Adds an additional supplementary user group to the container. Option added in Docker 1.13.

--group-rm

Removes a previously added supplementary user group from the container. Option added in Docker 1.13.

--host-add

Adds or updates a custom host-to-IP mapping (host:ip). Option added in Docker 1.13.

--host-rm

Removes a custom host-to-IP mapping (host:ip). Option added in Docker 1.13.

--hostname

Updates the container hostname. Option added in Docker 1.13.

--image

Updates the service image tag.

--label-add

Adds or updates a service label.

--label-rm

Removes a label by its key.

--limit-cpu

Updates the limit CPUs. Default value is 0.000.

--limit-memory

Updates the limit memory. Default value is 0.

--log-driver

Updates logging driver for service.

--log-opt

Updates logging driver options.

--mount-add

Adds or updates a mount on a service.

--mount-rm

Removes a mount by its target path.

--publish-add

Adds or updates a published port.

--publish-rm

Removes a published port by its target port.

--read-only

Mounts the container’s root filesystem as read only. Option added in Docker 17.06. Default is false.

--replicas

Updates the number of tasks.

--reserve-cpu

Updates the reserve CPUs. Default is 0.000.

--reserve-memory

Updates the reserve memory. Default is 0.

--restart-condition

Updates the restart when condition is met (none, on-failure, or any).

--restart-delay

Updates the delay between restart attempts (ns|us|ms|s|m|h).

--restart-max-attempts

Updates the maximum number of restarts before giving up.

-- rollback

Whether to roll back to a previous specification. Option added in Docker 1.13. Default is false.

--tty, -t

Whether to allocate a pseudo-TTY. Option added in Docker 1.13. Default is false.

--update-delay

Updates delay between updates (ns|us|ms|s|m|h). Default is 0s.

--update-failure-action

Updates action on update failure (pause|continue). Default is pause.

--update-monitor

Duration after each task update to monitor for failure (ns|us|ms|s|m|h). Option added in Docker 1.13. Default 0s.

--update-parallelism

Updates the maximum number of tasks updated simultaneously (0 to update all at once). Default is 1.

--user, -u

Adds the username or UID (format: <name|uid>[:<group|gid>]).

--workdir, -w

Updates the working directory inside the container.

Next, we update some of the parameters of a deployed service.

Updating the Replicas

First, create a mysql service to update.

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

A service from Docker image mysql:5.6 is created and the service ID is output.

∼ $ 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

Update the number of replicas to five using the docker service update command. If the command is successful, the service name is output from the command.

∼ $ docker service update --replicas 5 mysql
mysql

Setting replicas to five does not just start four new tasks to make a total of five tasks. When a service is updated to change the number of replicas, all the service tasks are shut down and new tasks are started. Subsequently listing the service tasks lists the first task as being shut down and five new tasks as being started.

∼ $ 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                                          

Updating the Docker Image Tag

Starting with a MySQL database service called mysql for Docker image mysql:5.6, next we update the service to a different Docker image tag—the mysql:latest Docker image. Run the following command to update the Docker image; the service name is output to indicate that the update is successful.

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

You can list detailed information about the service with the docker service inspect command. The image listed in the ContainerSpec is mysql:latest. The PreviousSpec is also listed.

∼ $ 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",
]

The update does not get completed immediately even though the docker service update command does. While the service is being updated, the UpdateStatus for the service is listed with State set to "updating" and the Message of "update in progress".

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

When the update completes, the UpdateStatus State becomes "completed" and the Message becomes "update completed".

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

While the service is updating, the service tasks are shutting down and the new service tasks are starting. When the update is starting, some of the running tasks might be based on the previous image mysql:5.6 whereas others could be based on the new image 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)"     

The desired state of the tasks with image mysql:5.6 is set to Shutdown. Gradually, all the new service tasks based on the new image mysql:latest are started.

∼ $ 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)"     

Filtering the service tasks with the –f option was introduced earlier. To find which, if any, tasks are scheduled on a particular node, you run the docker service ps command with the filter set to the node. Filtered tasks, both Running and Shutdown, are then listed.

∼ $ 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)"     

Service tasks may also be filtered by desired state. To list only running tasks, set the desired-state filter to 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                       

Likewise, only the shutdown tasks are listed by setting the desired-state filter to 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)"     

Updating the Placement Constraints

The placement constraints may be added/removed with the --constraint-add and --constraint-rm options. We started with a Swarm consisting of three nodes—one manager and two worker nodes. We then promoted a worker node to a manager, resulting in a Swarm with two manager nodes and one worker node. .

Starting with service replicas running across the Swarm nodes, the replicas may be constrained to run on only worker nodes with the following command. The docker service update command outputs the service name if successful.

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

It may take a while (a few seconds or minutes) for the desired state of a service to be reconciled, during which time tasks could be running on manager nodes even though the node.role is set to worker or less than the required number of tasks could be running. When the update has completed (the update status may be found from the docker service inspect command), listing the running tasks for the mysql service indicates that the tasks are running only on the worker nodes.

∼ $ 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                           

As another example, service tasks for the mysql service may be constrained to run on only manager nodes. Starting with service tasks running on both manager and worker nodes and with no other constraints added, run the following command to place all tasks on the manager nodes.

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

The tasks are not shut down on worker nodes and started on manager nodes immediately and initially may continue to be running on worker nodes.

List the service replicas again after a while. You’ll see that all the tasks are listed as running on the manager nodes.

∼ $ 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                           

Updating Environment Variables

The --env-add and --env-rm options are used to add/remove environment variables to/from a service. The mysql service we created includes only one environment variable —the mandatory MYSQL_ROOT_PASSWORD variable. You can use the docker service update command to add the environment variables MYSQL_DATABASE, MYSQL_PASSWORD, and MYSQL_ALLOW_EMPTY_PASSWORD and to update MYSQL_ROOT_PASSWORD in the same command to an empty password. The command outputs the service name if successful.

∼ $ 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

When the update has completed, the docker service inspect command lists the environment variables added.

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

Updating the environment variables causes the containers to restart. So, simply adding environment variables doesn’t cause the new database to be created in the same container. A new container is started with the updated environment variables.

Updating the Docker Image

The Docker image may also be updated, not just the image tag. As an example, update the Docker image for a MySQL database service to use the postgres Docker image , which is for the PostgreSQL database. The command outputs the service name if the update is successful.

∼ $ docker service update --image postgres mysql
mysql

After the update has completed, showing the running service tasks lists new tasks for the postgres image. The service name stays the same and the Docker image is updated to 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                 

Updating the Docker image does not remove the environment variables associated with the mysql Docker image, which are still listed in the service detail .

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

The added environment variables for the MySQL database need to be removed, as the PostgreSQL database Docker image postgres does not use the same environment variables. Remove all the environment variables from the mysql service with the --env-rm option to the docker service update command. To remove only the env variable, the name needs to be specified, not the env value.

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

Updating the Container Labels

The --container-label-add and --container-label-rm options are used to update the Docker container labels for a service. To add a container label to the mysql service, run a docker service update command, which outputs the service name if successful.

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

On listing detailed information about the service, the added label is listed in the ContainerSpec labels.

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

The label added may be removed with the --container-label-rm option. To remove only the label, the key needs to be specified, not the label value.

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

Updating Resources Settings

The --limit-cpu, --limit-memory, --reserve-cpu, and --reserve-memory options of the docker service update command are used to update the resource settings for a service. As an example, update the resource limits and reserves. The command outputs the service name if successful.

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

The resources settings are updated. Service detail lists the updated resource settings in the Resources JSON object.

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

Removing a Service

The docker service rm command removes a service. If the output of the command is the service name, the service has been removed. All the associated service tasks and Docker containers also are removed.

∼ $ docker service rm mysql
mysql

Creating a Global Service

As discussed earlier, a service has two modes—replicated or global. The default mode is replicated. The mode may also be explicitly set to replicated with the --mode option of the docker service create command. The service mode cannot be updated after a service has been created, with the docker service update command for example. Create a replicated service for nginx using the --mode option.

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

A replicated mode service is created with the default number of replicas, which is 1. List the services with the docker service ls command. The nginx service is listed with one replica.

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

A global service runs one task on each node in a Swarm by default. A global service may be required at times such as for an agent (logging/monitoring) that needs to run on each node. A global service is used for logging in Chapter 11. Next, we create a nginx Docker image-based service that’s global. Remove the replicated service nginx with the docker service rm nginx command. A service name must be unique even if different services are of different modes. Next, create a global mode nginx service with the same command as for the replicated service, except that the --mode option is set to global instead of replicated.

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

A global mode service is created. The docker service ls command lists the service. The REPLICAS column for a global service does not list the number of replicas, as no replicas are created. Instead global is listed in the REPLICAS column.

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

A service task is created for a global service on each node in the Swarm on which a task can run. Scheduling constraints may be used with a global service to prevent running a task on each node. Scheduling is discussed in Chapter 8. Global services cannot be scaled.

Summary

This chapter introduced Docker services running on a Docker Swarm. A service consists of service tasks or replicas. A Docker Swarm supports two types of services—replicated services and global services. A replicated service has the assigned number of replicas and is scalable. A global service has a task on each node in a Swarm. The term “replica” is used in the context of a replicated service to refer to the service tasks that are run across the nodes in a Swarm. A replicated service could run a specified number of tasks for a service, which could imply running no tasks or running multiple tasks on a particular node. The term “replica” is generally not used in the context of a global service, which runs only one task on each node in the Swarm. Each task (replica) is associated with a Docker container. We started with a Hello World service and invoked the service with curl on the command line and in a browser. Subsequently, we discussed a service for a MySQL database. We started a bash shell for a MySQL service container and created a database table. Scaling, updating, and removing a service are some of the other service features this chapter covered. The chapter concluded by creating a global service. The next chapter covers the Docker Swarm scaling service in more detail.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.26.141