Docker Engine Starting from version 1.12.0, Docker Swarm is integrated natively. The operation of the cluster can be directly controlled by the docker service command, which is very convenient and the operation process is greatly simplified. Docker Swarm For the average developer, the biggest advantage lies in the native support of the load balancing mechanism, which can effectively scale the service up. With the help of the Raft Consensus algorithm, the robustness of the system is very good and can be tolerated as much as possible (n -1)/2 fault nodes.
Build Swarm Cluster
Install the latest docker
curl -sSL https://get.docker.com/ | sh
firewall-cmd --permanent --zone=trusted --add-port=2377/tcp && \ firewall-cmd --permanent --zone=trusted --add-port=7946/tcp && \ firewall-cmd --permanent --zone=trusted --add-port=7946/udp && \ firewall-cmd --permanent --zone=trusted --add-port=4789/udp && \ firewall-cmd --reload
Create a management node
$ docker swarm init --advertise-addr 192.168.99.100 Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 To add a manager to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-61ztec5kyafptydic6jfc1i33t37flcl4nuipzcusor96k7kby-5vy9t8u35tuqm7vh67lrz9xp6 \ 192.168.99.100:2377
When the management node is created, we can view the node creation status through the docker info and docker node ls commands.
$ docker info Containers: 2 Running: 0 Paused: 0 Stopped: 2 ...snip... Swarm: active NodeID: dxn1zf6l61qsb1josjja83ngz Is Manager: true Managers: 1 Nodes: 1 ...snip...
$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader ??worker??
According to the previous command line output result prompt, two workers are now added to the cluster. Remember to replace the corresponding token and IP address with the actual value during execution.
$ docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 This node joined a swarm as a worker. $ docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 This node joined a swarm as a worker. #????????hostname `hoshnamectl set-hostname worker2`
Now we can see all the nodes in the cluster on the manager1 node
$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 3g1y59jwfg7cf99w4lt0f662 worker2 Ready Active j68exjopxe7wfl6yuxml7a7j worker1 Ready Active dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader
So far, the cluster environment has been set up.
Deployment Test Service
We deployed nginx as an example to test the Swarm cluster we built.
$ docker service create --replicas 3 --publish 8080:80 --name helloworld nginx
The –replicas parameter here is used to indicate how many instances nginx needs to deploy because there are three physical machines. If replicas is set to 3, swarm will deploy one instance on each of the three machines. If you want to rescale the number of instances, you can use the following command.
docker service scale helloworld=5
We can check the deployment of nginx through a series of commands, such as
$ docker service inspect --pretty helloworld $ docker service ps helloworld
Deleting a service is also very simple and you can simply execute rm.
$ docker service rm helloworld
Let’s look at a docker-compose.yml file first. It doesn’t matter what this is doing. It’s just a format that is easy to explain:
version: '2' services: web: image: dockercloud/hello-world ports: - 8080 networks: - front-tier - back-tier redis: image: redis links: - web networks: - back-tier lb: image: dockercloud/haproxy ports: - 80:80 links: - web networks: - front-tier - back-tier volumes: - run/docker.sock: run/docker.sock networks: front-tier: driver: bridge back-tier: driver: bridge
It can be seen that a standard configuration file should contain three major parts: version, services, and networks. The most critical part is services and networks. Let’s first look at the rules for writing services.
services: web: image: hello-world
The second-level tag under the services tab is web. The name is customized by the user. It is the service name.
Image is the image name or image ID of the specified service. If the image does not exist locally, Compose will try to pull the image.
For example, the following formats are all possible:
image: redis image: Ubuntu:14.04 image: tutum/influxdb image: example-registry.com:4000/postgresql image: a4bc65fd
The service can be based on a specified image, or it can be based on a Dockerfile. When you use up to start a build task, this build tag is the build, which specifies the path to the Dockerfile folder. Compose will use it to automatically build this image and then use this image to start the service container.
build: to dir
It can also be a relative path, and the Dockerfile can be read as long as the context is determined.
Set the context root and specify the Dockerfile as the target.
build: context: ../ dockerfile: path Dockerfile
Note that build is a directory, if you want to specify the Dockerfile file you need to use the dockerfile tag in the child tag of the build tag, as in the above example.
If you specify both the image and build tags, Compose will build the image and name the image after the image.
build: ./dir image: webapp:tag
Since you can define the build task in docker-compose.yml, you must have the arg tag. Just like the ARG directive in the Dockerfile, it can specify the environment variables during the build process, but cancel after the build succeeds, at docker-compose. The yml file also supports this notation:
build: context: . args: buildno: 1 password: secret
The following writing is also supported. In general, the following wording is more suitable for reading.
build: context: . args: - buildno=1 - password=secret
Unlike ENV, ARG allows null values. E.g:
args: - buildno - password
This way the build process can assign values ??to them.
Note: YAML Boolean values ??(true, false, yes, no, on, off) must be quoted (either single or double quotes), otherwise they will be parsed as strings.
Use command to override the default command executed after the container starts.
command: bundle exec thin -p 3000
It can also be written in a format similar to Dockerfile:
command: [bundle, exec, thin, -p, 3000]
As mentioned earlier, Compose’s container name format is: <project name> <service name> <serial number>
Although you can customize the project name, service name, but if you want to fully control the container’s name, you can use this tag to specify:
The name of this container is specified as app.
In the use of Compose, the biggest advantage is to use less to start the command, but the order of the general project container startup is required, if you start the container directly from top to bottom, it will inevitably fail because of container dependency problems.
For example, if the application container is started when the database container is not started, the application container will exit because it cannot find the database. In order to avoid this situation, we need to add a label, namely depends_on, which resolves the container’s dependency and startup sequence. The problem.
For example, the following container will start two services redis and db, and finally start the web service:
version: '2' services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres
Note that when launching a web service using the docker-compose up web method by default, both the redis and db services are started because the dependencies are defined in the configuration file.
The same as the –dns parameter, the format is as follows:
can also be a list:
dns: - 220.127.116.11 - 18.104.22.168
In addition, the configuration of dns_search is similar:
dns_search: example.com dns_search: - dc1.example.com - dc2.example.com
Mounting a temporary directory inside the container has the same effect as the run parameter:
tmpfs: /run tmpfs: - /run - /tmp
In the Dockerfile there is an instruction called the ENTRYPOINT directive that specifies the access point, and Chapter 4 has the difference compared to the CMD.
The access point can be defined in docker-compose.yml, overriding the definition in the Dockerfile:
Entrypoint: The /code/entrypoint.sh
format is similar to Docker, but can also be written like this:
entrypoint: - php - -d - zend_extension=-20100525/xdebug.so local php no-debug-non-zts - -d - memory_limit=-1 - vendorphpunit
Remember the .env file mentioned earlier. This file can set Compose variables. In docker-compose.yml, you can define a file that stores variables.
If the configuration file is specified with docker-compose -f FILE, the path to the env_file uses the configuration file path.
If there is a conflict between the variable name and the environment instruction, the latter will prevail. The format is as follows:
or set multiple according to docker-compose.yml:
env_file: - ./common.env - . web.env - secrets.env
Note that the environment variable mentioned here is for the host’s Compose. If there is a build operation in the configuration file, these variables will not enter the build process. If you want to use variables in your build, it is still preferred. The arg tag.
Unlike the above env_file tag, which is somewhat similar to arg, the effect of this tag is to set the mirror variable, which can save the variable to the image, which means that the starting container will also contain these variable settings. This is the same as arg. The biggest difference.
General arg tag variables are used only during the build process. The ENV instruction in environment and Dockerfile will keep the variables in the image and container, similar to the effect of docker run -e.
environment: RACK_ENV: development SHOW: 'true' SESSION_SECRET: environment: - RACK_ENV=development - SHOW=true - SESSION_SECRET
- The expose
This tag is the same as the EXPOSE directive in the Dockerfile. It is used to specify the exposed port, but only as a reference. In fact, the port mapping of docker-compose.yml still has a tag like ports.
expose: - "3000" - "8000"
In the Docker process, we have a lot of containers that are started using docker run alone. To make Compose connect to containers that are not defined in docker-compose.yml, we need a special label, external_links, which allows the Compose project to work. The containers inside are connected to containers outside of the project configuration (provided that at least one container in the external container is connected to the same network as the service in the project).
The format is as follows:
external_links: - redis_1 - project_db_1:mysql - project_db_1:postgresql
Add the host name tag, which is to add some records to the /etc/hosts file, similar to the –add-host of the Docker client:
extra_hosts: - "somehost:22.214.171.124" - "otherhost:126.96.36.199"
View the internal hosts of the container after startup:
188.8.131.52 somehost 184.108.40.206 otherhost
Add metadata to the container, and the meaning of the Dockerfile’s LABEL directive is as follows:
labels: com.example.description: "Accounting webapp" com.example.department: "Finance" com.example.label-with-empty-value: "" labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" - "com.example.label-with-empty-value"
Remember the above depends_on, that the tag solves the startup sequence problem, this tag resolves the container connection problem, and is the same as the docker client’s –link, which connects to containers in other services.
The format is as follows:
links: - db - db:database - redis
The alias used will be automatically created in /etc/hosts in the service container. E.g:
220.127.116.11 db 18.104.22.168 database 22.214.171.124 redis
The corresponding environment variable will also be created.
This tag is used to configure the log service. The format is as follows:
logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123"
The default driver is json-file. Only json-file and journald can display logs through docker-compose logs. There are other ways to view logs, but Compose does not support them. For optional values, use options.
For more information on this you can read the official documentation:
sets the PID mode to host PID mode, sharing the process namespace with the host system. Containers using this tag will be able to access and manipulate the namespaces of other containers and hosts.
Map the port’s tag.
Using the HOST:CONTAINER format or just specifying the port of the container, the host randomly maps ports.
ports: - "3000" - "8000:8000" - "49100:22" - "127.0.0.1:8001:8001"
Note: When using HOST:CONTAINER format to map ports, if you use a container port less than 60 you may get a wrong result, because YAML will parse xx:yy this number format is hexadecimal. Therefore, it is recommended to use a string format.
Override the default label for each container. Simply put, it is the label for managing all services. For example, set the user tag for all services to USER.
security_opt: - label:user:USER - label:role:ROLE
Set another signal to stop the container. The SIGTERM stop container is used by default. Set another signal to use the stop_signal tag.
Mount a directory or an existing data volume container, either directly using the format [HOST:CONTAINER], or using the format [HOST:CONTAINER:ro], which is read-only for containers This can effectively protect the host’s file system.
The Compose data volume designation path can be a relative path, using . or .. to specify the relative directory.
The format of the data volume can be in the following forms:
// Just specify a path, Docker will automatically create a data volume (this path is inside the container).
// Mount data volume using absolute path
// The relative path centered on the Compose configuration file is mounted as a data volume to the container.
// Use the relative path of the user (the directory represented by ~/ is /home/<user directory>/ or /root/).
// An existing named data volume.
If you do not use the host’s path, you can specify a volume_driver.
Mount data volumes from other containers or services. Optional parameters are: ro or :rw. The former indicates that the container is read-only and the latter indicates that the container is readable and writeable to the data volume. It is readable and writable by default.
volumes_from: - service_name - service_name:ro - container:container_name - container:container_name:rw
- Cap_add, cap_drop
Add or remove the container’s kernel features. Detailed information is explained in the previous section of the container and will not be repeated here.
cap_add: - ALL cap_drop: - NET_ADMIN - SYS_ADMIN
Specifies the parent cgroup of a container.
List of device mappings. Similar to the –device parameter of the Docker client.
devices: - "/dev/ttyUSB0:/dev/ttyUSB0"
This tag can be used to extend another service. Extended content can be from the current file, or from other files, and the same service. Latecomers can choose to overwrite the original configuration.
Extends : file: common.yml
users can use this tag anywhere, as long as the tag content contains both file and service values. The value of file can be a relative or absolute path. If you do not specify the value of file, Compose will read the current YML file information.
More details of the operation are described later in subsection 12.3.4.
The network mode is similar to the –net parameter of the Docker client, except that there is a relatively more service:[service name] format.
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]"
You can specify the network that uses the service or container.
Join the specified network in the following format:
services: some-service: networks: - some-network - other-network
There is also a special child tag aliases for this tag. This is a tag to set the service alias, for example:
services: some-service: networks: some-network: aliases: - alias1 - alias3 other-network: aliases: - alias2
The same service can have different aliases on different networks.
There are also these tags: cpu_shares, cpu_quota, cpuset, domainname, hostname, ipc, mac_address, mem_limit, memswap_limit, privileged, read_only, restart, shm_size, stdin_open, tty, user, working_dir
These are all single-valued tags, similar to Use docker run effect.
cpu_shares: 73 cpu_quota: 50000 cpuset: 0,1 user: postgresql working_dir: /code domainname: foo.com hostname: foo ipc: host mac_address: 02:42:ac:11:65:43 mem_limit: 1000000000 memswap_limit: 2000000000 privileged: true restart: always read_only: true shm_size: 64M stdin_open: true tty: true