系统:CentOS7.9,Docker实践

安装Docker

参考链接:https://yeasy.gitbook.io/docker_practice/install/centos 官方参考文档:https://docs.docker.com/engine/install/centos/

链接里提到的注意点:

  • 切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker.
  • Docker 支持 64 位版本 CentOS 7/8,并且要求内核版本不低于 3.10。 CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 overlay2 存储层驱动)无法使用,并且部分功能可能不太稳定。

使用YUM安装(没有试过)

添加国内的yum源:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ sudo yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

$ sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo

# 官方源
# $ sudo yum-config-manager \
#     --add-repo \
#     https://download.docker.com/linux/centos/docker-ce.repo

安装Docker:

更新 yum 软件源缓存,并安装 docker-ce

1
$ sudo yum install docker-ce docker-ce-cli containerd.io

使用脚本自动安装(用的这个)

在测试和开发环境可以使用更简单的安装脚本来安装。另外可以通过 --mirror 选项使用国内源进行安装。

1
2
3
4
# $ curl -fsSL test.docker.com -o get-docker.sh
$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun
# $ sudo sh get-docker.sh --mirror AzureChinaCloud

执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定(stable)版本安装在系统中。

启动Docker

1
2
$ sudo systemctl enable docker
$ sudo systemctl start docker

此时,使用systemctl status docker查看docker状态,已经是active了!

建立docker用户组

默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。

1
2
3
4
# 建立docker组
sudo groupadd doker
# 将用户加入docker组
sudo usermod -aG docker cindy

使用有权限的用户重新登陆,测试docker是否安装正确

 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
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ whoami
cindy
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete
Digest: sha256:926fac19d22aa2d60f1a276b66a20eb765fbeea2db5dbdaafeb456ad8ce81598
Status: Downloaded newer image for hello-world:latest

Hello from Docker!

This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

有输出这类信息,说明安装成功!

添加内核参数

这一步文章里有提到,但我的服务器不需要做。

如果在 CentOS 使用 Docker 看到下面的这些警告信息:

1
2
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

请添加内核配置参数以启用这些功能。

1
2
3
4
$ sudo tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

然后重新加载 sysctl.conf 即可

$ sudo sysctl -p

使用镜像

参考链接:https://yeasy.gitbook.io/docker_practice/image/pull

获取镜像

镜像仓库Docker Hub里有很多镜像可以直接获取,而获取的命令是docker pull

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ docker pull --help

Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Download an image from a registry

Aliases:
docker image pull, docker pull

Options:

-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--platform string Set platform if server is multi-platform capable

-q, --quiet Suppress verbose output

即,$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

  • 仓库地址:<域名/ip>[:端口],默认地址是 Docker Hub(docker.io)。
  • 仓库名:<用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。

文章中给出了一个例子: 比如:

1
2
3
4
5
6
7
8
$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
92dc2a97ff99: Pull complete
be13a9d27eb8: Pull complete
c8299583700a: Pull complete
Digest: sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9c4361e321b26
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04

上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub (docker.io)获取镜像。而镜像名称是 ubuntu:18.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 18.04 的镜像。docker pull 命令的输出结果最后一行给出了镜像的完整名称,即: docker.io/library/ubuntu:18.04

列出镜像

命令:docker image ls

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
docker image ls --help

Usage: docker image ls [OPTIONS] [REPOSITORY[:TAG]]

List images

Aliases:
docker image ls, docker image list, docker images

Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Format output using a custom template:
'table': Print output in table format with column headers (default)
'table TEMPLATE': Print output in table format using the given Go template
'json': Print in JSON format
'TEMPLATE': Print output using the given Go template.

Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates

--no-trunc Don't truncate output
-q, --quiet Only show image IDs

查看镜像、容器、数据卷占用空间:docker system df

一些镜像概念:

  • 虚悬镜像(dangling image):由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 <none> 的镜像。这类可直接删除
  • 中间层镜像:为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。所以在使用一段时间后,可能会看到一些依赖的中间层镜像。加上-a参数可列出这类镜像。这种镜像不要删除。

删除本地镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
docker image rm --help

Usage: docker image rm [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

Aliases:
docker image rm, docker image remove, docker rmi

Options:
-f, --force Force removal of the image
--no-prune Do not delete untagged parents

删除命令的参数形式可以是多样的,比如长短id、镜像名。

如何利用docker image ls实现批量删除镜像,下面是个例子:

1
2
3
4
5
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker image rm $(docker image ls -q ubuntu)
Untagged: ubuntu:18.04
Untagged: ubuntu@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
Deleted: sha256:f9a80a55f492e823bf5d51f1bd5f87ea3eed1cb31788686aa99a2fb61a27af6a
Deleted: sha256:548a79621a426b4eb077c926eabac5a8620c454fb230640253e1b44dc7dd7562

注意:镜像有可能删除失败。比如:

  • 镜像的多层结构让镜像复用变得非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。
  • 镜像如果被某个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。

操作容器

参考链接:https://yeasy.gitbook.io/docker_practice/container/run

介绍容器的基本操作:启动、守护态运行、终止(不是删除)、进入容器、导出导入、删除

启动容器

有两种启动方式:1、基于image新建容器并启动;2、启动终止状态(exited)的容器

方式1

命令:docker run。如下面的例子是启动一个bash终端,允许交互。

1
2
3
4
5
6
7
8
$ docker run -t -i ubuntu:18.04 /bin/bash
root@af8bae53bdd3:/#
# 直接就进入了新开的容器的ubuntu终端了,很方便
# 容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。是货真价实的轻量级虚拟化。
root@5fe7df47e920:/home# ps
PID TTY TIME CMD
1 pts/0 00:00:00 bash
18 pts/0 00:00:00 ps

方式2

可以利用 docker container start 命令,直接将一个已经终止(exited)的容器启动运行。参数要指定要启动的容器id。

另外,重启执行态的容器,可以用docker container restart

守护态运行

守护态(Daemonized)运行,即在后台运行,输出也不会输出到当前的终端上。通常使用-d参数来实现。

如文章中给的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a
# 使用-d参数启动,会返回唯一id

# 查看容器信息,可以看到正在运行的该容器信息
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8cc6b78121c ubuntu:18.04 "/bin/sh -c 'while t…" 59 seconds ago Up 57 seconds elastic_williamson

# 查看容器的输出信息(需要指定上面的id或names)
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container logs a8cc6b78121c
hello world
hello world

终止容器

  1. docker container stop
  2. 终止Docker容器中指定的应用时,容器也自动终止。例如上面只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 终止容器
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container stop a8cc6b78121c
a8cc6b78121c

# 查看状态
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8cc6b78121c ubuntu:18.04 "/bin/sh -c 'while t…" 7 minutes ago Exited (137) About a minute ago elastic_williamson
5fe7df47e920 ubuntu:18.04 "/bin/bash" 28 minutes ago Exited (127) 17 minutes ago hungry_spence

进入容器

进入容器,一般使用docker attachdocker exec(更推荐)命令。

方式1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b10eb582635 ubuntu:18.04 "/bin/bash" 54 seconds ago Up 52 seconds awesome_hermann
# 利用attach命令进入指定id的容器
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker attach 3b10eb582635
root@3b10eb582635:/# whoami
root
# 使用exit方式退出,容器会自动停止
root@3b10eb582635:/# exit
exit

方式2

1
2
3
4
5
6
7
8
9
# exec方式进入容器。可以加上-i和-t参数,使用命令行界面
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker exec -it 3b1 bash
root@3b10eb582635:/# exit
exit

# 使用exec进入容器的方式,exit不会自动停止容器。所以推荐用这个方法进入。
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b10eb582635 ubuntu:18.04 "/bin/bash" 6 minutes ago Up About a minute awesome_hermann

导出和导入

  1. 导出 docker export 7691a814370e > ubuntu.tar

  2. 导入 cat ubuntu.tar | docker import - test/ubuntu:v1.0

docker import http://example.com/exampleimage.tgz example/imagerepo

注:用户既可以使用 _docker load_ 来导入镜像存储文件到本地镜像库,也可以使用 _docker import_ _来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。

删除

命令:docker container rm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 删除一个运行态的docker会报错
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container rm awesome_hermann
Error response from daemon: You cannot remove a running container 3b10eb5826358933c4e6f4bb47900892b4d9d32c74bf75bdbd6dbe953ae5f9d0. Stop the container before attempting removal or force remove

# 可以使用-f参数强制删除。Docker 会发送 `SIGKILL` 信号给容器。
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container rm -f awesome_hermann
awesome_hermann

[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

批量删除所有终止态的容器:docker container prune

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8cc6b78121c ubuntu:18.04 "/bin/sh -c 'while t…" 41 minutes ago Exited (137) 35 minutes ago elastic_williamson
5fe7df47e920 ubuntu:18.04 "/bin/bash" About an hour ago Exited (127) 51 minutes ago hungry_spence

[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
a8cc6b78121c0a089f028227fadfddb1aba8f9a59f12900023fc76ce378bee91
5fe7df47e9207ce29068daca28447c9c3fdbd0215f546d1a8a5d9251683a327c
Total reclaimed space: 112B

[cindy@iZbp15qc4wmx335c268l5mZ ~]$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES