初识 Docker

初识 Docker

Docker 简介

简介来自于 Docker 入门教程 - 阮一峰的网络日志

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

安装 Docker

在此部分,作者使用的是 Centos 8.2 进行的操作,下述的安装命令仅保证在该环境下运行。

设置 Docker 仓库

根据官方教程,执行以下两条命令:

1
2
3
4
5
sudo yum install -y yum-utils

sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

由于国内直接连接 Docker 官方镜像源十分缓慢,所以在第二个命令中将官方镜像源替换为阿里云镜像源。

安装 Docker 引擎

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

在执行这条命令时,极有可能会报错。比如作者遇到的报错如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Error:
 Problem: package docker-ce-3:19.03.8-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of the providers can be installed
  - cannot install the best candidate for the job
  - package containerd.io-1.2.10-3.2.el7.x86_64 is excluded
  - package containerd.io-1.2.13-3.1.el7.x86_64 is excluded
  - package containerd.io-1.2.2-3.3.el7.x86_64 is excluded
  - package containerd.io-1.2.2-3.el7.x86_64 is excluded
  - package containerd.io-1.2.4-3.1.el7.x86_64 is excluded
  - package containerd.io-1.2.5-3.1.el7.x86_64 is excluded
  - package containerd.io-1.2.6-3.3.el7.x86_64 is excluded

为了解决这个报错,需要先执行下述命令安装好 containerd.io 组件。

1
2
3
4
sudo yum install -y \
    https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.13-3.2.el7.x86_64.rpm

sudo yum -y install ./containerd.io-1.2.13-3.1.el7.x86_64.rpm

至于为什么安装的 containerd.io 组件是 centos 7 目录下的,有两个原因:

  1. 此版本在 centos 8 环境下也可以正常使用;
  2. 阿里云官方只提供了适配 centos 7 的 containerd.io 组件。

然后重新执行上述命令即可完成 Docker 的安装。

1
sudo yum install docker-ce docker-ce-cli

我们可以通过两个命令来验证 Docker 是否安装成功。

1
2
3
docker version
## 或
docker info

若输出类似于以下的内容,则配置正确。

 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
[root@localhost ~]## docker version
Client: Docker Engine - Community
 Version:           19.03.12
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        48a66213fe
 Built:             Mon Jun 22 15:46:54 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.12
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.10
  Git commit:       48a66213fe
  Built:            Mon Jun 22 15:45:28 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc8
  GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

配置 Docker 仓库

由于在国内连接 Docker 官方仓库 https://hub.docker.com 十分缓慢,故我们可以将仓库地址更换为国内的各种源,详细步骤如下。

  1. /etc/docker 目录中新增一个名为 daemon.json 的配置文件,如果已经存在这个文件,则只需要进行修改。
  2. 将该文件中的 registry-mirrors 项修改为如下形式。
1
2
3
4
5
6
{
  "registry-mirrors": [
    "https://kuamavit.mirror.aliyuncs.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

到此就配置完毕了。

启动并运行 Docker

启动

1
2
3
$ sudo service docker start
## 或
$ sudo systemctl start docker

运行 hello-world

1
sudo docker run hello-world

此时,由于本地尚未安装 hello-world 实例,Docker 会自动从上文中配置的镜像中拉取 hello-world 实例,然后运行这个实例。具体输出如下。

 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
[root@localhost docker]## docker run hello-world

## 这里提示未在本地找到 hello-world 实例,将从镜像中拉取最新版。
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world

0e03bdcc26d7: Pull complete
Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
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/

容器管理

当 image 文件开始运行之后,就会生成一个容器实例,容器实例实际上也是一个文件,故也称为实例文件。当容器实例停止运行时,容器文件并不会被删除。

  1. 列出本机正在运行的容器
1
sudo docker container ls
  1. 列出本机所有容器(包括已停止运行的)
1
sudo docker container ls -all

输出结果如下。

1
2
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
d3a382fde773        hello-world         "/hello"            8 minutes ago       Exited (0) 8 minutes ago                       romantic_proskuriakova

其中 CONTAINER ID 就是该容器的唯一标识符,在后续的终止容器运行时需要用到。

  1. 终止容器运行
1
sudo docker container kill d3a382fde773

当然本例中 hello-world 容器已经停止运行了,所以不能再次停止,此处仅做示例。 即使一个容器文件已经停止运行,但是其依然会占据磁盘空间,可以使用下述命令进行删除。

1
sudo docker container rm d3a382fde773

镜像管理

当我们拉取了多个镜像,其中某些又不需要使用了,则需要对镜像进行手动管理,详细操作如下。

  1. 罗列所有本地已经安装的镜像
1
sudo docker image ls

输出如下

1
2
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        8 months ago        13.3kB
  1. 移除不需要的镜像
1
sudo docker image rm hello-world

注意,如果 image 在运行,或者已经生成了实例文件,是不能直接删除的,需要先将实例容器停止并删除实例文件,才可以正常删除。执行结果如下。

1
2
3
4
Untagged: hello-world:latest
Untagged: hello-world@sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy