Cover image for Docker

Docker


Timeline

Timeline

2025-10-14

init

This article introduces the basics of Docker, discusses in detail its common commands, the union file system and loading principles of images, the persistence and sharing mechanisms of container data volumes, and summarizes the Dockerfile build process as well as the containerized installation and configuration of common software.

Common Docker Commands

Help and Startup Commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Start Docker
$ sudo systemctl start docker

# Stop Docker
$ sudo systemctl stop docker

# Restart Docker

# Enable on Boot
$ sudo systemctl enable docker

# View Docker Basic Information

# Docker Specific Command Help Documentation
$ sudo docker 具体命令 --help

Image Commands

1
2
3
4
5
6
# List Images on Local Host
$ docker images
# List All Local Images (Including Historical Images)
$ docker images -a
# Show only image ID
$ docker images -q
1
2
3
4
5
6
7
8
# Search for an image name
$ docker search 镜像名
# List only N images, default 25
$ docker search --limit N 镜像名
# Pull an image
$ docker pull 镜像名
# Pull an image and specify a version (tag)
$ docker pull 镜像名[:TAG]
1
2
3
4
5
6
7
8
# View space occupied by images/containers/volumes
$ docker system df
# Delete a single image
$ docker rmi 镜像名[:TAG]/镜像id
# Delete multiple images, -f force delete
$ docker rmi -f 镜像名1[:TAG]
# Delete all images
$ docker rmi -f $(docker images -qa)

Container commands

1
2
# Create and start a container
$ docker run [OPTIONS] IMAGE [COMMAND] [ARG..]

OPTIONS

  • –name=“new container name” Assign a name to the container
  • -d Run container in background and return container ID, i.e., start a daemon container
  • -i Run container in interactive mode, usually used with -t
  • -t Allocate a pseudo-TTY for the container, usually used with -i: i.e., start an interactive container
  • -P Random port mapping, capital P
  • -p hostPort:containerPort Specify port mapping, lowercase p, e.g., -p 8080:80
1
2
$ docker run -it ubuntu /bin/bash
# Here we want an interactive shell, so we use /bin/bash
1
2
# List all running containers
$ docker ps

OPTIONS

  • -a List all currently running containers + those that have run historically
  • -l Show the most recently created container
  • -n Show the last n created containers
  • -q Quiet mode, only display container IDs

Exit the container

  1. Enter the container with run, exit with exit,Container stops
1
$ exit
  1. Enter the container with run, exit with ctrl+p+q**, container does not stop**

Start a container that has stopped running*

1
$ docker start 容器ID或者容器名

Stop the container

1
$ docker stop 容器ID或容器名

Force stop container

1
$ docker kill 容器ID或容器名

Delete stopped containers

1
$ docker rm 容器ID或容器名

To delete a running container, add the -f parameter

Delete multiple container instances at once - danger!

1
2
3
$ docker rm -f $(docker ps -a -q)
# or
$ docker ps -a -q | xargs docker rm

Some important issues

Start a daemon container

1
$ docker run -d ubuntu

Problem: Then using docker ps -a, you find the container has exited. The reason is
For a Docker container to run in the background, it must have a foreground process, if the command run in the container is not one that stays suspended, it will automatically exit
Therefore, the -d parameter does not work for some images; use -it to run an interactive one

1
2
$ docker run -it redis:6.0.8
$ docker run -d redis:6.0.8

View logs of a container

1
$ docker logs 容器ID

View processes running inside a container

1
$ docker top 容器ID

View container details

1
$ docker inspect 容器id

Enter a running container and interact via command line

1
2
3
4
# Enter a running container and interact via command line
$ docker exec -it 容器ID /bin/bash
# Re-enter
$ docker attach 容器ID

Difference

  • attach directly enters the terminal of the container’s startup command without starting a new process; exiting with exit will directly cause the container to stop
  • exec opens a new terminal directly in the container and can start new processes; exiting with exit will not cause the container to stop

Therefore, generally we first use docker run -d and then use docker exec -it

Copy files from the container to the host

1
2
3
$ docker cp 容器ID:容器内路径 目的主机路径
# example
$ docker cp ddd1abihiin87:/tmp/a.txt ~/Desktop

Import and export containers

1
2
3
4
5
6
# export exports the container's content stream as a tar archive file
$ docker export 容器ID > abc.tar
# export creates a new filesystem from the content in the tar package and then imports it as an image
$ cat abc.tar | docker import - 镜像用户/镜像名:镜像版本号
# example
$ cat abc.tar | docker import - atguigu/ubuntu3.7

Docker images

What is an image

Docker images are actually composed of layers of filesystems, a hierarchical filesystem called UnionFS

UnionFS (Union File System)

Union File System (UnionFS) is a layered, lightweight, and high-performance filesystem that supports modifications to the filesystem as a commit to be stacked layer by layer, while also allowing different directories to be mounted under the same virtual filesystem (unite several directories into a single virtual filesystem). UnionFS is the foundation of Docker images. Images can be inherited through layering, and based on a base image (with no parent image), various specific application images can be created

Principle of Docker image loading

  • bootfs (boot file system) mainly contains the bootloader and kernel
    The bootloader mainly loads the kernel. When Linux starts, it loads the bootfs file system. At the bottom layer of a Docker image is the boot file system (bootfs). This layer is the same as our typical Linux/Unix file system, containing the boot loader and kernel. After the boot loading is complete, the entire kernel is in memory. At this point, the right to use memory is transferred from bootfs to the kernel, and the system also unmounts bootfs.
  • rootfs(root file system)
    Above bootfs, it contains the standard directories and files of a typical Linux system, such as /dev, /proc, /bin, /etc. rootfs refers to various operating system distributions, such as Ubuntu, CentOS, etc.

For a streamlined OS, rootfs can be very small, only needing to include the most basic commands, tools, and libraries, because the underlying layer directly uses the host’s kernel, and you only need to provide rootfs. It can be seen that for different Linux distributions, bootfs is basically the same, while rootfs differs. Therefore, different distributions can share bootfs.

One of the biggest advantages of image layering is resource sharing, making it easy to copy and migrate, all for reuse.

For example, if multiple images are built from the same base image, then the Docker Host only needs to save one copy of the base image on disk; at the same time, it only needs to load one copy of the base image in memory to serve all containers. Moreover, each layer of the image can be shared.

Key understanding

Docker’s image layers are all read-only, while the container layer is writable.
When a container starts, a new writable layer is loaded on top of the image. This layer is usually called the “container layer,” and everything below the container layer is called the image layer.

Publishing an image

docker commit submits a container copy to make it a new image

1
2
3
$  docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
# example
$ docker commit -m="vim add ok" -a="zhaohang" fcbfaingngi5 hnu/myubuntu:1.3

Afterwards, you can publish the image to Docker Hub or Alibaba Cloud (public repository), or to a private repository (similar to the relationship between GitLab and GitHub).

https://cn.bing.com/search?q=How to build a private Hub with Docker&qs=n&form=QBRE&sp=-1&lq=0&pq=How to build a private hub with Docker&sc=0-14&sk=&cvid=3005BB22809F420AA7DF1C31A5A20ABA&ghsh=0&ghacc=0&ghpl=

Docker container data volumes

If you encounter ‘cannot open directory: Permission denied’ when mounting a host directory in Docker, add the --privileged=true parameter after the mount directory.
With this parameter, the root inside the container has true root privileges; otherwise, the root inside the container is just an ordinary user with external permissions.

1
2
3
$ docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名/镜像ID
# example
$ docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry

By default, the repository is created in the /var/lib/registry directory of the container. It is recommended to use container volume mapping for easier debugging on the host machine.

A volume is a directory or file that exists in one or more containers, mounted by Docker to the container, but not part of the Union File System. Thus, it can bypass the Union File System to provide features for persistent storage or data sharing.

The design purpose of volumes isdata persistence, completely independent of the container’s lifecycle, so Docker does not delete the mounted data volume when the container is removed.

Note: Changes to container volumes are not included in image updates, and the lifecycle of a data volume continues until no container uses it.

Some examples

1
$ docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu

Read and write rule mapping addition instructions

Read-only permission, restricted inside the container instance, can only read but not write

1
$ docker run -it --privileged=true -v 宿主机绝对路径目录:容器内目录:ro 镜像名

Volume inheritance and sharing

1
2
$ docker run -it --privileged=true --volumes-from u1 --name u2 ubuntu
$ docker run -it --privileged=true --volumes-from=u1 --name=u2 ubuntu

If the host from volumes-from is gone, this host still mounts the volume of the parent host.

Introduction to Docker regular installation

Docker pulling certain software may cause some issues, such as MySQL character set configuration

mysql

1
2
3
4
5
$ docker pull mysql:8.0.20
$ docker run -d -p 3306:3306 --privileged=true -v /root/mysql/log:/var/log/mysql -v /root/mysql/data:/var/lib/mysql -v /root/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:8.0.20
$ cd /root/mysql/conf
$ touch my.cnf
$ vim my.cnf

MySQL configuration (it seems that version 8.0 and above may not require configuration)

1
2
3
4
5
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
1
2
3
4
$ docker restart mysql
$ docker exec -it mysql /bin/bash
$ mysql -uroot -p
$ SHOW VARIABLES LIKE 'character%'

Data persistence after mounting volumes

Redis cluster configuration, scaling up, scaling down, etc.

Redis has not been systematically studied yet

Dockerfile parsing

What is a Dockerfile

A Dockerfile is a text file used to build Docker images, consisting of a script made up of instructions and parameters required to build the image.

Basic knowledge of Dockerfile content

  1. Each reserved word instruction must be in uppercase and followed by at least one parameter
  2. Instructions are executed in order from top to bottom
  3. # indicates a comment
  4. Each instruction creates a new image layer and commits the image

General process of Docker executing a Dockerfile

  1. Docker runs a container from a base image
  2. Execute an instruction and make modifications to the container
  3. Perform an operation similar to docker commit to submit a new image layer
  4. Docker runs a new container based on the just-committed image
  5. Execute the next instruction in the Dockerfile until all instructions are completed

Dockerfile reserved words

FROM

Base image, which image the current image is based on; specify an existing image as a template; the first instruction must be FROM

MAINTAINER

Name and email address of the image maintainer

RUN

Commands to run during container build
Two formats: shell format and exec format
RUN is executed during docker build

EXPOSE

Port exposed by the current container

WORKDIR

Specify the working directory that the terminal defaults to when logging into the container after creation, a landing point

USER

Specify which user the image should execute as; if not specified, default is root

ENV

Environment variables set during the image build process

ADD

Copy files from the host directory into the image, automatically handle URLs and extract tar archives

COPY

Similar to ADD, copy files and directories into the image. Copy files/directories from the in the build context directory to the in the new image layer
COPY src dest
COPY [“src”,“dest”]

VOLUME

Container data volume, used for data preservation and persistence

The difference between volume and run -v, and when to use volume

When a container is running, write operations to the container’s storage layer should be minimized. For applications like databases that need to persist dynamic data, their database files should be stored in volumes. To prevent users from forgetting to mount the directory where dynamic files are saved as a volume at runtime, we can specify certain directories to be mounted as anonymous volumes in the Dockerfile. This way, if the user does not specify a mount at runtime, the application can still run normally without writing large amounts of data to the container’s storage layer.

So, in practice, is the VOLUME instruction in the Dockerfile the same as the -v parameter in docker run, binding a host directory to a container directory to achieve directory sharing?

Not exactly, in fact,the VOLUME instruction only declares a directory in the container as an anonymous volume, but it does not have the function of binding the anonymous volume to a specified host directory.

When we declare an anonymous volume with Volume in the Dockerfile used to build the image, and we run a container from this image, Docker will create a directory under a specified directory in its installation path to bind the container’s anonymous volume (this specified directory may vary with different Docker versions). My current directory is: /var/lib/docker/volumes/{container ID}.

Summary: Volume only specifies a directory to ensure the container runs normally even if the user forgets to specify the -v parameter at startup. For example, with MySQL, you cannot say that if the user does not specify -v at startup and then deletes the container, all MySQL data files are deleted—that would cause a major incident in production. Therefore, MySQL’s Dockerfile needs to configure volume, so that even if the user does not specify -v, the data files are not lost after the container is deleted. They can still be recovered.

Will the data files at the location specified by volume be deleted after the container is deleted?

Like the -v instruction, with volume, the files mapped on the host will not be deleted after the container is deleted.

What happens if -v and volume specify different locations?

The directory set by -v will take precedence. In fact, the purpose of the volume instruction is to prevent data loss when the user forgets to specify -v. So if the user specifies -v, the location specified by volume is naturally not needed.

In fact, for general Dockerfiles, unless the application is a database type that needs to persist data to disk, specifying volume is unnecessary. Specifying volume is only to prevent all data from being stored in the container when the user forgets to specify -v, which would result in all data being lost once the container is deleted.

**So why doesn’t the Dockerfile provide an instruction that can map a host directory to a container directory?**In fact, this design makes sense. If a host directory were specified in the Dockerfile, the Dockerfile would lose portability, since each person may need to map different directories. The best approach is to leave this decision to each person running the Dockerfile, which is why there is the run -v host_directory:container_directory instruction.

————————————————

Copyright notice: This article is an original work by CSDN blogger ‘Nuo Qian’, licensed under the CC 4.0 BY-SA copyright agreement. Please include the original source link and this notice when reprinting.

Original link: https://blog.csdn.net/qq32933432/article/details/120944205

1
2
3
4
$ docker volume create edc-nginx-vol // Create a custom container volume
$ docker volume ls // View all container volumes
$ docker volume inspect edc-nginx-vol // View details of a specified container volume
$ docker volume rm edc-nginx-vol // Delete a custom data volume

docker volume command

https://blog.csdn.net/lihongbao80/article/details/122812274

CMD

  • Specify what to do after the container starts
    Similar to RUN, it also has shell and exec formats
  • Multiple CMD instructions can exist in a Dockerfile, but only the last one takes effect. CMD will be replaced by parameters after docker run.

Example:
In the Dockerfile of Tomcat:

1
2
EXPOSE 8080
CMD ["catalina.sh","run"]

If we start Tomcat like this:

1
$ docker run -it -p 8080:8080 57800e5b1cbf /bin/bash

The /bin/bash parameter will override the CMD parameter, causing Tomcat to fail to start properly.

  • Difference from RUN
  • run is the command executed during docker build when building an image
  • cmd is the command executed during docker run when starting a container

ENTRYPOINT

also used to specify a command to run when a container starts, similar to the CMD command butENTRYPOINTwill not be overridden by the command after docker run, and these command-line arguments will be passed as parameters toENTRYPOINTthe program of the instruction

1
2
3
4
FROM nginx

ENTRYPOINT ["nginx","-c"] # fixed parameters
CMD ["/etc/nginx/nginx.conf"] # variable parameters

execute according to the Dockerfile

1
2
3
$ docker run nginx:test
# the actual derived command
$ nginx -c /etc/nginx/nginx.conf

actively pass parameters to run

1
2
3
$ docker run nginx:test -c /etc/nginx/new.conf
# actually derive the command
$ nginx -c /etc/nginx/new.conf

example

custom image centosjava8

requirement: Centos7 image with vim+ifconfig+jdk8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
FROM centos
MAINTAINER even629<asqwgo@163.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH
# install vim editor
RUN yum -y install vim
# Install the ifconfig command to view the network IP
RUN yum -y install net-tools
# Install Java 8 and its libraries
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
# ADD is a relative path jar; add jdk-8u171-linux-x64.tar.gz to the container. The installation package must be in the same location as the Dockerfile, and it will automatically extract
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
# Configure Java environment variables
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

EXPOSE 80
CMD echo $MYPATH
CMD echo "success-----------ok"
CMD /bin/bash
  • Build
1
$ docker build -t 新镜像名字:TAG .

(Note the dot at the end)

Dangling image

  • What is it
    Images with both repository name and tag as ; this may be caused by issues in Dockerfile writing or problems during Docker build
  • View all dangling images
1
$ docker image ls -f dangling=true
  • Delete dangling images
1
$ docker image prune

Docker microservice practice

  1. Create a common microservice module via IDEA
  2. Publish a microservice via Dockerfile and deploy it to a Docker container
1
2
3
4
5
6
7
8
9
10
11
FROM java:8
MAINTAINER even629<asqwgo@163.com>
# VOLUME specifies the temporary file directory as /tmp; it creates a temporary file under the host's /var/lib/docker directory and links it to the container's /tmp
VOLUME /tmp
# Add the jar package to the container and rename it to zzyy_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar zzyy_docker.jar
# Run the jar package
RUN bash -c 'touch /zzyy_docker.jar'
ENTRYPOINT ["java","-jar","/zzyy_docker.jar"]
#Expose port 6001 as a microservice
EXPOSE 6001
1
$ docker build -t zzyy_docker:1.6 .

Docker network

