This time I share a Docker learning tutorial, which is a bit long~
Table of contents
1 Introduction to containers
1.1 What is a Linux container
1.2 Isn’t a container just virtualization?
1.3 A brief history of container development
2 What is Docker?
2.1 How does Docker work?
2.2 Is Docker technology the same as traditional Linux containers?
2.3 Goals of docker
3 Install Docker
3.1 Docker basic command operations
3.2 Start the first container
3.3 Docker image life cycle
4 Docker image related operations
4.1 Search the official warehouse image
4.2 Get the image
4.3 Export the image
4.4 Delete the image
4.5 Import the image
4.6 View the image details Information
5 Daily management of containers
5.1 Starting/stopping
containers 5.2 How to enter the container
5.3 Delete all containers
5.4 Port mapping at startup
6 Management of Docker data volumes
6.1 Creating volumes when mounting
6.2 Mounting after creating volumes
6.3 Manually saving the container as Image
7 Dockerfile automatically builds docker image
7.1 Dockerfile instruction set
7.2 Create a Dockerfile
7.3 Use Dcokerfile to install kodexplorer
8 Image layering in Docker
8.1 Why Docker images are layered
8.2 Writable container layer
8.3 Details of the container layer
9 Use docker to run zabbix-server
9.1 Interconnection between containers
9.2 Start zabbix container
9.3 About zabbix API
10 docker warehouse (registry)
10.1 Create a normal warehouse
10.2 Warehouse with basic certification
11 docker-compose orchestration tool
11.1 Install docker-compose
11.2 Orchestrate startup image
11.3 haproxy proxy backend docker container
11.4 Install socat Directly operate socket to control haproxy
12 Restart docker Solution to exit all services and containers
12.1 Specify automatic restart at startup
12.2 Modify docker default configuration file
13 Docker network type
13.1 Docker network type
13.2 Do not configure network functions for containers
13.3 Share network configuration with other containers (Container)
13.4 Use hosting Host Network
13.5 View Network List
13.6 Use PIPEWORK to configure independent IP for docker container
13.7 Docker cross-host communication macvlan
14 docker enterprise mirror warehouse harbor
14.1 Suggestions for using containers
14.2 Monitoring of Docker containers
15 References
1 Introduction to containers
1.1 What is a Linux container
A Linux container is a series of processes that are isolated from the rest of the system, run from another image, and have all the files needed to support the process provided by that image. The image provided by the container contains all the dependencies of the application, making it portable and consistent from development to testing to production.
In more detail, imagine that you are developing an application. You are using a laptop and your development environment has a specific configuration. Other developers may have slightly different environment configurations. The application you are developing depends on your current configuration and also depends on certain files. At the same time, your enterprise also has standardized test and production environments with their own configuration and set of supporting files. You want to simulate as many of these environments locally as possible without incurring the overhead of recreating a server environment.
So, how do you ensure that your application can run and pass quality checks in these environments, and deploy without headaches, re-coding, and bug fixes? The answer is to use containers. Containers ensure that your applications have the necessary configuration and files to run smoothly from development to testing to production without any issues. This way you can avoid crises and make everyone happy.
While this is a simplified example, there are many ways in which Linux containers can be used to solve difficult problems where a high level of portability, configurability, and isolation is required. Whether the infrastructure is on-premises, in the cloud, or a mix of both, containers can meet your needs.
1.2 Aren’t containers just virtualization?
Yes, but not exactly. Let’s think about it in a simple way:
Virtualization allows many operating systems to run simultaneously on a single system.
Containers can share the same operating system kernel, isolating application processes from the rest of the system.
Figure - Comparison between ordinary virtualization technology and Docker
what does that mean? First, running multiple operating systems on a single hypervisor for virtualization does not achieve the same lightweight effect as using containers. In fact, when you have only limited resources with limited capacity, you need lightweight applications that can be deployed densely. Linux containers run from a single operating system that is shared among all containers, so applications and services can stay lightweight and run quickly in parallel.
1.3 A brief history of container development
The concept of what we now call container technology first appeared in 2000 as FreeBSD jails, a technology that partitions a FreeBSD system into multiple subsystems (also called jails). Jails are developed as secure environments that system administrators can share with multiple users within or outside the enterprise.
The purpose of Jail is to allow processes to be created in a modified chroot environment - where access to the file system, network and users are virtualized - without breaking away and affecting the entire system. Despite Jail's implementation limitations, eventually people found a way out of this isolation environment.
But the concept is very attractive.
In 2001, the implementation of isolated environments entered the Linux field through Jacques Gélinas's VServer project. As Gélinas puts it, the purpose of this work is to "run multiple common Linux servers [sic] in a highly independent and secure single environment." After completing this foundational work on multiple controlled user spaces in Linux Later, Linux containers began to gradually take shape and eventually developed into what they are today.
2 What is Docker?
The term "Docker" refers to a variety of things, including open source community projects, the tools used by open source projects, the company Docker Inc. that leads support for such projects, and the tools officially supported by that company. It does get a little confusing when a technology product and a company share the same name.
Let’s briefly explain:
“Docker” in IT software refers to containerization technology that supports the creation and use of Linux containers.
The open source Docker community is dedicated to improving this type of technology and making it freely available to all users for their benefit.
Docker Inc. started with the Docker community product. It is mainly responsible for improving the security of the community version and sharing the improved version with the broader technology community. In addition, it specializes in perfecting and securely solidifying these technology products to serve enterprise customers.
With Docker, you can use containers as lightweight, modular virtual machines. You also get the flexibility to efficiently create, deploy, replicate, and migrate containers from one environment to another.
2.1 How does Docker work?
Docker technology uses the Linux kernel and kernel features such as Cgroups and namespaces to separate processes so that they can run independently of each other. This independence is exactly the purpose of using containers; it can run multiple processes and multiple applications independently, more fully utilizing the role of the infrastructure, while maintaining the security of each independent system.
Container tools, including Docker, provide image-based deployment models. This makes it easy to share an application or service group across multiple environments with its dependent programs. Docker can also automate the deployment of applications within this container environment (or combine multiple processes to build a single application).
In addition, because these tools are built on Linux containers, Docker is both easy to use and unique in that it provides users with unprecedented high-level application access, rapid deployment, and version control and distribution capabilities.
2.2 Is Docker technology the same as traditional Linux containers?
no. Docker technology was originally built on LXC technology (which most people associate with "traditional" Linux containers), but it has since gradually moved away from its reliance on this technology.
LXC is useful as a lightweight virtualization feature, but it doesn't provide a great developer or user experience. In addition to running containers, Docker technology also provides many other capabilities, including simplifying the process of building containers, transporting images, and controlling image versions.
Traditional Linux containers use the init system to manage various processes. This means that all applications run as a whole. In contrast, Docker technology encourages applications to run their own processes independently and provides the tools to do so. This refined operating model has its own advantages.
2.3 Goals of docker
The main goal of docker is "Build, Ship and Run any App, Anywhere", build, ship and run anywhere
Build : Make a docker image
Shipping : docker pull
Run : start a container
Each container has its own file system rootfs.
3 Install Docker
Environmental Statement
# 需要两台几点进行安装
[root@docker01 ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[root@docker01 ~]# uname -r
3.10.0-327.el7.x86_64
[root@docker01 ~]# hostname -I
10.0.0.100172.16.1.100
[root@docker02 ~]# hostname -I
10.0.0.101172.16.1.101
Operate on both nodes
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
yum install docker-ce -y
Modify the docker01 configuration:
# 修改启动文件,监听远程端口
vim /usr/lib/systemd/system/docker.service
ExecStart\=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://10.0.0.100:2375
systemctl daemon\-reload
systemctl enable docker.service
systemctl restart docker.service
# ps -ef检查进行,是否启动
Tested on docker02
[root@docker02 ~]# docker -H 10.0.0.100 info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.12.0-ce
Storage Driver: devicemapper
···
3.1 Docker basic command operations
View docker related information
[root@docker01 ~]# docker version
Client:
Version: 17.12.0-ce
API version: 1.35
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 2720:10:142017
OS/Arch: linux/amd64
Server:
Engine:
Version: 17.12.0-ce
API version: 1.35 (minimum version 1.12)
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 2720:12:462017
OS/Arch: linux/amd64
Experimental: false
Configure docker image acceleration
vi /etc/docker/daemon.json
{ "registry-mirrors": ["https://registry.docker-cn.com"]
}
3.2 Start the first container
[root@docker01 ~]# docker run -d -p 80:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
e7bb522d92ff: Pull complete
6edc05228666: Pull complete
cd866a17e81f: Pull complete
Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d
Status: Downloaded newer image for nginx:latest
8d8f81da12b5c10af6ba1a5d07f4abc041cb95b01f3d632c3d638922800b0b4d
# 容器启动后,在浏览器进行访问测试
Parameter Description
parameter |
illustrate |
run |
Create and run a container |
-d |
Put in background |
-p |
Port Mapping |
nginx |
Image name |
3.3 Docker image life cycle
4 Docker image related operations
4.1 Search the official warehouse image
[root@docker01 ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 3992 [OK]
ansible/centos7-ansible Ansible on Centos7 105
List description
parameter |
illustrate |
NAME |
Image name |
DESCRIPTION |
Mirror description |
STARS |
Number of likes |
OFFICIAL |
is it official |
AUTOMATED |
Whether it is built automatically |
4.2 Get the image
Pull the image based on the image name
[root@docker01 ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
af4b0a2388c6: Downloading 34.65MB/73.67MB
View the current host image list
[root@docker01 ~]# docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest ff426288ea90 3 weeks ago 207MB
nginx latest 3f8a4339aadd 5 weeks ago 108MB
How to pull third-party images
docker pull index.tenxcloud.com/tenxcloud/httpd
4.3 Export image
[root@docker01 ~]# docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest ff426288ea90 3 weeks ago 207MB
nginx latest 3f8a4339aadd 5 weeks ago 108MB
# 导出
[root@docker01 ~]# docker image save centos > docker-centos.tar.gz
4.4 Delete image
[root@docker01 ~]# docker image rm centos:latest
[root@docker01 ~]# docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3f8a4339aadd 5 weeks ago 108MB
4.5 Import images
[root@docker01 ~]# docker image load -i docker-centos.tar.gz
e15afa4858b6: Loading layer 215.8MB/215.8MB
Loaded image: centos:latest
[root@docker01 ~]# docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest ff426288ea90 3 weeks ago 207MB
nginx latest 3f8a4339aadd 5 weeks ago 108MB
4.6 View image details
[root@docker01 ~]# docker image inspect centos
5 Daily management of containers
5.1 Start/stop of container
The simplest way to run a container
[root@docker01 ~]# docker run nginx
Create a container in two steps (not commonly used)
[root@docker01 ~]# docker create centos:latest /bin/bash
bb7f32368ecf0492adb59e20032ab2e6cf6a563a0e6751e58930ee5f7aaef204
[root@docker01 ~]# docker start stupefied_nobel
stupefied_nobel
How to quickly start a container
[root@docker01 ~]# docker run centos:latest /usr/bin/sleep 20;
The first process in the container must be running all the time, otherwise the container will be in the exit state!
View running containers
[root@docker01 ~]# docker container ls
或
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8708e93fd767 nginx "nginx -g 'daemon of…"6 seconds ago Up 4 seconds 80/tcp keen_lewin
View your container details/ip
[root@docker01 ~]# docker container inspect 容器名称/id
View all your containers (including those that are not running)
root@docker01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8708e93fd767 nginx "nginx -g 'daemon of…"4minutes ago Exited (0) 59 seconds ago keen_lewin
f9f3e6af7508 nginx "nginx -g 'daemon of…" 5 minutes ago Exited (0) 5 minutes ago optimistic_haibt
8d8f81da12b5 nginx "nginx -g 'daemon of…" 3 hours ago Exited (0) 3 hours ago lucid_bohr
Stop container
[root@docker01 ~]# docker stop 容器名称/id
或
[root@docker01 ~]# docker container kill 容器名称/id
5.2 Entering the container method
How to enter during startup
[root@docker01 ~]# docker run -it #参数:-it 可交互终端
[root@docker01 ~]# docker run -it nginx:latest /bin/bash
root@79241093859e:/#
Exit/leave the container
1 | ctrl+p & ctrl+q
How to enter the container after startup
Start a docker
[root@docker01 ~]# docker run -it centos:latest
[root@1bf0f43c4d2f /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 10015:47 pts/000:00:00 /bin/bash
root 131015:47 pts/000:00:00 ps -ef
Attach into the container and use pts/0, which will allow users who use this method to see the same operation as if they were put in.
[root@docker01 ~]# docker attach 1bf0f43c4d2f
[root@1bf0f43c4d2f /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 10015:47 pts/000:00:00 /bin/bash
root 141015:49 pts/000:00:00 ps -ef
Start a container with a self-name --name
[root@docker01 ~]# docker attach 1bf0f43c4d2f
[root@1bf0f43c4d2f /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 10015:47 pts/000:00:00 /bin/bash
root 141015:49 pts/000:00:00 ps -ef
exrc entry container method (recommended)
[root@docker01 ~]# docker exec -it clsn1 /bin/bash
[root@b20fa75b4b40 /]# 重新分配一个终端
[root@b20fa75b4b40 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 10016:11 pts/000:00:00 /bin/bash
root 130016:14 pts/100:00:00 /bin/bash
root 2613016:14 pts/100:00:00 ps -ef
5.3 Delete all containers
[root@docker01 ~]# docker rm -f `docker ps -a -q`
# -f 强制删除
5.4 Port mapping at startup
-p parameter port mapping
[root@docker01 ~]# docker run -d -p 8888:80 nginx:latest
287bec5c60263166c03e1fc5b0b8262fe76507be3dfae4ce5cd2ee2d1e8a89a9
Different specified mapping methods
parameter |
illustrate |
-p hostPort:containerPort |
Port mapping -p 8080:80 |
-p ip:hostPort:containerPort |
Configure listening address -p 10.0.0.100:8080:80 |
-p ip::containerPort |
Randomly assign ports -p 10.0.0.100::80 |
-p hostPort:containerPort:udp |
Specify protocol -p 8080:80:tcp |
-p 81:80 –p 443:443 |
Specify multiple |
random mapping
docker run -P (大P)# 需要镜像支持
6 Docker data volume management
6.1 Creating volumes when mounting
Mount volume
[root@docker01 ~]# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latest
079786c1e297b5c5031e7a841160c74e91d4ad06516505043c60dbb78a259d09
Site directory within the container: /usr/share/nginx/html
Write data on the host machine and view
[root@docker01 ~]# echo "http://www.nmtui.com" >/data/index.html
[root@docker01 ~]# curl 10.0.0.100
http://www.nmtui.com
Set up a shared volume and start a new container using the same volume
[root@docker01 ~]# docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx:latest
351f0bd78d273604bd0971b186979aa0f3cbf45247274493d2490527babb4e42
[root@docker01 ~]# curl 10.0.0.100:8080
http://www.nmtui.com
View volume list
[root@docker01 ~]# docker volume ls
DRIVER VOLUME NAME
6.2 Mount the volume after creating it
Create a volume
[root@docker01 ~]# docker volume create
f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
[root@docker01 ~]# docker volume ls
DRIVER VOLUME NAME
local f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
Specified volume name
[root@docker01 ~]# docker volume ls
DRIVER VOLUME NAME
local clsn
local f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
View volume path
[root@docker01 ~]# docker volume inspect clsn
[
{
"CreatedAt": "2018-02-01T00:39:25+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/clsn/_data",
"Name": "clsn",
"Options": {},
"Scope": "local"
}
]
Create using volume
[root@docker01 ~]# docker run -d -p 9000:80 -v clsn:/usr/share/nginx/html nginx:latest
1434559cff996162da7ce71820ed8f5937fb7c02113bbc84e965845c219d3503
# 宿主机测试
[root@docker01 ~]# echo 'blog.nmtui.com' >/var/lib/docker/volumes/clsn/_data/index.html
[root@docker01 ~]# curl 10.0.0.100:9000
blog.nmtui.com
Set up volume
[root@docker01 ~]# docker run -d -P --volumes-from 079786c1e297 nginx:latest
b54b9c9930b417ab3257c6e4a8280b54fae57043c0b76b9dc60b4788e92369fb
Check the ports used
[root@docker01 ~]# netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1400/sshd
tcp 0 0 10.0.0.100:2375 0.0.0.0:* LISTEN 26218/dockerd
tcp6 0 0 :::9000 :::* LISTEN 32015/docker-proxy
tcp6 0 0 :::8080 :::* LISTEN 31853/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 31752/docker-proxy
tcp6 0 0 :::22 :::* LISTEN 1400/sshd
tcp6 0 0 :::32769 :::* LISTEN 32300/docker-proxy
[root@docker01 ~]# curl 10.0.0.100:32769
http://www.nmtui.com
6.3 Manually save containers as images
This time it is created based on docker official centos 6.8 image
Official image list: https://hub.docker.com/explore/
Start a centos6.8 image
[root@docker01 ~]# docker pull centos:6.8
[root@docker01 ~]# docker run -it -p 1022:22 centos:6.8 /bin/bash
# 在容器种安装sshd服务,并修改系统密码
[root@582051b2b92b ~]# yum install openssh-server -y
[root@582051b2b92b ~]# echo "root:123456" |chpasswd
[root@582051b2b92b ~]# /etc/init.d/sshd start
Mirror ssh connection test after startup is complete
Submit container as image
[root@docker01 ~]# docker commit brave_mcclintock centos6-ssh
Start the container using the new image
[root@docker01 ~]# docker run -d -p 1122:22 centos6-ssh:latest /usr/sbin/sshd -D
5b8161fda2a9f2c39c196c67e2eb9274977e7723fe51c4f08a0190217ae93094
Install the httpd service in the container
[root@5b8161fda2a9 /]# yum install httpd -y
Write startup script script
[root@5b8161fda2a9 /]# cat init.sh
#!/bin/bash
/etc/init.d/httpd start
/usr/sbin/sshd -D
[root@5b8161fda2a9 /]# chmod +x init.sh
# 注意执行权限
Pay attention to execution permissions
Submit again as a new image
[root@docker01 ~]# docker commit 5b8161fda2a9 centos6-httpd
sha256:705d67a786cac040800b8485cf046fd57b1828b805c515377fc3e9cea3a481c1
Start the mirror and do port mapping. and test access in the browser
[root@docker01 ~]# docker run -d -p 1222:22 -p 80:80 centos6-httpd /init.sh
46fa6a06644e31701dc019fb3a8c3b6ef008d4c2c10d46662a97664f838d8c2c
7 Dockerfile automatically builds docker image
Official build dockerfile file reference: https://github.com/CentOS/CentOS-Dockerfiles
7.1 Dockerfile instruction set
The main components of dockerfile:
Basic image information FROM centos:6.8
Image creation instructions RUN yum insatll openssh-server \-y
Execute the command CMD when starting the container \["/bin/bash"\]
Common instructions for dockerfile:
FROM Who is the mother of this mirror? (Specify the base image)
MAINTAINER Tell others, who is responsible for raising it? (Specify maintainer information, optional)
RUN What do you want it to do (just add RUN in front of the command)
ADD Give it some entrepreneurial funds (COPY file, it will be automatically decompressed)
WORKDIR I am cd, I just put on makeup today (Set the current working directory)
VOLUME Give it a place to store luggage (set the volume, mount the host directory)
EXPOSE What door does it want to open (specify the external port)
CMD Run, brother! (Specify what to do after the container is started)
Dockerfile other instructions:
COPY copies the file
ENV environment variable
ENTRYPOINT command executed after the container is started.
7.2 Create a Dockerfile
Create the first Dockerfile
# 创建目录
[root@docker01 base]# cd /opt/base
# 创建Dcokerfile文件,注意大小写
[root@docker01 base]# vim Dockerfile
FROM centos:6.8
RUN yum install openssh-server -y
RUN echo "root:123456" |chpasswd
RUN /etc/init.d/sshd start
CMD ["/usr/sbin/sshd","-D"]
Build docker image
[root@docker01 base]# docker image build -t centos6.8-ssh .
-t 为镜像标签打标签 . 表示当前路径
Start using a self-built image
[root@docker01 base]# docker run -d -p 2022:22 centos6.8-ssh-b
dc3027d3c15dac881e8e2aeff80724216f3ac725f142daa66484f7cb5d074e7a
7.3 Install kodexplorer using Dcokerfile
Dockerfile file content
FROM centos:6.8
RUN yum install wget unzip php php-gd php-mbstring -y && yum clean all
# 设置工作目录,之后的操作都在这个目录中
WORKDIR /var/www/html/
RUN wget -c http://static.kodcloud.com/update/download/kodexplorer4.25.zip
RUN unzip kodexplorer4.25.zip && rm -f kodexplorer4.25.zip
RUN chown -R apache.apache .
CMD ["/usr/sbin/apachectl","-D","FOREGROUND"]
For more Dockerfile, please refer to the official method.
8 Image layering in Docker
Reference document: http://www.maiziedu.com/wiki/cloud/dockerimage
Docker supports the creation of new images by extending existing images. In fact, 99% of the images in Docker Hub are built by installing and configuring the required software in the base image.
As you can see from the picture above, the new image is generated by superimposing the base image layer by layer. Each time you install a piece of software, you add a layer to the existing image.
8.1 Why Docker images are layered
One of the biggest benefits of image layering is shared resources.
For example, if multiple images are built from the same base image, Docker Host only needs to save one base image on the disk; at the same time, it only needs to load one base image into the memory to serve all containers. And every layer of the image can be shared.
If multiple containers share a base image, when a container modifies the contents of the base image, such as files under /etc, the /etc of other containers will not be modified, and the modification will only be limited to a single container. Inside. This is the container Copy-on-Write feature.
8.2 Writable container layer
When the 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 "mirror layer".
All changes to the container - whether adding, deleting, or modifying files will only occur at the container layer. Only the container layer is writable, and all image layers below the container layer are read-only.
8.3 Details of the container layer
There may be many mirror layers, and all mirror layers will be combined to form a unified file system. If there is a file with the same path in different layers, such as /a, the /a in the upper layer will overwrite the /a in the lower layer, which means that the user can only access the file /a in the upper layer. In the container layer, what the user sees is a superimposed file system.
File operation instructions
File operations |
illustrate |
add files |
When a file is created in a container, the new file is added to the container layer. |
read file |
When reading a file in a container, Docker will search for the file in each image layer from top to bottom. Once found, it is immediately copied to the container layer, then opened and read into memory. |
Modify files |
When modifying an existing file in the container, Docker will search for the file in each image layer from top to bottom. Once found, copy it to the container layer and modify it. |
Delete Files |
When deleting a file in a container, Docker also searches for the file in the image layer from top to bottom. Once found, the deletion is logged at the container layer. (Just record the deletion operation) |
A copy of the data is only copied when it needs to be modified. This feature is called Copy-on-Write. It can be seen that the container layer saves the changed parts of the image and does not make any modifications to the image itself.
This explains the problem we raised earlier: the container layer records modifications to the image. All image layers are read-only and will not be modified by the container, so the image can be shared by multiple containers.
9 Use docker to run zabbix-server
9.1 Interconnection between containers
Before running zabbix, be sure to understand how to interconnect containers
# 创建一个nginx容器
docker run -d -p 80:80 nginx
# 创建容器,做link,并进入容器中
docker run -it --link quirky_brown:web01 centos-ssh /bin/bash
# 在容器中访问nginx容器可以ping通
ping web01
Command execution process
# 启动apache容器
[root@docker01 ~]# docker run -d httpd:2.4
3f1f7fc554720424327286bd2b04aeab1b084a3fb011a785b0deab6a34e56955
^[[A[root@docker01 docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f1f7fc55472 httpd:2.4"httpd-foreground"6 seconds ago Up 5 seconds 80/tcp determined_clarke
# 拉取一个busybox 镜像
[root@docker01 ~]# docker pull busybox
# 启动容器
[root@docker01 ~]# docker run -it --link determined_clarke:web busybox:latest /bin/sh
/ #
# 使用新的容器访问最初的web容器
/ # ping web
PING web (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.058 ms
^C
--- web ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.058/0.058/0.058 ms
9.2 Start zabbix container
1. Start a mysql container
docker run --name mysql-server -t \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-d mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin
2. Start the java-gateway container to monitor the java service
docker run --name zabbix-java-gateway -t \
-d zabbix/zabbix-java-gateway:latest
3. Start the zabbix-mysql container and use link to connect mysql and java-gateway.
docker run --name zabbix-server-mysql -t \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
--link mysql-server:mysql \
--link zabbix-java-gateway:zabbix-java-gateway \
-p 10051:10051 \
-d zabbix/zabbix-server-mysql:latest
4. Start zabbix web display and use link to connect zabbix-mysql and mysql.
docker run --name zabbix-web-nginx-mysql -t \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
--link mysql-server:mysql \
--link zabbix-server-mysql:zabbix-server \
-p 80:80 \
-d zabbix/zabbix-web-nginx-mysql:latest
9.3 About zabbix API
For information about the zabbix API, please refer to the official documentation: https://www.zabbix.com/documentation/3.4/zh/manual/api
Get token method
# 获取token
[root@docker02 ~]# curl -s -X POST -H 'Content-Type:application/json' -d '
{
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "Admin",
"password": "zabbix"
},
"id": 1
}' http://10.0.0.100/api_jsonrpc.php
{"jsonrpc":"2.0","result":"d3be707f9e866ec5d0d1c242292cbebd","id":1}
10 docker warehouse (registry)
10.1 Create a normal warehouse
1. Create a warehouse
docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
2. Modify the configuration file to support http
[root@docker01 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.100:5000"]
}
Restart docker for the changes to take effect
[root@docker01 ~]# systemctl restart docker.service
3. Modify the image label
[root@docker01 ~]# docker tag busybox:latest 10.0.0.100:5000/clsn/busybox:1.0
[root@docker01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos6-ssh latest 3c2b1e57a0f5 18 hours ago 393MB
httpd 2.42e202f453940 6 days ago 179MB
10.0.0.100:5000/clsn/busybox 1.05b0d59026729 8 days ago 1.15MB
4. Upload the newly tagged image to the warehouse
[root@docker01 ~]# docker push 10.0.0.100:5000/clsn/busybox
10.2 Warehouse with basic certification
1. Install encryption tools
[root@docker01 clsn]# yum install httpd-tools -y
2. Set authentication password
mkdir /opt/registry-var/auth/ -p
htpasswd \-Bbn clsn 123456 > /opt/registry-var/auth/htpasswd
3. Start the container and pass in the authentication parameters when starting.
docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
4. Use verified user testing
# 登陆用户
[root@docker01 ~]# docker login 10.0.0.100:5000
Username: clsn
Password: 123456
Login Succeeded
# 推送镜像到仓库
[root@docker01 ~]# docker push 10.0.0.100:5000/clsn/busybox
The push refers to repository [10.0.0.100:5000/clsn/busybox]
4febd3792a1f: Pushed
1.0: digest: sha256:4cee1979ba0bf7db9fc5d28fb7b798ca69ae95a47c5fecf46327720df4ff352d size: 527
#认证文件的保存位置
[root@docker01 ~]# cat .docker/config.json
{
"auths": {
"10.0.0.100:5000": {
"auth": "Y2xzbjoxMjM0NTY="
},
"https://index.docker.io/v1/": {
"auth": "Y2xzbjpIenNAMTk5Ng=="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/17.12.0-ce (linux)"
}
}
At this point, a simple docker image warehouse is built.
11 docker-compose orchestration tool
11.1 Install docker-compose
Install docker-compose
# 下载pip软件
yum install -y python2-pip
# 下载 docker-compose
pip install docker-compose
Enable pip download acceleration in China: http://mirrors.aliyun.com/help/pypi
mkdir ~/.pip/
cat > ~/.pip/pip.conf <<'EOF'
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
EOF
11.2 Orchestrate startup image
1. Create a file directory
[root@docker01 ~]# mkdir /opt/my_wordpress/
[root@docker01 ~]# cd /opt/my_wordpress/
2. Write arrangement files
[root@docker01 my_wordpress]# vim docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
volumes:
- /data/db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- /data/web_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
3. Start
[root@docker01 my_wordpress]# docker-compose up
#启动方法:docker-compose up
#后台启动方法:docker-compose up -d
4. Access http://10.0.0.100:8000 on the browser
Just install wordpress
11.3 haproxy proxy backend docker container
1. Modify the arrangement script
[root@docker01 my_wordpress]# cat docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
volumes:
- /data/db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- /data/web_data:/var/www/html
ports:
- "80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
2. Start two wordpress at the same time
[root@docker01 my_wordpress]# docker-compose scale wordpress=2
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Starting mywordpress_wordpress_1 ... done
Creating mywordpress_wordpress_2 ... done
3. Install haproxy
[root@docker01 ~]# yum install haproxy -y
4. Modify haproxy configuration file
For detailed description of the configuration file, refer to: https://www.cnblogs.com/MacoLee/p/5853413.html
[root@docker01 ~]#cp /etc/haproxy/haproxy.cfg{,.bak}
[root@docker01 ~]# vim /etc/haproxy/haproxy.cfg
global
log127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats level admin #支持命令行控制
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen stats
mode http
bind 0.0.0.0:8888
stats enable
stats uri /haproxy-status
stats auth admin:123456
frontend frontend_www_example_com
bind 10.0.0.100:8000
mode http
option httplog
log global
default_backend backend_www_example_com
backend backend_www_example_com
option forwardfor header X-REAL-IP
option httpchk HEAD / HTTP/1.0
balance roundrobin
server web-node1 10.0.0.100:32768 check inter 2000 rise 30 fall 15
server web-node2 10.0.0.100:32769 check inter 2000 rise 30 fall 15
5. Start haproxy
systemctl start haproxy
systemctl enable haproxy
6. Use a browser to access the 8000 port that hapeoxy listens on to see the load.
7. Use a browser to access http://10.0.0.100:8888/haproxy-status
You can see the monitoring status of the backend nodes.
11.4 Install socat and directly operate the socket to control haproxy
1. Install software
yum install socat.x86\_64 -y
2. View help
[root@docker01 web_data]# echo "help"|socat stdio /var/lib/haproxy/stats
3. Offline backend nodes
echo "disable server backend_www_example_com/web-node2"|socat stdio /var/lib/haproxy/stats
4. Online backend node
echo "enable server backend_www_example_com/web-node3"|socat stdio /var/lib/haproxy/stats
5. Write a php test page and place it under /data/web_data. You can view the current node by accessing it in the browser.
[root@docker01 web_data]# vim check.php
<html>
<head>
<title>PHP测试</title>
</head>
<body>
<?php echo '<p>Hello World </p>'; ?>
<?php echo "访问的服务器地址是:"."<fontcolor=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>";
echo"访问的服务器域名是:"."<fontcolor=red>".$_SERVER['SERVER_NAME']."</font>"."<br>";
?>
</body>
</html>
12 Solution to restart docker service and exit all containers
12.1 Specify automatic restart at startup
docker run --restart=always
12.2 Modify docker default configuration file
# 添加上下面这行
"live-restore": true
docker server configuration file /etc/docker/daemon.json reference
[root@docker02 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"graph": "/opt/mydocker", # 修改数据的存放目录到/opt/mydocker/,原/var/lib/docker/
"insecure-registries": ["10.0.0.100:5000"],
"live-restore": true
}
Restart takes effect and only takes effect for containers started after this
[root@docker01 ~]# systemctl restart docker.service
13 Docker network types
13.1 Docker network types
type |
illustrate |
None |
Do not configure any network functions for the container, no network --net=none |
Container |
Share the Network Namespace with another running container, --net=container:containerID |
Host |
Share Network Namespace with host, --net=host |
Bridge |
NAT network model designed by Docker (default type) |
Bridge's default docker network isolation is based on the network namespace. When a docker container is created on a physical machine, a network namespace is allocated to each docker container, and the container IP is bridged to the virtual network bridge of the physical machine.
13.2 Do not configure network functions for containers
Creating a container in this mode will not configure any network parameters for the container, such as container network card, IP, communication routing, etc., all of which need to be configured by yourself.
[root@docker01 ~]# docker run -it --network none busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
13.3 Sharing network configuration with other containers (Container)
This mode is very similar to the host mode, except that the container created in this mode shares the IP and port of other containers instead of the physical machine. The container itself in this mode does not configure the network and port. After creating the container in this mode, you will find that inside The IP is the container IP you specified and the port is shared, and others are isolated from each other, such as processes.
[root@docker01 ~]# docker run -it --network container:mywordpress_db_1 busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
13.4 Using host networking
The container created in this mode does not have its own independent network namespace. It shares a Network Namespace with the physical machine and shares all ports and IPs of the physical machine. This mode is considered unsafe.
[root@docker01 ~]# docker run -it --network host busybox:latest /bin/sh
13.5 View network list
[root@docker01 ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
b15e8a720d3b bridge bridge local
345d65b4c2a0 host host local
bc5e2a32bb55 mywordpress_default bridge local
ebf76eea91bb none null local
13.6 Use PIPEWORK to configure independent IP for docker container
Reference document: http://blog.csdn.net/design321/article/details/48264825
Official website: https://github.com/jpetazzo/pipework
Host environment: centos7.2
1. Install pipeline
wget https://github.com/jpetazzo/pipework/archive/master.zip
unzip master.zip
cp pipework-master/pipework /usr/local/bin/
chmod +x /usr/local/bin/pipework
2. Configure the bridge network card
Install bridging tools
yum install bridge-utils.x86\_64 -y
Modify the network card configuration to implement bridging
# 修改eth0配置,让br0实现桥接
[root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
BRIDGE=br0
[root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
BOOTPROTO=static
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=10.0.0.100
NETMASK=255.255.255.0
GATEWAY=10.0.0.254
DNS1=223.5.5.5
# 重启网络
[root@docker01 ~]# /etc/init.d/network restart
3. Run a container image test:
pipework br0 \$\(docker run -d -it -p 6880:80 --name httpd\_pw httpd\) 10.0.0.220/24\@10.0.0.254
Test ports and connectivity on other hosts
[root@docker01 ~]# curl 10.0.0.220
<html><body><h1>It works!</h1></body></html>
[root@docker01 ~]# ping 10.0.0.220 -c 1
PING 10.0.0.220 (10.0.0.220) 56(84) bytes of data.
64 bytes from 10.0.0.220: icmp_seq=1 ttl=64 time=0.043 ms
4. Run another container and set the network type to none:
pipework br0 $(docker run -d -it --net=none --name test httpd:2.4) 10.0.0.221/[email protected]
Conduct access testing
[root@docker01 ~]# curl 10.0.0.221
<html><body><h1>It works!</h1></body></html>
5. After restarting the container, you need to specify again:
pipework br0 testduliip 172.16.146.113/24\@172.16.146.1 pipework br0 testduliip01 172.16.146.112/24\@172.16.146.1
For overlay of Dcoker cross-host communication, please refer to:
http://www.cnblogs.com/CloudMan6/p/7270551.html
13.7 Docker cross-host communication macvlan
Create network
[root@docker01 ~]# docker network create --driver macvlan --subnet 10.1.0.0/24 --gateway 10.1.0.254 -o parent=eth0 macvlan_1
33a1f41dcc074f91b5bd45e7dfedabfb2b8ec82db16542f05213839a119b62ca
Set the network card to promiscuous mode
ip link set eth0 promisc on
Create a network container using macvlan
[root@docker02 ~]# docker run -it --network macvlan_1 --ip=10.1.0.222 busybox /bin/sh
14 docker enterprise mirror warehouse harbor
Container management
[root@docker01 harbor]# pwd
/opt/harbor
[root@docker01 harbor]# docker-compose stop
1. Install docker and docker-compose
download harbor
cd /opt && https://storage.googleapis.com/harbor-releases/harbor-offline-installer-v1.3.0.tgz
tar xf harbor-offline-installer-v1.3.0.tgz
2. Modify the host and web interface passwords
[root@docker01 harbor]# vim harbor.cfg
···
hostname = 10.0.0.100
harbor_admin_password = Harbor12345
···
3. Execute the installation script
[root@docker01 harbor]# ./install.sh
Browser access http://10.0.0.11
add an item
4. Push the image to the designated project in the warehouse
[root@docker02 ~]# docker tag centos:6.8 10.0.0.100/clsn/centos6.8:1.0
[root@docker02 ~]#
[root@docker02 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 5b0d59026729 8 days ago 1.15MB
10.0.0.100/clsn/centos6.81.06704d778b3ba 2 months ago 195MB
centos 6.86704d778b3ba 2 months ago 195MB
[root@docker02 ~]# docker login 10.0.0.100
Username: admin
Password:
Login Succeeded
5. Push the image
[root@docker02 ~]# docker push 10.0.0.100/clsn/centos6.8
The push refers to repository [10.0.0.100/clsn/centos6.8]
e00c9229b481: Pushing 13.53MB/194.5MB
6. View in the web interface
14.1 Recommendations for using containers
-
Don’t do app releases in split form
-
Don't create large images
-
Don't run multiple processes in a single container
-
Don’t save credentials in the image and don’t rely on IP addresses
-
Run process as non-root user
-
Don't use the "latest" tag
-
Don’t create images from running containers
-
Don’t use single-layer mirroring
-
Don't store data in containers
14.2 About monitoring Docker containers
Basic information about the container
Including container number, ID, name, image, startup command, port and other information
Container running status
Count the number of containers in each status, including running, paused, stopped and abnormal exit
Container usage information
Statistics on the container’s CPU usage, memory usage, block device I/O usage, network usage and other resource usage
15 References
[1] https://www.redhat.com/zh/topics/containers/whats-a-linux-container
[2] https://www.redhat.com/zh/topics/containers/what-is-docker
[3] http://blog.51cto.com/dihaifeng/1713512
[4] https://www.cnblogs.com/Bourbon-tian/p/6867796.html
[5] https://www.cnblogs.com/CloudMan6/p/6806193.htm
Acknowledgments to the author: Miserable Green Boy