After starting Docker, a virtual bridge named docker0 is created

1
2
3
4
5
6
7
8
# View all Docker networks
$ docker network ls
# Create a network
$ docker network create aa_network
# Delete a network
$ docker network rm aa_network
# View network metadata
$ docker network inspect bridge

Three major network modes created by Docker by default:

  • bridge
  • host
  • none

Five major network modes of Docker:

  • bridge
    Assign and set IP, etc., for each container, and connect the container to a docker0
    Virtual bridge, this mode is the default
    Specify with --network bridge, default uses docker0
  • host
    The container will not virtualize its own network card or configure its own IP, etc., but will use the host’s IP and port
    Use --network host to specify
  • none
    The container has an independent network namespace, but no network settings are applied to it, such as assigning veth pairs, bridge connections, IP, etc.
    Use --network none to specify
  • container
    The newly created container does not create its own network card or configure its own IP, but shares the IP and port range with a specified container
    Use --network container:NAME or container ID

What can Docker networking do:

  • Interconnection and communication between containers, as well as port mapping
  • When container IP changes, network communication can be directly carried out via service name without being affected

The bridge docker0 creates a pair of peer virtual device interfaces, one called veth and the other eth0, matching as a pair

In host mode, use the same network segment as the host

1
2
3
4
# Warning
$ docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
# Correct
$ docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8

If using host mode, the port number will be based on the host port number, and will increment if duplicated

None mode:
In this mode, no network configuration is performed for the Docker container
That is to say, this Docker container has no network card, IP, routing information, etc., only an Io
We need to add a network card and configure IP, etc., for the Docker container ourselves

Container mode

1
2
3
$ docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8
# Running this command below will result in an error
$ docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8

It is equivalent to tomcat86 and tomcat85 sharing the same IP and the same port, causing a port conflict, because tomcat requires port 8080, so container mode is not suitable in this case

1
2
3
4
$ docker run -it --name=alpine1 alpine /bin/sh
$ docker run -it --network container:alpine1 --name=alpine2 alpine /bin/sh
# Enter the container and check the network
$ ip addr

If alpine1 is shut down, alpine2’s network will be gone

Custom network case

  1. Custom bridge network, the custom network uses the bridge network by default
1
$ docker network create zzyy_network
  1. Create a new custom network
1
2
3
4
5
6
7
8
9
10
$ docker run -d -p 8081:8080 --network zzyy_network --name tomcat81 billygoo/tomcat8-jdk
$ docker run -d -p 8082:8080 --network zzyy_network --name tomcat82 billygoo/tomcat8-jdk
$ docker exec -it tomcat81 bash
$ ip addr
$ ping tomcat82
$ exit
$ docker exec -it tomcat82 bash
$ ip addr
$ ping tomcat81
$ exit
  1. Create a new container and join the custom network created in the previous step
  2. Ping test each other

docker-compose

Compose is a tool software launched by Docker that can manage multiple Docker containers to form an application. It requires defining a configuration file in YAML format**docker-compose.yml,**Write the call relationships between multiple containers. Then, with just one command, you can start/stop these containers simultaneously.

Compose core concepts

  • One file

docker-compose.yml

  • Two elements
  1. Service

Individual application container instances, such as order microservice, inventory microservice, MySQL container, Nginx container, or Redis container

  1. Project

A complete business unit composed of a set of related application containers, defined in the docker-compose.yml file

Three steps for using Compose

  1. Write a Dockerfile to define each microservice application and build the corresponding image file
  2. Use docker-compose.yml to define a complete business unit and arrange each container service in the overall application
  3. Finally, execute the docker-compose up command to start and run the entire application, achieving one-click deployment

Common Compose commands

1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker-compose -h #View help
$ docker-compose up #Start all docker-compose services
$ docker-compose up -d #Start all docker-compose services and run in the background
$ docker-compose down #Stop and remove containers, networks, volumes, and images
$ docker-compose exec yml里面的服务id # Enter the container instance: docker-compose exec <service_id_in_docker-compose.yml> /bin/bash
$ docker-compose ps #Display all running containers orchestrated by current docker-compose
$ docker-compose top #Display container processes orchestrated by current docker-compose
$ docker-compose logs yml里面的服务id #View container output logs
$ docker-compose config #Check configuration
$ docker-compose config -q #Check configuration, output only if there are issues
$ docker-compose restart #Restart services
$ docker-comopse start #Start services
$ docker-compose stop #Stop services

Orchestrate microservices with compose

  1. Write docker-compose.yml

Set container name with container_name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
version: "3"

services:
microService:
image: zzyy_docker: 1.6
contianer_name: ms01
ports:
-"6001:6001"
volumes:
- /app/microService:/data
networks:
- atguigu_net
depends_on:
- redis
- mysql

redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- atguigu_net
command: redis-server /etc/redis/redis.conf

mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'db2021'
MYSQL_USER: 'zzyy'
MYSQL_PASSWORD: 'zzyy123'
ports:
- "3306:3306"
volumes:
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks:
- atguigu_net
command: --default-authentication-plugin=mysql_native_password #Resolve external inaccessibility

networks:
atguigu_net:

  1. Replace hardcoded IPs in application.yml with Docker service names

For example:

1
2
3
spring:
datasource:
url: jdbc:mysql://mysql:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
  1. Write a Dockerfile and place the packaged jar file in the same directory as the Dockerfile
1
$ docker build -t zzyy_docker:1.6 .
  1. Use docker-compose
1
2
3
4
# Check the syntax of the yaml file
$ docker-compose config -q
# Execute, -d means run in the background
$ docker-compose up -d

Check the network after running

1
$ docker network ls

Found that the network name has a prefix and suffix, and the service name also has a prefix and suffix

Docker lightweight visualization tool Portainer

https://www.portainer.io/

Docker container monitoring with CAdvisor+InfluxDB+Grafana (CIG)

Native command

1
$ docker stats

You can easily see the CPU, memory, and network traffic data of all containers on the current host, but docker stats results only cover all containers on the current host, the data is real-time, has no storage, and lacks health indicator threshold alerting

CAdvisor for monitoring and collection + InfluxDB for data storage + Grafana for chart display

  1. CAdvisor

CAdvisor is a container resource monitoring tool that monitors container memory, CPU, network I/O, disk I/O, etc., and provides a web page to view the real-time status of containers. CAdvisor stores data for only 2 minutes by default and is limited to a single physical machine. However, CAdvisor offers many data integration interfaces, supporting InfluxDB, Redis, Kafka, etc., and can be configured to send monitoring data to these databases for storage

CAdvisor has two main functions:

  • Display monitoring data at both the host and container levels
  • Display historical change data
  1. InfluxDB

InfluxDB is an open-source distributed time-series, event, and metrics database written in Go, requiring no external dependencies. CAdivisor itself provides an integration method for InfluxDB; simply specify the configuration when starting the container.

Main features of InfluxDB:

  • Time-series based, supporting event-related functions (such as max, min, sum, etc.)
  • Measurability: You can perform calculations on large amounts of data in real-time.
  • Event-based: It supports arbitrary event data.
  1. Granfana

Grafana is an open-source data analysis and visualization platform, supporting multiple data source configurations (supported data sources include InfluxDB, MySQL, Elasticsearch, OpenTSDB, Graphite, etc.) and rich plugins and template features, with support for chart permission control and alerts.

Main features of Grafana:

  • Flexible and rich graphical options
  • Can mix multiple styles
  • Supports day and night modes
  • Multiple data sources

Three-piece container orchestration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
version: '3.1'



volumes:

grafana_data: {}



services:

influxdb:

image: tutum/influxdb:0.9

restart: always

environment:

- PRE_CREATE_DB=cadvisor

ports:

- "8083:8083"

- "8086:8086"

volumes:

- ./data/influxdb:/data



cadvisor:

image: google/cadvisor

links:

- influxdb:influxsrv

command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086

restart: always

ports:

- "8080:8080"

volumes:

- /:/rootfs:ro

- /var/run:/var/run:rw

- /sys:/sys:ro

- /var/lib/docker/:/var/lib/docker:ro



grafana:

user: "104"

image: grafana/grafana

user: "104"

restart: always

links:

- influxdb:influxsrv

ports:

- "3000:3000"

volumes:

- grafana_data:/var/lib/grafana

environment:

- HTTP_USER=admin

- HTTP_PASS=admin

- INFLUXDB_HOST=influxsrv

- INFLUXDB_PORT=8086

- INFLUXDB_NAME=cadvisor

- INFLUXDB_USER=root

- INFLUXDB_PASS=root