yanpenggong 大数据实验室

一个专注于科研前线的大数据团队,致力于打造更好更牛的大数据平台

0%

docker从入门到实践

Author: yanpengGong         Email:yanpenggong@163.com

目录


[TOC]

前言

Docker 是个伟大的项目,它彻底释放了虚拟化的威力,极大降低了云计算资源供应的成本,同时让应用的分发、测试、部署和分发都变得前所未有的高效和轻松!

本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍一些高级操作;第 10 章给出典型的应用场景和实践案例;11 ~ 13 章介绍关于 Docker 实现的相关技术。14 ~ 17章介绍相关的一些开源项目。

一、 Docker 简介

1. Docker是什么

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。

Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。

Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。

在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。

2. 使用Docker的理由

作为一种虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。

首先,Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。 其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。

容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。

具体说来,Docker 在如下几个方面具有较大的优势。

  1. 更快速的交付和部署

    对开发和运维(devop)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

    开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。

  2. 更高效的虚拟化

    Docker 容器的运行不需要额外的 hypervisor 支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。

  3. 更轻松的迁移和扩展

    Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。

  4. 更简单的管理

    使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。

  5. 对比传统虚拟机总结

    | 特性 | 容器 | 虚拟机 |
    | :————- | :————————- | :————- |
    | 启动 | 秒级 | 分钟级 |
    | 硬盘使用 | 一般为 MB | 一般为 GB |
    | 性能 | 接近原生 | 弱于 |
    | 系统支持量 | 单机支持上千个容器 | 一般几十个 |

二、Docker 基本概念

1. Docker 镜像

Docker 镜像就是一个只读的模板。

例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。

镜像可以用来创建 Docker 容器。

Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。

2. Docker容器的运用

2018-08-04 17:51 更新

Docker 利用容器来运行应用。

容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。

3. Docker仓库

仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。

最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool 等,可以提供大陆用户更稳定快速的访问。

当然,用户也可以在本地网络内创建一个私有仓库。

当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

注:Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。

三、Docker安装指南

官方网站上有各种环境下的 安装指南,这里主要介绍下CentOS系列的安装。

1. 使用官方安装脚本自动安装

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
[root@localhost software]# curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
# Executing docker install script, commit: b2e29ef7a9a89840d2333637f7d1900a83e7153f
+ sh -c 'yum install -y -q yum-utils'
Package yum-utils-1.1.31-54.el7_8.noarch already installed and latest version
+ sh -c 'yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo'
Loaded plugins: fastestmirror, langpacks, product-id, subscription-manager

This system is not registered with an entitlement server. You can use subscription-manager to register.

adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
+ '[' stable '!=' stable ']'
+ sh -c 'yum makecache'
Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

This system is not registered with an entitlement server. You can use subscription-manager to register.

Loading mirror speeds from cached hostfile
* base: ftp.sjtu.edu.cn
* extras: mirrors.bfsu.edu.cn
* updates: ftp.sjtu.edu.cn
base | 3.6 kB 00:00:00
docker-ce-stable | 3.5 kB 00:00:00
extras | 2.9 kB 00:00:00
updates | 2.9 kB 00:00:00
Metadata Cache Created
+ sh -c 'yum install -y -q docker-ce docker-ce-cli containerd.io docker-scan-plugin docker-compose-plugin docker-ce-rootless-extras'
warning: /var/cache/yum/x86_64/7/docker-ce-stable/packages/docker-ce-20.10.17-3.el7.x86_64.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
Public key for docker-ce-20.10.17-3.el7.x86_64.rpm is not installed

Importing GPG key 0x621E9F35:
Userid : "Docker Release (CE rpm) <docker@docker.com>"
Fingerprint: 060a 61c5 1b55 8a7f 742b 77aa c52f eb6b 621e 9f35
From : https://mirrors.aliyun.com/docker-ce/linux/centos/gpg

================================================================================

To run Docker as a non-privileged user, consider setting up the
Docker daemon in rootless mode for your user:

dockerd-rootless-setuptool.sh install

Visit https://docs.docker.com/go/rootless/ to learn about rootless mode.


To run the Docker daemon as a fully privileged service, but granting non-root
users access, refer to https://docs.docker.com/go/daemon-access/

WARNING: Access to the remote API on a privileged Docker daemon is equivalent
to root access on the host. Refer to the 'Docker daemon attack surface'
documentation for details: https://docs.docker.com/go/attack-surface/

================================================================================

[root@localhost software]#

也可以使用国内 daocloud 一键安装命令:

1
[root@localhost software]# curl -sSL https://get.daocloud.io/docker | sh

2. 手动安装

2.1 卸载旧版本

较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@localhost software]# yum remove docker \
> docker-client \
> docker-client-latest \
> docker-common \
> docker-latest \
> docker-latest-logrotate \
> docker-logrotate \
> docker-engine
Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

This system is not registered with an entitlement server. You can use subscription-manager to register.

No Match for argument: docker
No Match for argument: docker-client
No Match for argument: docker-client-latest
No Match for argument: docker-common
No Match for argument: docker-latest
No Match for argument: docker-latest-logrotate
No Match for argument: docker-logrotate
No Match for argument: docker-engine
No Packages marked for removal
[root@localhost software]#

2.2 安装 Docker Engine-Community

在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库。之后,您可以从仓库安装和更新 Docker。

2.2.1 设置仓库

安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-datalvm2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost software]# yum install -y yum-utils device-mapper-persistent-data lvm2
Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

This system is not registered with an entitlement server. You can use subscription-manager to register.

Loading mirror speeds from cached hostfile
* base: ftp.sjtu.edu.cn
* extras: mirrors.bfsu.edu.cn
* updates: ftp.sjtu.edu.cn
Package yum-utils-1.1.31-54.el7_8.noarch already installed and latest version
Package device-mapper-persistent-data-0.8.5-3.el7_9.2.x86_64 already installed and latest version
Package 7:lvm2-2.02.187-6.el7_9.5.x86_64 already installed and latest version
Nothing to do
[root@localhost software]#

设置稳定的仓库:

  • 使用官方源地址(比较慢)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@localhost software]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    Loaded plugins: fastestmirror, langpacks, product-id, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
    grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
    repo saved to /etc/yum.repos.d/docker-ce.repo
    [root@localhost software]#

  • 选择国内的 阿里云 源地址:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@localhost software]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    Loaded plugins: fastestmirror, langpacks, product-id, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    adding repo from: http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    grabbing file http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
    repo saved to /etc/yum.repos.d/docker-ce.repo
    [root@localhost software]#
  • 选择国内的 清华大学 源地址:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@localhost software]# yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
    Loaded plugins: fastestmirror, langpacks, product-id, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    adding repo from: https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
    grabbing file https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
    repo saved to /etc/yum.repos.d/docker-ce.repo
    [root@localhost software]#

2.2.2 安装 Docker Engine-Community

  • 安装最新版本的 Docker Engine-Communitycontainerd

    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
    [root@localhost software]# yum install docker-ce docker-ce-cli containerd.io
    Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    Loading mirror speeds from cached hostfile
    * base: ftp.sjtu.edu.cn
    * extras: mirrors.bfsu.edu.cn
    * updates: ftp.sjtu.edu.cn
    docker-ce-stable | 3.5 kB 00:00:00
    Package 1:docker-ce-cli-20.10.17-3.el7.x86_64 already installed and latest version
    Package containerd.io-1.6.7-3.1.el7.x86_64 already installed and latest version
    Resolving Dependencies
    --> Running transaction check
    ---> Package docker-ce.x86_64 3:20.10.17-3.el7 will be installed
    --> Processing Dependency: docker-ce-rootless-extras for package: 3:docker-ce-20.10.17-3.el7.x86_64
    --> Running transaction check
    ---> Package docker-ce-rootless-extras.x86_64 0:20.10.17-3.el7 will be installed
    --> Finished Dependency Resolution

    Dependencies Resolved

    ========================================================================================================================
    Package Arch Version Repository Size
    ========================================================================================================================
    Installing:
    docker-ce x86_64 3:20.10.17-3.el7 docker-ce-stable 22 M
    Installing for dependencies:
    docker-ce-rootless-extras x86_64 20.10.17-3.el7 docker-ce-stable 8.2 M

    Transaction Summary
    ========================================================================================================================
    Install 1 Package (+1 Dependent package)

    Total download size: 31 M
    Installed size: 115 M
    Is this ok [y/d/N]: y
    Downloading packages:
    (1/2): docker-ce-rootless-extras-20.10.17-3.el7.x86_64.rpm | 8.2 MB 00:00:28
    (2/2): docker-ce-20.10.17-3.el7.x86_64.rpm | 22 MB 00:01:18
    ------------------------------------------------------------------------------------------------------------------------
    Total 400 kB/s | 31 MB 00:01:18
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
    Installing : 3:docker-ce-20.10.17-3.el7.x86_64 1/2
    Installing : docker-ce-rootless-extras-20.10.17-3.el7.x86_64 2/2
    Verifying : docker-ce-rootless-extras-20.10.17-3.el7.x86_64 1/2
    Verifying : 3:docker-ce-20.10.17-3.el7.x86_64 2/2

    Installed:
    docker-ce.x86_64 3:20.10.17-3.el7

    Dependency Installed:
    docker-ce-rootless-extras.x86_64 0:20.10.17-3.el7

    Complete!
    [root@localhost software]#

    如果提示您接受 GPG 密钥,请选是。

    有多个 Docker 仓库吗?

    如果启用了多个 Docker 仓库,则在 yum installyum update 命令中指定版本的情况下,进行的安装或更新将始终安装最高版本,这可能不适合您的稳定性需求。

    Docker 安装完默认未启动。并且已经创建好 docker 用户组,但该用户组下没有用户。

  • 安装特定版本:

    安装特定版本的 Docker Engine-Community,请在存储库中列出可用版本,然后选择并安装。

    • 列出并排序您存储库中可用的版本。此示例按版本号(从高到低)对结果进行排序。

      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
      [root@localhost software]# yum list docker-ce --showduplicates | sort -r
      * updates: ftp.sjtu.edu.cn
      This system is not registered with an entitlement server. You can use subscription-manager to register.
      : subscription-manager
      Loading mirror speeds from cached hostfile
      Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos,
      Installed Packages
      * extras: mirrors.bfsu.edu.cn
      docker-ce.x86_64 3:20.10.9-3.el7 docker-ce-stable
      docker-ce.x86_64 3:20.10.8-3.el7 docker-ce-stable
      docker-ce.x86_64 3:20.10.7-3.el7 docker-ce-stable
      ...
      docker-ce.x86_64 3:18.09.2-3.el7 docker-ce-stable
      docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable
      docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable
      docker-ce.x86_64 18.06.3.ce-3.el7 docker-ce-stable
      docker-ce.x86_64 18.06.2.ce-3.el7 docker-ce-stable
      docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable
      docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
      docker-ce.x86_64 18.03.1.ce-1.el7.centos docker-ce-stable
      ...
      * base: ftp.sjtu.edu.cn
      Available Packages


      [root@localhost software]#
  • 通过其完整的软件包名称安装特定版本,该软件包名称是软件包名称(docker-ce)加上版本字符串(第二列),从第一个冒号(:)一直到第一个连字符,并用连字符(-)分隔。例如:docker-ce-18.09.1

    1
    [root@localhost software]# yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

3. Docker启动

启动 Docker:

1
2
[root@localhost software]# sudo systemctl start docker
[root@localhost software]#

通过运行 hello-world 镜像来验证是否正确安装了 Docker Engine-Community 。

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
[root@localhost software]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:7d246653d0511db2a6b2e0436cfd0e52ac8c066000264b3ce63331ac66dca625
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/

[root@localhost software]# chkconfig docker on
Note: Forwarding request to 'systemctl enable docker.service'.
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@localhost software]#

4. Docker卸载

  1. 首先搜索已经安装的docker 安装包

    1
    2
    3
    4
    5
    6
    7
    8
    [root@localhost software]# yum list installed|grep docker
    containerd.io.x86_64 1.6.7-3.1.el7 @docker-ce-stable
    docker-ce.x86_64 3:20.10.17-3.el7 @docker-ce-stable
    docker-ce-cli.x86_64 1:20.10.17-3.el7 @docker-ce-stable
    docker-ce-rootless-extras.x86_64 20.10.17-3.el7 @docker-ce-stable
    docker-compose-plugin.x86_64 2.6.0-3.el7 @docker-ce-stable
    docker-scan-plugin.x86_64 0.17.0-3.el7 @docker-ce-stable
    [root@localhost software]#
  2. 分别删除安装包

    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    [root@localhost software]# yum -y remove docker-ce.x86_64 
    Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    Resolving Dependencies
    --> Running transaction check
    ---> Package docker-ce.x86_64 3:20.10.17-3.el7 will be erased
    --> Processing Dependency: docker-ce for package: docker-ce-rootless-extras-20.10.17-3.el7.x86_64
    --> Running transaction check
    ---> Package docker-ce-rootless-extras.x86_64 0:20.10.17-3.el7 will be erased
    --> Finished Dependency Resolution

    Dependencies Resolved

    ========================================================================================================================
    Package Arch Version Repository Size
    ========================================================================================================================
    Removing:
    docker-ce x86_64 3:20.10.17-3.el7 @docker-ce-stable 96 M
    Removing for dependencies:
    docker-ce-rootless-extras x86_64 20.10.17-3.el7 @docker-ce-stable 19 M

    Transaction Summary
    ========================================================================================================================
    Remove 1 Package (+1 Dependent package)

    Installed size: 115 M
    Downloading packages:
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
    Erasing : 3:docker-ce-20.10.17-3.el7.x86_64 1/2
    Erasing : docker-ce-rootless-extras-20.10.17-3.el7.x86_64 2/2
    Verifying : docker-ce-rootless-extras-20.10.17-3.el7.x86_64 1/2
    Verifying : 3:docker-ce-20.10.17-3.el7.x86_64 2/2

    Removed:
    docker-ce.x86_64 3:20.10.17-3.el7

    Dependency Removed:
    docker-ce-rootless-extras.x86_64 0:20.10.17-3.el7

    Complete!
    [root@localhost software]# yum -y remove docker-ce-cli.x86_64
    Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    Resolving Dependencies
    --> Running transaction check
    ---> Package docker-ce-cli.x86_64 1:20.10.17-3.el7 will be erased
    --> Processing Dependency: docker-ce-cli for package: docker-scan-plugin-0.17.0-3.el7.x86_64
    --> Running transaction check
    ---> Package docker-scan-plugin.x86_64 0:0.17.0-3.el7 will be erased
    --> Finished Dependency Resolution

    Dependencies Resolved

    ========================================================================================================================
    Package Arch Version Repository Size
    ========================================================================================================================
    Removing:
    docker-ce-cli x86_64 1:20.10.17-3.el7 @docker-ce-stable 140 M
    Removing for dependencies:
    docker-scan-plugin x86_64 0.17.0-3.el7 @docker-ce-stable 13 M

    Transaction Summary
    ========================================================================================================================
    Remove 1 Package (+1 Dependent package)

    Installed size: 153 M
    Downloading packages:
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
    Erasing : 1:docker-ce-cli-20.10.17-3.el7.x86_64 1/2
    Erasing : docker-scan-plugin-0.17.0-3.el7.x86_64 2/2
    Verifying : docker-scan-plugin-0.17.0-3.el7.x86_64 1/2
    Verifying : 1:docker-ce-cli-20.10.17-3.el7.x86_64 2/2

    Removed:
    docker-ce-cli.x86_64 1:20.10.17-3.el7

    Dependency Removed:
    docker-scan-plugin.x86_64 0:0.17.0-3.el7

    Complete!

    [root@localhost software]# yum -y remove docker-compose-plugin.x86_64
    Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    Resolving Dependencies
    --> Running transaction check
    ---> Package docker-compose-plugin.x86_64 0:2.6.0-3.el7 will be erased
    --> Finished Dependency Resolution

    Dependencies Resolved

    ========================================================================================================================
    Package Arch Version Repository Size
    ========================================================================================================================
    Removing:
    docker-compose-plugin x86_64 2.6.0-3.el7 @docker-ce-stable 25 M

    Transaction Summary
    ========================================================================================================================
    Remove 1 Package

    Installed size: 25 M
    Downloading packages:
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
    Erasing : docker-compose-plugin-2.6.0-3.el7.x86_64 1/1
    Verifying : docker-compose-plugin-2.6.0-3.el7.x86_64 1/1

    Removed:
    docker-compose-plugin.x86_64 0:2.6.0-3.el7

    Complete!

    [root@localhost software]# yum -y remove containerd.io.x86_64
    Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    Resolving Dependencies
    --> Running transaction check
    ---> Package containerd.io.x86_64 0:1.6.7-3.1.el7 will be erased
    --> Finished Dependency Resolution

    Dependencies Resolved

    ========================================================================================================================
    Package Arch Version Repository Size
    ========================================================================================================================
    Removing:
    containerd.io x86_64 1.6.7-3.1.el7 @docker-ce-stable 125 M

    Transaction Summary
    ========================================================================================================================
    Remove 1 Package

    Installed size: 125 M
    Downloading packages:
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
    Erasing : containerd.io-1.6.7-3.1.el7.x86_64 1/1
    Verifying : containerd.io-1.6.7-3.1.el7.x86_64 1/1

    Removed:
    containerd.io.x86_64 0:1.6.7-3.1.el7

    Complete!
    [root@localhost software]#
  3. 删除docker 镜像

    1
    2
    [root@localhost software]# rm -rf /var/lib/docker
    [root@localhost software]#
  4. 再次check docker是否已经卸载成功

    1
    2
    [root@localhost software]# yum list installed|grep docker 
    [root@localhost software]#

    如果没有,就表示卸载成功。

四、Docker使用

1. Docker Hello World

Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。输出Hello world

1
2
3
[root@localhost software]# docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world
[root@localhost software]#

各个参数解析:

  • docker: Docker 的二进制执行文件。
  • run: 与前面的 docker 组合来运行一个容器。
  • ubuntu:15.10 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
  • /bin/echo “Hello world”: 在启动的容器里执行的命令

以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果。

1.1 运行交互式的容器

通过 docker 的两个参数 -i -t,让 docker 运行的容器实现“对话”的能力:

1
2
[root@localhost software]# docker run -i -t ubuntu:15.10 /bin/bash
root@ed4a85705ff3:/#

各个参数解析:

  • -t: 在新容器内指定一个伪终端或终端。
  • -i: 允许你对容器内的标准输入 (STDIN) 进行交互。

注意第二行 root@ed4a85705ff3:/#,此时我们已进入一个 ubuntu15.10 系统的容器

我们尝试在容器中运行命令 cat /proc/versionls分别查看当前系统的版本信息和当前目录下的文件列表

1
2
3
4
5
root@ed4a85705ff3:/# cat /proc/version
Linux version 3.10.0-862.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) ) #1 SMP Fri Apr 20 16:44:24 UTC 2018
root@ed4a85705ff3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@ed4a85705ff3:/#

可以通过运行 exit 命令或者使用 CTRL+D 来退出容器。

1
2
3
root@ed4a85705ff3:/# exit
exit
[root@localhost software]#

注意第三行中 [root@localhost software]# 表明我们已经退出了当前的容器,返回到当前的主机中。

1.2 启动容器(后台模式)

创建一个以进程方式运行的容器:

1
2
3
[root@localhost software]# docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
f8f69699ea5ee423c804656040a2512541dc1503320a19c573c5bf9a29bfb0a0
[root@localhost software]#

在输出中,我们没有看到期望的 hello world,而是一串长字符

f8f69699ea5ee423c804656040a2512541dc1503320a19c573c5bf9a29bfb0a0

这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。

首先,我们需要确认容器有在运行,可以通过 docker ps 来查看:

1
2
3
4
[root@localhost software]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8f69699ea5e ubuntu:15.10 "/bin/sh -c 'while t…" 59 seconds ago Up 58 seconds reverent_rubin
[root@localhost software]#

输出详情介绍:

  • CONTAINER ID: 容器 ID。

  • IMAGE: 使用的镜像。

  • COMMAND: 启动容器时运行的命令。

  • CREATED: 容器的创建时间。

  • STATUS: 容器状态。状态有7种:

    • created(已创建)

    • restarting(重启中)

    • running 或 Up(运行中)

    • removing(迁移中)

    • paused(暂停)

    • exited(停止)

    • dead(死亡)

  • PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。

  • NAMES: 自动分配的容器名称。

在宿主主机内使用 docker logs 命令,查看容器内的标准输出:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost software]# docker logs f8f69699ea5e
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
...

1.3 停止容器

使用 docker stop 命令来停止容器:

1
2
3
[root@localhost software]# docker stop f8f69699ea5e
f8f69699ea5e
[root@localhost software]#

通过 docker ps 查看,容器已经停止工作:

1
2
3
[root@localhost software]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost software]#

可以看到容器已经不在了。

也可以用下面的命令来停止:

1
2
3
[root@localhost software]# docker stop reverent_rubin
reverent_rubin
[root@localhost software]#

2. Docker容器使用

2.1 Docker 客户端

docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 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
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
[root@localhost software]# docker

Usage: docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
--config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and
default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit

Management Commands:
app* Docker App (Docker Inc., v0.9.1-beta3)
builder Manage builds
buildx* Docker Buildx (Docker Inc., v0.8.2-docker)
config Manage Docker configs
container Manage containers
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
scan* Docker Scan (Docker Inc., v0.17.0)
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes

Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

To get more help with docker, check out our guides at https://docs.docker.com/go/guides/
[root@localhost software]#

可以通过命令docker command --help 更深入的了解指定的 Docker 命令使用方法。

例如我们要查看 docker stats 指令的具体使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost software]# docker stats --help

Usage: docker stats [OPTIONS] [CONTAINER...]

Display a live stream of container(s) resource usage statistics

Options:
-a, --all Show all containers (default shows just running)
--format string Pretty-print images using a Go template
--no-stream Disable streaming stats and only pull the first result
--no-trunc Do not truncate output
[root@localhost software]#

2.2 容器使用

2.2.1 获取镜像

如果本地没有 ubuntu 镜像,可以使用 docker pull 命令来载入 ubuntu 镜像:

1
2
3
4
5
6
7
8
[root@localhost software]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
d19f32bd9e41: Pull complete
Digest: sha256:34fea4f31bf187bc915536831fd0afc9d214755bf700b5cdb1336c82516d154e
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
[root@localhost software]#

2.2.2 启动容器

以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器:

1
2
[root@localhost software]# docker run -it ubuntu /bin/bash
root@5358c9601c75:/#

参数说明:

  • -i: 交互式操作。
  • -t: 终端。
  • ubuntu: ubuntu 镜像。
  • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

要退出终端,直接输入 exit:

1
2
3
root@5358c9601c75:/# exit
exit
[root@localhost software]#

2.2.3 启动已停止运行的容器

查看所有的容器命令如下:

1
2
3
4
[root@localhost software]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5358c9601c75 ubuntu "/bin/bash" About a minute ago Exited (0) About a minute ago
[root@localhost software]#

使用 docker start 启动一个已停止的容器:

1
2
3
[root@localhost software]# docker start 5358c9601c75
5358c9601c75
[root@localhost software]#

2.2.4 后台运行

在大部分的场景下,希望 docker 的服务是在后台运行的,可以过 -d 指定容器的运行模式。

1
2
3
4
5
6
7
[root@localhost software]# docker run -itd --name ubuntu-test ubuntu /bin/bash
c293ba3fecac5d8f833bec90aca18670ba253fa0af7f7697990c9b8933902c23
[root@localhost software]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c293ba3fecac ubuntu "/bin/bash" 23 seconds ago Up 22 seconds ubuntu-test
5358c9601c75 ubuntu "/bin/bash" 4 minutes ago Up About a minute lucid_austin
[root@localhost software]#

注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec(下面会介绍到)。

2.2.5 停止一个容器

停止容器的命令如下:

1
2
3
[root@localhost software]# docker stop c293ba3fecac
c293ba3fecac
[root@localhost software]#

停止的容器可以通过 docker restart 重启:

1
2
3
[root@localhost software]# docker restart c293ba3fecac
c293ba3fecac
[root@localhost software]#

2.2.6 进入容器

在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:

  • docker attach

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@localhost software]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    c293ba3fecac ubuntu "/bin/bash" 5 minutes ago Up 1 second ubuntu-test
    [root@localhost software]# docker attach c293ba3fecac
    root@c293ba3fecac:/# exit
    exit
    [root@localhost software]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    [root@localhost software]#

    注意: 如果从这个容器退出,会导致容器的停止。

  • docker exec:推荐大家使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@localhost software]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    c293ba3fecac ubuntu "/bin/bash" 6 minutes ago Up 3 seconds ubuntu-test
    [root@localhost software]# docker exec -it c293ba3fecac /bin/bash
    root@c293ba3fecac:/# exit
    exit
    [root@localhost software]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    c293ba3fecac ubuntu "/bin/bash" 6 minutes ago Up 18 seconds ubuntu-test
    [root@localhost software]#

    注意: 如果从这个容器退出,容器不会停止,这就是为什么推荐大家使用 docker exec 的原因。

    更多参数说明请使用 docker exec —help 命令查看。

2.2.7 导出、导入容器和删除容器

  1. 导出容器

    如果要导出本地某个容器,可以使用 docker export 命令。

    1
    2
    3
    [root@localhost software]# cd DDocker/
    [root@localhost DDocker]# docker export c293ba3fecac > ./ubuntu.tar
    [root@localhost DDocker]#

    导出容器 c293ba3fecac 快照到本地文件 ubuntu.tar。

    1
    2
    3
    4
    [root@localhost DDocker]# ll ./
    total 78476
    -rw-r--r--. 1 root root 80356864 Aug 15 03:15 ubuntu.tar
    [root@localhost DDocker]#

    这样将导出容器快照到本地文件。

  2. 导入容器快照

    可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:

    1
    2
    3
    4
    5
    6
    7
    8
    [root@localhost DDocker]# cat ./ubuntu.tar | docker import - test/ubuntu:v1
    sha256:c46e9fe3434edee953f9dd9fe8d1a2351dba59c0abd6e4510055e3b39995b9aa
    [root@localhost DDocker]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    test/ubuntu v1 c46e9fe3434e 5 seconds ago 77.8MB
    ubuntu latest df5de72bdb3b 2 weeks ago 77.8MB
    ubuntu 15.10 9b9cb95443b5 6 years ago 137MB
    [root@localhost DDocker]#

    此外,也可以通过指定 URL 或者某个目录来导入,例如:

    1
    docker import 链接地址 example/imagerepo
  3. 删除容器

    删除容器使用 docker rm 命令:

    1
    2
    3
    4
    5
    6
    7
    8
    [root@localhost DDocker]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    c293ba3fecac ubuntu "/bin/bash" 3 days ago Up 3 days ubuntu-test
    [root@localhost DDocker]# docker rm -f c293ba3fecac
    c293ba3fecac
    [root@localhost DDocker]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    [root@localhost DDocker]#
  4. 清理掉所有处于终止状态的容器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [root@localhost DDocker]# docker container prune
    WARNING! This will remove all stopped containers.
    Are you sure you want to continue? [y/N] y
    Deleted Containers:
    5358c9601c75ab8b25844441696287320cad518773d558e5ba506274e8e933c0
    f8f69699ea5ee423c804656040a2512541dc1503320a19c573c5bf9a29bfb0a0
    ed4a85705ff3bdc89fae2c8464033dcc3e6d712a3bcdeec9a206a934f7b9e566
    c19a6c0f44d983b5fc42999acc8e344669e4e5cd5a3e95a288a76f2a9c3e716f
    09a8c4e0a0ee2301d3b783fd326a9819ca39b94c6d891738ce1a760d4a1ca3fc
    ef0d5fdfe2791b92c8352e46d7e4c3bf226c555b097abc9f6ccdeec56bc59cbb

    Total reclaimed space: 31B
    [root@localhost DDocker]#

2.3 Docker 简单Web实例

2.3.1 运行一个 web 应用

前面运行的容器并没有一些什么特别的用处。

接下来让尝试使用 docker 构建一个 web 应用程序。在docker容器中运行一个 Python Flask 应用来运行一个web应用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost DDocker]# docker pull training/webapp  # 载入镜像
Using default tag: latest
latest: Pulling from training/webapp
Image docker.io/training/webapp:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
e190868d63f8: Pull complete
909cd34c6fd7: Pull complete
0b9bfabab7c1: Pull complete
a3ed95caeb02: Pull complete
10bbbc0fc0ff: Pull complete
fca59b508e9f: Pull complete
e7ae2541b15b: Pull complete
9dd97ef58ce9: Pull complete
a4c1b0cb7af7: Pull complete
Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d
Status: Downloaded newer image for training/webapp:latest
docker.io/training/webapp:latest
[root@localhost DDocker]# docker run -d -P training/webapp python app.py
5d69665d500ef470659f02a6fa4a5c36707b67ec552a6797b3efbf79d82797b3
[root@localhost DDocker]#

参数说明:

  • -d:让容器在后台运行。
  • -P:将容器内部使用的网络端口随机映射到我们使用的主机上。

2.3.2 查看 WEB 应用容器

1
2
3
4
[root@localhost DDocker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d69665d500e training/webapp "python app.py" 2 minutes ago Up 2 minutes 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp jovial_kilby
[root@localhost DDocker]#

这里多了端口信息 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp

Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 49153上。

这时我们可以通过浏览器访问WEB应用

也可以通过 -p 参数来设置不一样的端口:

1
2
3
4
5
6
7
[root@localhost DDocker]# docker run -d -p 5000:5000 training/webapp python app.py
0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89
[root@localhost DDocker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a217a11c448 training/webapp "python app.py" 12 seconds ago Up 11 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp awesome_tharp
5d69665d500e training/webapp "python app.py" 23 hours ago Up 23 hours 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp jovial_kilby
[root@localhost DDocker]#

2.3.3 网络端口的快捷方式

通过 docker ps 命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 docker port,使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。

上面创建的 web 应用容器 ID 为 0a217a11c448 名字为 awesome_tharp

我可以使用 docker port 0a217a11c448docker port awesome_tharp 来查看容器端口的映射情况。

1
2
3
4
5
6
7
[root@localhost DDocker]# docker port 0a217a11c448
5000/tcp -> 0.0.0.0:5000
5000/tcp -> :::5000
[root@localhost DDocker]# docker port awesome_tharp
5000/tcp -> 0.0.0.0:5000
5000/tcp -> :::5000
[root@localhost DDocker]#

2.3.4 查看Web应用程序日志

docker logs [ID或者名字] 可以查看容器内部的标准输出。

1
2
3
4
5
[root@localhost DDocker]# docker logs -f 0a217a11c448
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.48.1 - - [19/Aug/2022 08:54:01] "GET / HTTP/1.1" 200 -
192.168.48.1 - - [19/Aug/2022 08:54:01] "GET /favicon.ico HTTP/1.1" 404 -
192.168.48.1 - - [19/Aug/2022 08:54:03] "GET / HTTP/1.1" 200 -

参数说明:

  • -f:docker logs 像使用 tail -f 一样来输出容器内部的标准输出。

从上面,可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。

2.3.5 查看Web应用程序容器的进程

使用 docker top 来查看容器内部运行的进程:

1
2
3
4
[root@localhost DDocker]# docker top awesome_tharp
UID PID PPID C STIME TTY TIME CMD
root 12634 12612 0 01:52 ? 00:00:00 python app.py
[root@localhost DDocker]#

2.3.6 检查Web应用程序

使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 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
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
[root@localhost DDocker]# docker inspect awesome_tharp 
[
{
"Id": "0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89",
"Created": "2022-08-19T08:52:59.445311998Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 12634,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-08-19T08:53:00.035220635Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557",
"ResolvConfPath": "/var/lib/docker/containers/0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89/hostname",
"HostsPath": "/var/lib/docker/containers/0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89/hosts",
"LogPath": "/var/lib/docker/containers/0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89/0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89-json.log",
"Name": "/awesome_tharp",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"5000/tcp": [
{
"HostIp": "",
"HostPort": "5000"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/b297f5b6a2089c75af5d4a466b7d28760a309fd8d8038868d1c37552acf62393-init/diff:/var/lib/docker/overlay2/7154389c17280fdf4962246ab3dd248579bb536c13b07fe327bd8ec65ff36add/diff:/var/lib/docker/overlay2/711961c1287a9e045b7caa18fa4cf6d21e186a0fa80126905d2e832f27573bf5/diff:/var/lib/docker/overlay2/a57c52470deecd88547bc5d03c7418e7b88add1a22c61e49c62595219d46e368/diff:/var/lib/docker/overlay2/e4a2c8c9702b9cd21534ee77f134332c54a575036e3f6eb7d7d12e38f211d4a5/diff:/var/lib/docker/overlay2/f5eeb64487fcce01056ae15c28c4e1637d12fb6b518bcfa8c3e87452ab746939/diff:/var/lib/docker/overlay2/1f4882c84fd6fceab9f1063362906839f858f5ed07237f34e2fde4dea7d3b9ed/diff:/var/lib/docker/overlay2/e8b89880d7223d3a9ba8a4cc46d4b887b6ec33f4653bd0472d69516c6fac471b/diff:/var/lib/docker/overlay2/6e1d3528d9bb72efa226ba8631eab7ff7405d92c5f8d13825aec7de0a9c4b7a4/diff:/var/lib/docker/overlay2/d9b6e6af59f120800c9f332210dfe279ceeeb66bb6056496538d8e269470ad3b/diff:/var/lib/docker/overlay2/5861193f780069a9c6f8230a7d667941e5721b07f2c5313e320766288367913d/diff:/var/lib/docker/overlay2/306fcd234e922e52fdd1ce6aa7afc5013d430041f60a9451c3982be7b3251018/diff:/var/lib/docker/overlay2/d7e5fb7ae7525868dca45d5b61405e2f4008d88979c70c8f59ce8c117d77e42d/diff:/var/lib/docker/overlay2/574a21f740852a28afd807db044d9049e524be22450475138cb598a720038cbb/diff",
"MergedDir": "/var/lib/docker/overlay2/b297f5b6a2089c75af5d4a466b7d28760a309fd8d8038868d1c37552acf62393/merged",
"UpperDir": "/var/lib/docker/overlay2/b297f5b6a2089c75af5d4a466b7d28760a309fd8d8038868d1c37552acf62393/diff",
"WorkDir": "/var/lib/docker/overlay2/b297f5b6a2089c75af5d4a466b7d28760a309fd8d8038868d1c37552acf62393/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "0a217a11c448",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"5000/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"python",
"app.py"
],
"Image": "training/webapp",
"Volumes": null,
"WorkingDir": "/opt/webapp",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "6489190fa50b7e3fbe25a49a039250da0042155719bf3e455038399ab6e61f3a",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"5000/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "5000"
},
{
"HostIp": "::",
"HostPort": "5000"
}
]
},
"SandboxKey": "/var/run/docker/netns/6489190fa50b",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "adbdf001a02ad9946a1b5df84a5e0d8bc2ec9e6dea316dc62ebaa714954bd423",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "1df9775fe6801665441fb8dcde4fe10916578f316c83e1d3fa234ac473a433a6",
"EndpointID": "adbdf001a02ad9946a1b5df84a5e0d8bc2ec9e6dea316dc62ebaa714954bd423",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
[root@localhost DDocker]#

2.3.7 停止Web应用程序

1
2
3
[root@localhost DDocker]# docker stop awesome_tharp 
awesome_tharp
[root@localhost DDocker]#

2.3.8 重启Web应用容器

已经停止的容器,可以使用命令 docker start 来启动。

1
2
3
[root@localhost DDocker]# docker start awesome_tharp 
awesome_tharp
[root@localhost DDocker]#

docker ps -l 查询最后一次创建的容器:

1
2
3
4
[root@localhost DDocker]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a217a11c448 training/webapp "python app.py" About an hour ago Up 45 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp awesome_tharp
[root@localhost DDocker]#

正在运行的容器,我们可以使用 docker restart 命令来重启。

1
2
3
[root@localhost DDocker]# docker restart awesome_tharp 
awesome_tharp
[root@localhost DDocker]#

2.3.9 移除Web应用容器

使用 docker rm 命令来删除不需要的容器:

1
2
3
4
5
[root@localhost DDocker]# docker stop awesome_tharp
awesome_tharp
[root@localhost DDocker]# docker rm awesome_tharp
awesome_tharp
[root@localhost DDocker]#

除容器时,容器必须是停止状态,否则会报如下错误:

1
2
3
[root@localhost DDocker]# docker rm awesome_tharp
Error response from daemon: You cannot remove a running container 0a217a11c448cbe6e2223ddbe6dd09aeb883ad9614ce8050f12cb040c1399e89. Stop the container before attempting removal or force remove
[root@localhost DDocker]#

3. Docker镜像使用

当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。

3.1 列出镜像列表

使用 docker images 来列出本地主机上的镜像。

1
2
3
4
5
6
7
8
[root@localhost DDocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/ubuntu v1 c46e9fe3434e 3 days ago 77.8MB
ubuntu latest df5de72bdb3b 2 weeks ago 77.8MB
ubuntu 18.04 8d5df41c547b 2 weeks ago 63.1MB
ubuntu 15.10 9b9cb95443b5 6 years ago 137MB
training/webapp latest 6fae60ef3446 7 years ago 349MB
[root@localhost DDocker]#

各个选项说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.1018.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

所以,如果要使用版本为15.10ubuntu系统镜像来运行容器时,命令如下:

1
2
[root@localhost DDocker]# docker run -t -i ubuntu:15.10 /bin/bash
root@4494c4d76bef:/#

参数说明:

  • -i: 交互式操作。
  • -t: 终端。
  • ubuntu:15.10: 这是指用 ubuntu 15.10 版本镜像为基础来启动容器。
  • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

如果要使用版本为 18.04 的 ubuntu 系统镜像来运行容器时,命令如下:

1
2
[root@localhost DDocker]# docker run -t -i ubuntu:18.04 /bin/bash
root@d25c29d78f45:/#

如果不指定一个镜像的版本标签,例如只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。

3.2 获取一个新的镜像

当在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果想预先下载这个镜像,可以使用 docker pull 命令来下载它。

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost DDocker]# docker pull ubuntu:13.10
13.10: Pulling from library/ubuntu
Image docker.io/library/ubuntu:13.10 uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
a3ed95caeb02: Pull complete
0d8710fc57fd: Pull complete
5037c5cd623d: Pull complete
83b53423b49f: Pull complete
e9e8bd3b94ab: Pull complete
7db00e6b6e5e: Pull complete
Digest: sha256:403105e61e2d540187da20d837b6a6e92efc3eb4337da9c04c191fb5e28c44dc
Status: Downloaded newer image for ubuntu:13.10
docker.io/library/ubuntu:13.10
[root@localhost DDocker]#

下载完成后,可以直接使用这个镜像来运行容器。

3.3 查找镜像

可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/

也可以使用 docker search 命令来搜索镜像。比如需要一个 httpd 的镜像来作为web 服务。可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。

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 DDocker]# docker search httpd
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
httpd The Apache HTTP Server Project 4121 [OK]
centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 44
centos/httpd 35 [OK]
hypoport/httpd-cgi httpd-cgi 2 [OK]
clearlinux/httpd httpd HyperText Transfer Protocol (HTTP) ser… 2
solsson/httpd-openidc mod_auth_openidc on official httpd image, ve… 2 [OK]
nnasaki/httpd-ssi SSI enabled Apache 2.4 on Alpine Linux 1
dockerpinata/httpd 1
centos/httpd-24-centos8 1
lead4good/httpd-fpm httpd server which connects via fcgi proxy h1 [OK]
inanimate/httpd-ssl A play container with httpd, ssl enabled, an… 1 [OK]
dariko/httpd-rproxy-ldap Apache httpd reverse proxy with LDAP authent… 1 [OK]
manageiq/httpd Container with httpd, built on CentOS for Ma… 1 [OK]
publici/httpd httpd:latest 1 [OK]
httpdocker/kubia 0
patrickha/httpd-err 0
manageiq/httpd_configmap_generator Httpd Configmap Generator 0 [OK]
amd64/httpd The Apache HTTP Server Project 0
manasip/httpd 0
httpdss/archerysec ArcherySec repository 0 [OK]
e2eteam/httpd 0
sandeep1988/httpd-new httpd-new 0
paketobuildpacks/httpd 0
19022021/httpd-connection_test This httpd image will test the connectivity … 0
sherazahmedvaival/httpd-php-fpm74 0
[root@localhost DDocker]#

参数说明:

  • NAME: 镜像仓库源的名称

  • DESCRIPTION: 镜像的描述

  • OFFICIAL: 是否 docker 官方发布

  • stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。

  • AUTOMATED: 自动构建。

3.4 拖取镜像

决定使用上图中的httpd 官方版本的镜像,使用命令 docker pull 来下载镜像。

1
2
3
4
5
6
7
8
9
10
[root@localhost DDocker]# docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
1efc276f4ff9: Downloading [==================================================>] 31.37MB/31.37MB
aed046121ed8: Download complete
4340e7be3d7f: Download complete
80e368ef21fc: Download complete
80cb79a80bbe: Download complete
write /var/lib/docker/tmp/GetImageBlob1509640261: no space left on device
[root@localhost DDocker]#

下载完成后,就可以使用这个镜像了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost docker]# docker run httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
1efc276f4ff9: Pull complete
aed046121ed8: Pull complete
4340e7be3d7f: Pull complete
80e368ef21fc: Pull complete
80cb79a80bbe: Pull complete
Digest: sha256:343452ec820a5d59eb3ab9aaa6201d193f91c3354f8c4f29705796d9353d4cc6
Status: Downloaded newer image for httpd:latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Mon Aug 22 06:29:11.880882 2022] [mpm_event:notice] [pid 1:tid 140442894695744] AH00489: Apache/2.4.54 (Unix) configured -- resuming normal operations
[Mon Aug 22 06:29:11.881094 2022] [core:notice] [pid 1:tid 140442894695744] AH00094: Command line: 'httpd -D FOREGROUND'

3.5 删除镜像

镜像删除使用docker rmi 命令,比如删除hello-world 镜像:

1
2
3
4
5
6
[root@localhost docker]# docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:7d246653d0511db2a6b2e0436cfd0e52ac8c066000264b3ce63331ac66dca625
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359
[root@localhost docker]#

3.6 创建镜像

当从 docker 镜像仓库中下载的镜像不能满足需求时,可以通过以下方式对镜像进行更改。

3.6.1 更新镜像

从已经创建的容器中更新镜像,并且提交这个镜像。

更新镜像之前,需要使用镜像来创建一个容器。

1
2
[root@localhost software]# docker run -t -i ubuntu:18.04 /bin/bash
root@5a156e79af57:/#

在运行的容器内使用 apt-get update 命令进行更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@5a156e79af57:/# apt-get update
Ign:1 http://mirrors.163.com/debian jessie InRelease
Ign:2 http://mirrors.163.com/debian jessie-proposed-updates InRelease
Get:3 http://mirrors.163.com/debian jessie Release [77.3 kB]
Hit:4 http://archive.ubuntu.com/ubuntu bionic InRelease
Err:5 http://mirrors.163.com/debian jessie-proposed-updates Release
404 Not Found [IP: 60.191.80.11 80]
Get:6 http://mirrors.163.com/debian jessie Release.gpg [1652 B]
Hit:7 http://archive.ubuntu.com/ubuntu bionic-updates InRelease
Hit:8 http://security.ubuntu.com/ubuntu bionic-security InRelease
Ign:6 http://mirrors.163.com/debian jessie Release.gpg
Hit:9 http://archive.ubuntu.com/ubuntu bionic-backports InRelease
Reading package lists... Done
E: The repository 'http://mirrors.163.com/debian jessie-proposed-updates Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
W: GPG error: http://mirrors.163.com/debian jessie Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 7638D0442B90D010 NO_PUBKEY CBF8D6FD518E17E1
E: The repository 'http://mirrors.163.com/debian jessie Release' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
root@5a156e79af57:/#
  1. 问题阐述:

    在运行的容器内使用 apt-get update 命令进行更新时,发下很多404错误。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    root@5a156e79af57:/# apt-get update 
    Ign http://archive.ubuntu.com wily InRelease
    Ign http://archive.ubuntu.com wily-updates InRelease
    Ign http://archive.ubuntu.com wily-security InRelease
    Ign http://archive.ubuntu.com wily Release.gpg
    Ign http://archive.ubuntu.com wily-updates Release.gpg
    Ign http://archive.ubuntu.com wily-security Release.gpg
    Ign http://archive.ubuntu.com wily Release
    Ign http://archive.ubuntu.com wily-updates Release
    Ign http://archive.ubuntu.com wily-security Release
    Err http://archive.ubuntu.com wily/main Sources
    404 Not Found [IP: 91.189.91.39 80]
    Err http://archive.ubuntu.com wily/restricted Sources
    404 Not Found [IP: 91.189.91.39 80]
    ...
    W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/wily-security/universe/binary-amd64/Packages 404 Not Found [IP: 91.189.91.39 80]

    E: Some index files failed to download. They have been ignored, or old ones used instead.
    root@5a156e79af57:/#
  2. 问题解决:

    经查,每一个Ubuntu发布版本都有它的结束时间,通常,Ubuntu发布版本支持18个月,而LTS (Long Term Support)(长期支持)版本分别支持3年(服务器版)和5年(桌面版)。

    当一个Ubuntu发布版本到达结束期后,它的库将不再能够访问,并且你也不会得到任何维护更新和安全补丁。当写这个的时候,我的15.10版本已经到了它的结束期了。
    对于那些使用旧版本的Ubuntu的用户,这是一个过期库的归档。因此,Ubuntu过期后,我们必须把源切换到 old-releases.ubuntu.com。

    下面的方法通过切换到旧版本的源来解决“404 Not Found”错误。

    首先,使用旧版本的源来替换当前主源

    1
    2
    3
    4
    5
    6
    7
    8
    root@5a156e79af57:/# cat <<eof> /etc/apt/sources.list
    > deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
    > deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
    > deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
    > deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
    > deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
    > eof
    root@5a156e79af57:/#

    现在,应该能够在旧版本的Ubuntu镜像系统上进行安装或者更新了

    1
    2
    3
    root@5a156e79af57:/# apt-get update
    ......
    root@5a156e79af57:/# apt-get install vim
  3. 更换国内镜像

    打开网站https://mirrors.tuna.tsinghua.edu.cn/

    找到ubuntu后面的问号,点击跳转后,有对应的设置方法

    1
    2
    3
    4
    root@94a33576bd1b:/# sed -i "s@http://.*archive.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list

    root@94a33576bd1b:/# sed -i "s@http://.*security.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list
    root@94a33576bd1b:/#

在完成操作之后,输入 exit 命令来退出这个容器。

此时 ID 为 94a33576bd1b 的容器,是按需求更改的容器。可以通过命令 docker commit 来提交容器副本。

1
2
3
[root@localhost software]# docker commit -m "has update" -a="yanpenggong" 94a33576bd1b yanpenggong/ubuntu:v2
sha256:e0a0ea0b15174c6f322a806ca08f11c316b4f878c01689a807c950f3447b840b
[root@localhost software]#

各个参数说明:

  • -m: 提交的描述信息
  • -a: 指定镜像作者
  • e218edb10161:容器 ID
  • runoob/ubuntu:v2: 指定要创建的目标镜像名

我们可以使用 docker images 命令来查看我们的新镜像 yanpenggong/ubuntu:v2

1
2
3
4
5
6
[root@localhost software]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
yanpenggong/ubuntu v2 e0a0ea0b1517 46 seconds ago 99.3MB
httpd latest f2a976f932ec 2 weeks ago 145MB
ubuntu 18.04 8d5df41c547b 2 weeks ago 63.1MB
[root@localhost software]#

使用我们的新镜像 yanpenggong/ubuntu 来启动一个容器:

1
2
[root@localhost software]# docker run -t -i yanpenggong/ubuntu:v2 /bin/bash
root@4cd6ec171b77:/#

3.6.2 构建镜像

使用 Dockerfile 指令来创建一个新的镜像

使用命令 docker build, 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建镜像。

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost DDocker]# cat Dockerfile 
FROM centos:6.7
MAINTAINER yanpenggong "yanpenggong@163.com"

RUN /bin/echo "root:yanpenggong" | chpasswd
RUN useradd yanpenggong
RUN /bin/echo "yanpenggong:yanpenggong" | chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" > /etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
[root@localhost DDocker]#

每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。

第一条FROM,指定使用哪个镜像源,RUN 指令告诉docker 在镜像内执行命令,安装了什么。

参数说明:

  • FROM:构建镜像基于哪个镜像
  • MAINTAINER:镜像维护者姓名或邮箱地址
  • RUN:构建镜像时运行的指令
  • CMD:运行容器时执行的shell环境
  • VOLUME:指定容器挂载点到宿主机自动生成的目录或其他容器
  • USER:为RUN、CMD、和 ENTRYPOINT 执行命令指定运行用户
  • WORKDIR:为 RUN、CMD、ENTRYPOINT、COPY 和 ADD 设置工作目录,就是切换目录
  • HEALTHCHECH:健康检查
  • ARG:构建时指定的一些参数
  • EXPOSE:声明容器的服务端口(仅仅是声明)
  • ENV:设置容器环境变量
  • ADD:拷贝文件或目录到容器中,如果是URL或压缩包便会自动下载或自动解压
  • COPY:拷贝文件或目录到容器中,跟ADD类似,但不具备自动下载或解压的功能
  • ENTRYPOINT:运行容器时执行的shell命令

然后,使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。

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
[root@localhost DDocker]# docker build -t yanpenggong/centos:6.7 .
Sending build context to Docker daemon 80.36MB
Step 1/9 : FROM centos:6.7
6.7: Pulling from library/centos
cbddbc0189a0: Pull complete
Digest: sha256:4c952fc7d30ed134109c769387313ab864711d1bd8b4660017f9d27243622df1
Status: Downloaded newer image for centos:6.7
---> 9f1de3c6ad53
Step 2/9 : MAINTAINER yanpenggong "yanpenggong@163.com"
---> Running in f2ceecd3f084
Removing intermediate container f2ceecd3f084
---> 94858bb3d4ef
Step 3/9 : RUN /bin/echo "root:yanpenggong" | chpasswd
---> Running in 425b7bfbb037
Removing intermediate container 425b7bfbb037
---> 1c9059ca47f8
Step 4/9 : RUN useradd yanpenggong
---> Running in 03fc22eb515b
Removing intermediate container 03fc22eb515b
---> 27028b46ae31
Step 5/9 : RUN /bin/echo "yanpenggong:yanpenggong" | chpasswd
---> Running in e8ad081c0835
Removing intermediate container e8ad081c0835
---> 06533911be02
Step 6/9 : RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" > /etc/default/local
---> Running in ea73216a2abc
Removing intermediate container ea73216a2abc
---> a09cf5c5f9a1
Step 7/9 : EXPOSE 22
---> Running in 2090bcdb357b
Removing intermediate container 2090bcdb357b
---> d7c5685a04ce
Step 8/9 : EXPOSE 80
---> Running in 09b19ed81af5
Removing intermediate container 09b19ed81af5
---> 5acf09136b6b
Step 9/9 : CMD /usr/sbin/sshd -D
---> Running in 514a034e0a13
Removing intermediate container 514a034e0a13
---> d791216a0356
Successfully built d791216a0356
Successfully tagged yanpenggong/centos:6.7
[root@localhost DDocker]#

参数说明:

  • -t :指定要创建的目标镜像名
  • . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径

使用docker images 查看创建的镜像已经在列表中存在,镜像ID为d791216a0356

1
2
3
4
5
6
7
8
[root@localhost DDocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
yanpenggong/centos 6.7 d791216a0356 48 seconds ago 191MB
yanpenggong/ubuntu v2 e0a0ea0b1517 56 minutes ago 99.3MB
httpd latest f2a976f932ec 2 weeks ago 145MB
ubuntu 18.04 8d5df41c547b 2 weeks ago 63.1MB
centos 6.7 9f1de3c6ad53 3 years ago 191MB
[root@localhost DDocker]#

使用新的镜像来创建容器:

1
2
3
4
[root@localhost DDocker]# docker run -it yanpenggong/centos:6.7 /bin/bash
[root@666f0af44d9c /]# id yanpenggong
uid=500(yanpenggong) gid=500(yanpenggong) groups=500(yanpenggong)
[root@666f0af44d9c /]#

从上面看到新镜像已经包含我们创建的用户 yanpenggong

3.6.3 设置镜像标签

使用 docker tag 命令,为镜像添加一个新的标签。

1
2
[root@localhost DDocker]# docker tag d791216a0356 yanpenggong/centos:dev
[root@localhost DDocker]#

docker tag 镜像ID,这里是 d791216a0356 ,用户名称、镜像源名(repository name)和新的标签名(tag)。

使用 docker images 命令可以看到,ID为d791216a0356的镜像多一个标签。

1
2
3
4
5
6
7
8
9
[root@localhost DDocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
yanpenggong/centos 6.7 d791216a0356 6 minutes ago 191MB
yanpenggong/centos dev d791216a0356 6 minutes ago 191MB
yanpenggong/ubuntu v2 e0a0ea0b1517 About an hour ago 99.3MB
httpd latest f2a976f932ec 2 weeks ago 145MB
ubuntu 18.04 8d5df41c547b 2 weeks ago 63.1MB
centos 6.7 9f1de3c6ad53 3 years ago 191MB
[root@localhost DDocker]#

4. Docker容器连接

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P-p 参数来指定端口映射。

下面我们来实现通过端口连接到一个 docker 容器。

4.1 网络端口映射

创建了一个 python 应用的容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost DDocker]# docker run -d -P training/webapp python app.py
Unable to find image 'training/webapp:latest' locally
latest: Pulling from training/webapp
Image docker.io/training/webapp:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
e190868d63f8: Pull complete
909cd34c6fd7: Pull complete
0b9bfabab7c1: Pull complete
a3ed95caeb02: Pull complete
10bbbc0fc0ff: Pull complete
fca59b508e9f: Pull complete
e7ae2541b15b: Pull complete
9dd97ef58ce9: Pull complete
a4c1b0cb7af7: Pull complete
Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d
Status: Downloaded newer image for training/webapp:latest
949ba9ad02954210132ff41d52c4d402031a4b87647a62be458cec17ee2a1fc5
[root@localhost DDocker]#

另外,可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

使用 -P 绑定端口号,使用 docker ps 可以看到容器端口 5000 绑定主机端口 49153。

1
2
3
4
[root@localhost DDocker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
949ba9ad0295 training/webapp "python app.py" 9 seconds ago Up 8 seconds 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp hopeful_darwin
[root@localhost DDocker]#

也可以使用 -p 标识来指定容器端口绑定到主机端口。

两种方式的区别是:

  • -P : [大写],是容器内部端口随机映射到主机的端口。
  • -p : [小写],是容器内部端口绑定到指定的主机端口。
1
2
3
4
5
6
7
[root@localhost DDocker]# docker run -d -p 5000:5000 training/webapp python app.py
fabc2132704350dfe29a1b899abef72926660a8ffb98f04f6a05d00db367e3f6
[root@localhost DDocker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fabc21327043 training/webapp "python app.py" 28 seconds ago Up 27 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp competent_allen
949ba9ad0295 training/webapp "python app.py" 3 hours ago Up 3 hours 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp hopeful_darwin
[root@localhost DDocker]#

另外,可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

1
2
3
4
5
6
7
8
[root@localhost DDocker]# docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
08da7892182cc14a717909593cfcd62862f6bcae9535aa8af88563b281b107e9
[root@localhost DDocker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
08da7892182c training/webapp "python app.py" 2 seconds ago Up 1 second 127.0.0.1:5001->5000/tcp angry_beaver
fabc21327043 training/webapp "python app.py" 4 minutes ago Up 4 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp competent_allen
949ba9ad0295 training/webapp "python app.py" 3 hours ago Up 3 hours 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp hopeful_darwin
[root@localhost DDocker]#

这样就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。

上面的例子中,默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp

1
2
3
4
5
6
7
8
9
[root@localhost DDocker]# docker run -d -p 127.0.0.1:5001:5000/udp training/webapp python app.py
452f6b05777215093e648b730693ca6f5f9c2b1c75909a92b13b87dd84eb549e
[root@localhost DDocker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
452f6b057772 training/webapp "python app.py" 2 seconds ago Up 1 second 5000/tcp, 127.0.0.1:5001->5000/udp beautiful_rosalind
08da7892182c training/webapp "python app.py" About a minute ago Up About a minute 127.0.0.1:5001->5000/tcp angry_beaver
fabc21327043 training/webapp "python app.py" 6 minutes ago Up 5 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp competent_allen
949ba9ad0295 training/webapp "python app.py" 3 hours ago Up 3 hours 0.0.0.0:49153->5000/tcp, :::49153->5000/tcp hopeful_darwin
[root@localhost DDocker]#

docker port 命令可以快捷地查看端口的绑定情况。

1
2
3
[root@localhost DDocker]# docker port angry_beaver 5000
127.0.0.1:5001
[root@localhost DDocker]#

4.2 Docker 容器互联

端口映射并不是唯一把 docker 连接到另一个容器的方法。

docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。

docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。

4.2.1 容器命名

当创建一个容器的时候,docker 会自动对它进行命名。另外,也可以使用 —name 标识来命名容器,例如:

1
2
3
[root@localhost DDocker]# docker run -d -P --name gyp01 training/webapp python app.py
1b5960c5c67768da9bfa1e692bfb4e92ffb8bb7adf84e97673834897428305ad
[root@localhost DDocker]#

可以使用 docker ps 命令来查看容器名称。

1
2
3
4
[root@localhost DDocker]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1b5960c5c677 training/webapp "python app.py" 9 seconds ago Up 8 seconds 0.0.0.0:49154->5000/tcp, :::49154->5000/tcp gyp01
[root@localhost DDocker]#

4.2.2 新建网络

创建一个新的 Docker 网络。

1
2
3
4
5
6
7
8
9
[root@localhost DDocker]# docker network create -d bridge test-net
9cd4cfe85b059e418a34d22ad67c93163fde29fd24c558b18ec8ffd2f67a32e8
[root@localhost DDocker]# docker network ls
NETWORK ID NAME DRIVER SCOPE
90318cd44c6e bridge bridge local
1a9a32f8cdda host host local
83e6b7fb39a6 none null local
9cd4cfe85b05 test-net bridge local
[root@localhost DDocker]#

参数说明:

-d:参数指定 Docker 网络类型,有 bridge、overlay。

其中 overlay 网络类型用于 Swarm mode。

4.2.3 连接容器

运行一个容器并连接到新建的 test-net 网络:

1
2
3
4
5
6
7
8
[root@localhost DDocker]# docker run -itd --name test1 --network test-net ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
d19f32bd9e41: Pull complete
Digest: sha256:34fea4f31bf187bc915536831fd0afc9d214755bf700b5cdb1336c82516d154e
Status: Downloaded newer image for ubuntu:latest
e6d15d1d5dc6f9698ab88a74c029d24e9b960a3ef45a946a476ffc0db6a3c64a
[root@localhost DDocker]#

打开新的终端,再运行一个容器并加入到 test-net 网络:

1
2
3
[root@localhost DDocker]# docker run -itd --name test2 --network test-net ubuntu /bin/bash
fa1f782105efcc19828d20e4391e91bb8d480621c3cab330be73820a58091a96
[root@localhost DDocker]#

下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。

如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping(即学即用:可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@e6d15d1d5dc6:/# apt-get update
Get:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu focal InRelease [265 kB]
...
Get:22 http://mirrors.tuna.tsinghua.edu.cn/ubuntu focal-proposed/restricted amd64 Packages [257 kB]
Fetched 24.2 MB in 1min 27s (279 kB/s)
Reading package lists... Done
root@e6d15d1d5dc6:/# apt-get install iputils-ping
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
...
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.34.0 /usr/local/share/perl/5.34.0 /usr/lib/x86_64-linux-gnu/perl5/5.34 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.34 /usr/share/perl/5.34 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)
debconf: falling back to frontend: Teletype
Setting up iputils-ping (3:20190709-3) ...
root@e6d15d1d5dc6:/#

在 test1 容器输入以下命令:

1
2
3
4
5
6
7
[root@localhost DDocker]# docker exec -it test1 /bin/bash
root@e6d15d1d5dc6:/# ping test2
PING test2 (172.18.0.3) 56(84) bytes of data.
64 bytes from test2.test-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.134 ms
64 bytes from test2.test-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.116 ms
64 bytes from test2.test-net (172.18.0.3): icmp_seq=3 ttl=64 time=0.065 ms

同理在 test2 容器也会成功连接到:

1
2
3
4
5
6
7
[root@localhost DDocker]# docker exec -it test2 /bin/bash
root@fa1f782105ef:/# ping test1
PING test1 (172.18.0.2) 56(84) bytes of data.
64 bytes from test1.test-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from test1.test-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.084 ms
64 bytes from test1.test-net (172.18.0.2): icmp_seq=3 ttl=64 time=0.121 ms
64 bytes from test1.test-net (172.18.0.2): icmp_seq=4 ttl=64 time=0.070 ms

这样,test1 容器和 test2 容器建立了互联关系。

如果有多个容器之间需要互相连接,推荐使用 Docker Compose,后面会介绍。

4.3 配置 DNS

可以在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:

1
2
3
4
5
6
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}

设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。

配置完,需要重启 docker 才能生效。

查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:

1
2
3
4
[root@localhost DDocker]# docker run -it --rm  ubuntu  cat etc/resolv.conf
nameserver 8.8.8.8
nameserver 114.114.114.114
[root@localhost DDocker]#

手动指定容器的配置

如果只想在指定的容器设置 DNS,则可以使用以下命令:

1
2
[root@localhost DDocker]# docker run -it --rm -h host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu
root@host_ubuntu:/#

参数说明:

  • --rm:容器退出时自动清理容器内部的文件系统。

  • -h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname/etc/hosts

  • --dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。

  • --dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost DDocker]# docker run -it --rm -h host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu
root@host_ubuntu:/# cat /etc/hostname
host_ubuntu
root@host_ubuntu:/# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.7 host_ubuntu
root@host_ubuntu:/# cat /etc/resolv.conf
search test.com
nameserver 114.114.114.114
root@host_ubuntu:/#

如果在容器启动时没有指定 --dns--dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS。

5. Docker仓库管理

仓库(Repository)是集中存放镜像的地方。以下介绍一下 Docker Hub。当然不止 docker hub,只是远程的服务商不一样,操作都是一样的。

5.1 Docker Hub

目前 Docker 官方维护了一个公共仓库 Docker Hub

大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。

5.2 注册

https://hub.docker.com 免费注册一个 Docker 账号。

5.3 登录和退出

登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost DDocker]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: kungs
Password:
Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: incorrect username or password
[root@localhost DDocker]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: kungs
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@localhost DDocker]#

退出 docker hub 可以使用以下命令:

1
2
3
[root@localhost DDocker]# docker logout
Removing login credentials for https://index.docker.io/v1/
[root@localhost DDocker]#

5.4 拉取镜像

可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。

以 ubuntu 为关键词进行搜索:

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 DDocker]# docker search ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating sys… 14855 [OK]
websphere-liberty WebSphere Liberty multi-architecture images … 288 [OK]
ubuntu-upstart DEPRECATED, as is Upstart (find other proces… 112 [OK]
neurodebian NeuroDebian provides neuroscience research s… 92 [OK]
ubuntu/nginx Nginx, a high-performance reverse proxy & we… 57
open-liberty Open Liberty multi-architecture images based… 54 [OK]
ubuntu-debootstrap DEPRECATED; use "ubuntu" instead 46 [OK]
ubuntu/apache2 Apache, a secure & extensible open-source HT… 40
ubuntu/mysql MySQL open source fast, stable, multi-thread36
kasmweb/ubuntu-bionic-desktop Ubuntu productivity desktop for Kasm Workspa… 31
ubuntu/squid Squid is a caching proxy for the Web. Long-t30
ubuntu/prometheus Prometheus is a systems and service monitori… 28
ubuntu/bind9 BIND 9 is a very flexible, full-featured DNS… 25
ubuntu/postgres PostgreSQL is an open source object-relation19
ubuntu/redis Redis, an open source key-value store. Long-… 11
ubuntu/kafka Apache Kafka, a distributed event streaming … 11
ubuntu/grafana Grafana, a feature rich metrics dashboard & … 6
ubuntu/prometheus-alertmanager Alertmanager handles client alerts from Prom… 6
ubuntu/memcached Memcached, in-memory keyvalue store for smal… 5
ubuntu/zookeeper ZooKeeper maintains configuration informatio… 5
ubuntu/telegraf Telegraf collects, processes, aggregates & w… 4
ubuntu/cortex Cortex provides storage for Prometheus. Long… 3
ubuntu/cassandra Cassandra, an open source NoSQL distributed … 2
ubuntu/dotnet-deps Chiselled Ubuntu for self-contained .NET & A… 2
ubuntu/loki Grafana Loki, a log aggregation system like … 0
[root@localhost DDocker]#

使用 docker pull 将官方 ubuntu 镜像下载到本地:

1
2
3
4
5
6
7
[root@localhost DDocker]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
Digest: sha256:34fea4f31bf187bc915536831fd0afc9d214755bf700b5cdb1336c82516d154e
Status: Image is up to date for ubuntu:latest
docker.io/library/ubuntu:latest
[root@localhost DDocker]#

5.5 推送镜像

用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。

以下命令中的 kungs 请替换为你的 Docker 账号用户名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost DDocker]# docker tag ubuntu:18.04 kungs/ubuntu:18.04
[root@localhost DDocker]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest df5de72bdb3b 4 weeks ago 77.8MB
kungs/ubuntu 18.04 8d5df41c547b 4 weeks ago 63.1MB
ubuntu 18.04 8d5df41c547b 4 weeks ago 63.1MB
training/webapp latest 6fae60ef3446 7 years ago 349MB
[root@localhost DDocker]# docker push kungs/ubuntu:18.04
The push refers to repository [docker.io/kungs/ubuntu]
e722d396f503: Mounted from library/ubuntu
18.04: digest: sha256:e4771b7160543c6e43968b4e9795be9ddcad9d573edd7cd7aebd3ce61326fc7a size: 529
[root@localhost DDocker]# docker search kungs/ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
kungs/ubuntu

6. Docker Dockerfile

6.1 什么是 Dockerfile?

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

6.2 使用 Dockerfile 定制镜像

这里仅讲解如何运行 Dockerfile 文件来定制一个镜像,具体 Dockerfile 文件内指令详解,将在下一节中介绍,这里你只要知道构建的流程即可。

  1. 下面以定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)

    在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@localhost ~]# cd /root/yanpenggong/DEMO/DockerTest/docker/
    [root@localhost docker]# mkdir Dockerfile
    [root@localhost docker]# cd Dockerfile/
    [root@localhost Dockerfile]# pwd
    /root/yanpenggong/DEMO/DockerTest/docker/Dockerfile
    [root@localhost Dockerfile]# vi Dockerfile
    [root@localhost Dockerfile]# cat Dockerfile
    FROM nginx
    RUN echo "这是一个本地构建的nginx镜像" > /usr/share/nginx/html/index.html
    [root@localhost Dockerfile]#
  2. FROM 和 RUN 指令的作用

    • FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

    • RUN:用于执行后面跟着的命令行命令。有以下俩种格式:

      • shell 格式:

        1
        2
        RUN <命令行命令>
        # <命令行命令> 等同于 在终端操作的 shell 命令.
      • exec 格式:

        1
        2
        3
        RUN ["可执行文件", "参数1", "参数2"]
        # 例如:
        # RUN ["./test.py", "dev", "offline"] 等价于 RUN ./test.py def offline

        注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

        1
        2
        3
        4
        FROM centos
        RUN yum -y install wget
        RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
        RUN tar -xvf redis.tar.gz

        以上执行会创建 3 层镜像。可简化为以下格式:

        1
        2
        3
        4
        FROM centos
        RUN yum -y install wget \
        && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
        && tar -xvf redis.tar.gz

        如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

6.3 开始构建镜像

在 Dockerfile 文件的存放目录下,执行构建动作。

以下示例,通过目录下的 Dockerfile 构建一个nginx:v3(镜像名称:镜像标签)。

:最后的 . 代表本次执行的上下文路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost Dockerfile]# docker build -t nginx:v1 .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM nginx
---> 3964ce7b8458
Step 2/2 : RUN echo "这是一个本地构建的nginx镜像" > /usr/share/nginx/html/index.html
---> Running in 37afd3da723f
Removing intermediate container 37afd3da723f
---> bc6855014a02
Successfully built bc6855014a02
Successfully tagged nginx:v1
[root@localhost Dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 bc6855014a02 About a minute ago 142MB
kungs1 v2 5707f6758e8f 2 days ago 118MB
kungs1 v1 2d82fcabb70f 2 days ago 77.8MB
nginx latest 3964ce7b8458 5 days ago 142MB
ubuntu latest 6b7dfa7e8fdb 10 days ago 77.8MB
httpd latest 157dcdf23d6c 12 days ago 145MB
training/webapp latest 6fae60ef3446 7 years ago 349MB
[root@localhost Dockerfile]#

以上显示,说明已经构建成功。

6.4 上下文路径

上面有提到指令最后一个 . 是上下文路径,那么什么是上下文路径呢?

上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。

解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。

如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。

注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。

6.5 指令详解

命令 说明
FROM 建镜像基于哪个镜像
MAINTAINER 镜像维护者姓名或邮箱地址
RUN 构建镜像时运行的指令
CMD 运行容器时执行的shell环境
VOLUME 指定容器挂载点到宿主机自动生成的目录或其他容器
USER 为RUN、CMD、和 ENTRYPOINT 执行命令指定运行用户
WORKDIR 为 RUN、CMD、ENTRYPOINT、COPY 和 ADD 设置工作目录,就是切换目录
HEALTHCHECH 健康检查
ARG 构建时指定的一些参数
EXPOSE 声明容器的服务端口(仅仅是声明)
ENV 设置容器环境变量
ADD 拷贝文件或目录到容器中,如果是URL或压缩包便会自动下载或自动解压
COPY 拷贝文件或目录到容器中,跟ADD类似,但不具备自动下载或解压的功能
ENTRYPOINT 运行容器时执行的shell命令

6.5.1 COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

格式:

1
2
COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

参数说明:

  • [--chown=:<group>]: 可选参数,用户改变复制到容器内文件的拥有者和属组。

  • <源路径1>: 源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

    1
    2
    COPY hom* /mydir/
    COPY hom?.txt /mydir/
  • <目标路径>: 容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

6.5.2 ADD

ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

6.5.3 CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

  • CMDdocker run 时运行。
  • RUN 是在 docker build

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

格式:

1
2
3
CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

6.5.4 ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了--entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

格式:

1
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。

示例:

假设已通过 Dockerfile 构建了 nginx:test 镜像:

1
2
3
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
  1. 不传参运行

    1
    [root@localhost Dockerfile]# docker run  nginx:test

    容器内会默认运行以下命令,启动主进程。

    1
    nginx -c /etc/nginx/nginx.conf
  2. 传参运行

    1
    [root@localhost Dockerfile]# docker run  nginx:test -c /etc/nginx/new.conf

    容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

    1
    nginx -c /etc/nginx/new.conf

6.5.5 ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

格式:

1
2
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:

1
2
3
4
ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"

6.5.6 ARG

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

格式:

1
ARG <参数名>[=<默认值>]

6.5.7 VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

  • 避免重要的数据,因容器重启而丢失,这是非常致命的。
  • 避免容器不断变大。

格式:

1
2
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

6.5.8 EXPOSE

仅仅只是声明端口。

作用:

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

格式:

1
EXPOSE <端口1> [<端口2>...]

6.5.9 WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。

docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

格式:

1
WORKDIR <工作目录路径>

6.5.10 USER

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

格式:

1
USER <用户名>[:<用户组>]

6.5.11 HEALTHCHECK

用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

格式:

1
2
3
4
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

6.5.12 ONBUILD

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

格式:

1
ONBUILD <其它指令>

6.5.13 LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:

1
LABEL <key>=<value> <key>=<value> <key>=<value> ...

比如我们可以添加镜像的作者:

1
LABEL org.opencontainers.image.authors="yanpenggong"

7. Docker Compose

7.0 YAML 入门教程

YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:”Yet Another Markup Language”(仍是一种标记语言)。

YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。

YAML 的配置文件后缀为 .yml,如:yanpenggong.yml

7.0.1 基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • #表示注释

7.0.2 数据类型

YAML 支持以下几种数据类型:

  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
  • 纯量(scalars):单个的、不可再分的值
7.0.2.1 YAML 对象

对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。

也可以使用 key:{key1: value1, key2: value2, …}

还可以使用缩进表示层级关系;

1
2
3
key: 
child-key: value
child-key2: value2

较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:

1
2
3
4
5
6
?  
- complexkey1
- complexkey2
:
- complexvalue1
- complexvalue2

意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]

7.0.2.2 YAML 数组

- 开头的行表示构成一个数组:

1
2
3
- A
- B
- C

YAML 支持多维数组,可以使用行内表示:

1
key: [value1, value2, ...]

数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。

1
2
3
4
-
- A
- B
- C

一个相对复杂的例子:

1
2
3
4
5
6
7
8
9
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W

意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。

数组也可以使用流式(flow)的方式表示:

1
companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]
7.0.2.3 复合结构

数组和对象可以构成复合结构,例:

1
2
3
4
5
6
7
8
9
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org

转换为 json 为:

1
2
3
4
5
6
7
8
9
{ 
languages: [ 'Ruby', 'Perl', 'Python'],
websites: {
YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org'
}
}
7.0.2.4 纯量

纯量是最基本的,不可再分的值,包括:

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • Null
  • 时间
  • 日期

使用一个例子来快速了解纯量的基本使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
boolean: 
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科学计数法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二进制表示
null:
nodeName: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- newline
newline2 #字符串可以拆成多行,每一行会被转化成一个空格
date:
- 2022-08-31 #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2022-08-31T10:50:21+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
7.0.2.5 引用
  • & 锚点和 * 别名,可以用来引用:
1
2
3
4
5
6
7
8
9
10
11
defaults: &defaults
adapter: postgres
host: localhost

development:
database: myapp_development
<<: *defaults

test:
database: myapp_test
<<: *defaults

相当于:

1
2
3
4
5
6
7
8
9
10
11
12
13
defaults:
adapter: postgres
host: localhost

development:
database: myapp_development
adapter: postgres
host: localhost

test:
database: myapp_test
adapter: postgres
host: localhost

& 用来建立锚点(defaults),<< 表示合并到当前数据,* 用来引用锚点。

下面是另一个例子:

1
2
3
4
5
- &showell Steve 
- Clark
- Brian
- Oren
- *showell

转为 JavaScript 代码如下:

1
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]

7.1 Compose 简介

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

Compose 使用的三个步骤:

  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

docker-compose.yml 的配置案例如下(配置参数参考下文):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# yml 配置实例
version: "1.0"
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .: /code
- logvolume01: /var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}

7.2 Compose 安装

Linux 上可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。

运行以下命令以下载 Docker Compose 的当前稳定版本:

1
2
3
4
5
6
[root@localhost DDocker]# sudo curl -SL "https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 425 100 425 0 0 479 0 --:--:-- --:--:-- --:--:-- 479
100 24.5M 100 24.5M 0 0 7220k 0 0:00:03 0:00:03 --:--:-- 13.3M
[root@localhost DDocker]#

要安装其他版本的 Compose,请替换 v2.14.0。

Docker Compose 存放在 GitHub,不太稳定。

也可以通过执行下面的命令,高速安装 Docker Compose。

1
2
3
4
5
6
7
[root@localhost Dockerfile]# curl -SL https://github.com/docker/compose/releases/download/v2.14.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
2 42.8M 2 944k 0 0 11860 0 1:03:07 0:01:21 1:01:46 8238
100 42.8M 100 42.8M 0 0 98k 0 0:07:27 0:07:27 --:--:-- 208k
[root@localhost Dockerfile]#

将可执行权限应用于二进制文件:

1
2
[root@localhost DDocker]# sudo chmod +x /usr/local/bin/docker-compose
[root@localhost DDocker]#

创建软链:

1
2
[root@localhost DDocker]# sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
[root@localhost DDocker]#

测试是否安装成功:

1
2
3
[root@localhost Dockerfile]# docker-compose --version
Docker Compose version v2.14.0
[root@localhost Dockerfile]#

注意: 对于 alpine,需要以下依赖包: py-pippython-devlibffi-devopenssl-devgcclibc-dev,和 make

macOS 和 windows:

1
Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,故不需要单独安装 Compose。

7.3 使用

7.3.1 准备

创建一个测试目录:

1
2
3
4
5
[root@localhost DockerTest]# pwd
/root/yanpenggong/DEMO/DockerTest
[root@localhost DockerTest]# mkdir composeTest
[root@localhost DockerTest]# cd composeTest/
[root@localhost composeTest]#

在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:

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
[root@localhost composetest]# cat app.py 
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)


def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)


@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
[root@localhost composetest]#

在此示例中,redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379。

在 composeTest 目录中创建另一个名为 requirements.txt 的文件,内容如下:

1
2
3
4
[root@localhost composetest]# cat requirements.txt 
flask
redis
[root@localhost composetest]#

7.3.2 创建 Dockerfile 文件

在 composeTest 目录中,创建一个名为 Dockerfile 的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost composeTest]# cat Dockerfile 
FROM python:3.7-alpine3.10
WORKDIR /code
ENV FLASK_APP=app.py \
FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD ["flask", "run"]
[root@localhost composeTest]#

Dockerfile 内容解释:

  • FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。

  • WORKDIR /code: 将工作目录设置为 /code。

  • ENV:设置 flask 命令使用的环境变量。

    1
    2
    ENV FLASK_APP app.py
    ENV FLASK_RUN_HOST 0.0.0.0

    1
    2
    ENV FLASK_APP=app.py \
    FLASK_RUN_HOST=0.0.0.0
  • RUN apk add —no-cache gcc musl-dev linux-headers: 安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。

  • ```
    COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    复制 requirements.txt 并安装 Python 依赖项。

    - **COPY . .**: 将 . 项目中的当前目录复制到 `.` 镜像中的工作目录。

    - **CMD ["flask", "run"]**: 容器提供默认的执行命令为:`flask run`。

    #### 7.3.3 创建 docker-compose.yml

    > **端口永久开放(permanent)**
    >
    > ```shell
    > #开端口
    > firewall-cmd --get-active-zones
    > firewall-cmd --zone=public --add-port=端口号/tcp --permanent
    > #重启
    > firewall-cmd --reload
    > #检验端口是否开放
    > firewall-cmd --query-port=8000/tcp

在测试目录中创建一个名为 docker-compose.yml 的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost composeTest]# cat docker-compose.yml 
# yml 配置实例
version: '2.0'
services:
web:
build: .
ports:
- "8001:8001"
redis:
image: redis:alpine
ports:
- "6379:6379"
[root@localhost composeTest]#

7.3.4 使用 Compose 命令构建和运行您的应用

在测试目录中,执行 docker-compose up 命令来启动应用程序:

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
[root@localhost composeTest]# docker-compose up
[+] Running 2/0
⠿ Container composetest-redis-1 Created 0.0s
⠿ Container composetest-app1-1 Created 0.0s
Attaching to composetest-app1-1, composetest-redis-1
composetest-redis-1 | 1:C 19 Dec 2022 09:07:46.874 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
composetest-redis-1 | 1:C 19 Dec 2022 09:07:46.874 # Redis version=7.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
composetest-redis-1 | 1:C 19 Dec 2022 09:07:46.874 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.875 * monotonic clock: POSIX clock_gettime
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 * Running mode=standalone, port=6379.
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 # Server initialized
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 * Loading RDB produced by version 7.0.7
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 * RDB age 165 seconds
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 * RDB memory usage when created 0.85 Mb
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 * Done loading RDB, keys loaded: 1, keys expired: 0.
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 * DB loaded from disk: 0.000 seconds
composetest-redis-1 | 1:M 19 Dec 2022 09:07:46.876 * Ready to accept connections
composetest-app1-1 | * Serving Flask app 'app.py'
composetest-app1-1 | * Debug mode: off
composetest-app1-1 | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
composetest-app1-1 | * Running on all addresses (0.0.0.0)
composetest-app1-1 | * Running on http://127.0.0.1:8001
composetest-app1-1 | * Running on http://172.26.0.3:8001
composetest-app1-1 | Press CTRL+C to quit
...

如果想在后台执行该服务可以加上 -d 参数:docker-compose up -d

1
2
3
4
5
6
[root@localhost composeTest]# docker-compose up -d
[+] Running 3/3
⠿ Network composetest_default Created 0.2s
⠿ Container composetest-redis-1 Started 0.4s
⠿ Container composetest-app1-1 Started 0.4s
[root@localhost composeTest]#

注意:

1
2
1. 修改dockerfile后,需要进行 `docker-compose up --build`
2. 修改docker-compose,仅仅需要 `docker-compose up`

7.4 yml配置指令参考

ID 指令 描述
1 version 指定本 yml 依从的 compose 哪个版本制定的
2 build 指定为构建镜像上下文路径
3 cap_add, cap_drop 添加或删除容器拥有的宿主机的内核功能
4 cgroup_parent 为容器指定父 cgroup 组,意味着将继承该组的资源限制
5 command 覆盖容器启动的默认命令
6 container_name 指定自定义容器名称,而不是生成的默认名称
7 depends_on 设置依赖关系
8 deploy 指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用
9 devices 指定设备映射列表
10 dns 自定义 DNS 服务器,可以是单个值或列表的多个值。
11 dns_search 自定义 DNS 搜索域。可以是单个值或列表。
12 entrypoint 覆盖容器默认的 entrypoint。
13 env_file 从文件添加环境变量。可以是单个值或列表的多个值。
14 environment 添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
15 expose 暴露端口,但不映射到宿主机,只被连接的服务访问。
16 extra_hosts 添加主机名映射。类似 docker client --add-host
17 healthcheck 用于检测 docker 服务是否健康运行。
18 image 指定容器运行的镜像。
19 logging 服务的日志记录配置。
20 network_mode 设置网络模式
21 restart 重启容器策略
22 secrets 存储敏感数据,例如密码
23 security_opt 修改容器默认的 schema 标签。
24 stop_grace_period 指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。
25 stop_signal 设置停止容器的替代信号。默认情况下使用 SIGTERM
26 sysctls 设置容器中的内核参数,可以使用数组或字典格式。
27 tmpfs 在容器内安装一个临时文件系统。可以是单个值或列表的多个值。
28 ulimits 覆盖容器默认的 ulimit。
29 volumes 将主机的数据卷或者文件挂载到容器里。

7.4.1 version

指定本 yml 依从的 compose 哪个版本制定的。

7.4.2 build

指定为构建镜像上下文路径:

例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:

1
2
3
4
version: "2.0"
services:
webapp:
build: ./dir

或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:

1
2
3
4
5
6
7
8
9
10
11
12
13
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
target: prod
  • context:上下文路径。
  • dockerfile:指定构建镜像的 Dockerfile 文件名。
  • args:添加构建参数,这是只能在构建过程中访问的环境变量。
  • labels:设置构建镜像的标签。
  • target:多层构建,可以指定构建哪一层。

7.4.3 cap_add,cap_drop

添加或删除容器拥有的宿主机的内核功能。

1
2
3
4
5
cap_add:
- ALL # 开启全部权限

cap_drop:
- SYS_PTRACE # 关闭 ptrace权限

7.4.4 cgroup_parent

为容器指定父 cgroup 组,意味着将继承该组的资源限制。

1
cgroup_parent: m-executor-abcd

7.4.5 command

覆盖容器启动的默认命令。

1
command: ["bundle", "exec", "thin", "-p", "3000"]

7.4.6 container_name

指定自定义容器名称,而不是生成的默认名称。

1
container_name: my-web-container

7.4.7 depends_on

设置依赖关系。

  • docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
  • docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。
  • docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
1
2
3
4
5
6
7
8
9
10
11
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres

注意:web 服务不会等待 redis db 完全启动 之后才启动。

7.4.8 deploy

指定与服务的部署和运行有关的配置。==只在 swarm 模式下才会有用==。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3.8"
services:
redis:
image: redis.alpine
deploy:
mode: replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: "0.50"
memory: 50M
reservations:
cpus: "0.25"
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s

可以选参数:

  • endpoint_mode:访问集群服务的方式。

    1
    2
    3
    4
    endpoint_mode: vip 
    # Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
    endpoint_mode: dnsrr
    # DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。
  • labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。

  • mode:指定服务提供的模式。

    • replicated:复制服务,复制指定服务到集群的机器上。

    • global:全局服务,服务将部署至集群的每个节点。

    • 图解:下图中黄色的方块是 replicated 模式的运行情况,灰色方块是 global 模式的运行情况。

  • replicasmode 为 replicated 时,需要使用此参数配置具体运行的节点数量。

  • resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。

    • limits: 控制最大限制

      • cpus: “0.50”,表示可占处理周期百分之50的处理时间
      • memory: 50M,表示可用的内存为50M
    • reservations: 初始可使用资源,保留资源

      • cpus: “0.25”, 表示可占处理周期百分之25的处理时间
      • memory: 20M,表示可用的内存为20M
  • restart_policy:配置如何在退出容器时重新启动容器。

    • condition:可选 none,on-failure 或者 any(默认值:any)。
    • delay:设置多久之后重启(默认值:0)。
    • max_attempts:尝试重新启动容器的次数,超出次数,则不再尝试(默认值:一直重试)。
    • window:设置容器重启超时时间(默认值:0)。
  • rollback_config:配置在更新失败的情况下应如何回滚服务。

    • parallelism:一次要回滚的容器数。如果设置为0,则所有容器将同时回滚。
    • delay:每个容器组回滚之间等待的时间(默认为0s)。
    • failure_action:如果回滚失败,该怎么办。其中一个 continue 或者 pause(默认pause)。
    • monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
    • max_failure_ratio:在回滚期间可以容忍的故障率(默认为0)。
    • order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认 stop-first )。
  • update_config:配置应如何更新服务,对于配置滚动更新很有用。

    • parallelism:一次更新的容器数。
    • delay:在更新一组容器之间等待的时间。
    • failure_action:如果更新失败,该怎么办。其中一个 continue,rollback 或者pause (默认:pause)。
    • monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
    • max_failure_ratio:在更新过程中可以容忍的故障率。
    • order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认stop-first)。

    :仅支持 V3.4 及更高版本。

7.4.9 devices

指定设备映射列表。

1
2
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"

7.4.10 dns

自定义 DNS 服务器,可以是单个值或列表的多个值。

1
2
3
4
5
dns: 8.8.8.8

dns:
- 8.8.8.8
- 9.9.9.9

自定义 DNS 搜索域。可以是单个值或列表。

1
2
3
4
5
dns_search: example.com

dns_search:
- dc1.example.com
- dc2.example.com

7.4.12 entrypoint

覆盖容器默认的 entrypoint。

1
entrypoint: /code/entrypoint.sh

也可以是以下格式:

1
2
3
4
5
6
7
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit

7.4.13 env_file

从文件添加环境变量。可以是单个值或列表的多个值。

1
env_file: .env

也可以是列表格式:

1
2
3
4
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env

7.4.14 environment

添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。

1
2
3
environments:
RACK_ENV: development
SHOW: "true"

7.4.15 expose

暴露端口,但不映射到宿主机,只被连接的服务访问。

仅可以指定内部端口为参数:

1
2
3
expose:
- "8000"
- "8862"

7.4.16 extra_hosts

添加主机名映射。类似 docker client --add-host

1
2
3
extra_hosts:
- "onehost:192.168.58.101"
- "otherhost:192.168.58.102"

以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:

1
2
192.168.58.101  onehost
192.168.58.102 otherhost

7.4.17 healthcheck

用于检测 docker 服务是否健康运行。

1
2
3
4
5
6
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 设置监测程序
interval: 1m30s # 设置监测间隔
timeout: 10s # 设置检测超时时间
retries: 3 # 设置重试次数
start_period: 40s # 启动后,多少秒开始启动检测程序

7.4.18 image

指定容器运行的镜像。以下格式都可以:

1
2
3
4
image: redis
image: ubuntu:16.04
image: tutum/influxdb
image: 60ce5883af74

7.4.19 logging

服务的日志记录配置。

driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项

1
2
3
driver: "json-file"
driver: "syslog"
driver: "none"
  • driver: "json-file" 驱动程序下,可以使用以下参数,限制日志得数量和大小。

    1
    2
    3
    4
    5
    logging:
    driver: json-file
    options:
    max-size: "200k" # 单个文件大小为200k
    max-file: "10" # 最多10个文件

    当达到文件限制上限,会自动删除旧得文件。

  • driver: "syslog" 驱动程序下,可以使用 syslog-address 指定日志接收地址。

    1
    2
    3
    4
    logging:
    driver: syslog
    options:
    syslog-address: "tcp://192.168.58.101:8802"

7.4.20 network_mode

设置网络模式

1
2
3
4
5
network-mode: "bridge"
network-mode: "host"
network-mode: "none"
network-mode: "service:[service name]"
network-mode: "container:[container name/id]"

networks:配置容器连接的网络,引用顶级networks下的条目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
services:
one-service:
networks:
one-network:
aliases:
- alias1
other-network:
aliases:
-alias2
networks:
one-network:
# Use a custom driver
driver: custom-driver-1
other-network:
# Use a custom driver which takes special options
driver: custom-driver-2

aliases: 同一网络上的其他容器阔以使用服务名称或此别名来连接到对应容器的服务。

7.4.21 restart

  • no: 默认的重启策略,在任何情况下都不会重启容器
  • always: 容器总是重新启动
  • on-failure: 在容器非正常退出时(退出状态非0),才会重启容器
  • unless-stopped: 在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
1
2
3
4
restart: "no"
restart: "always"
restart: "on-failure"
retart: "unless-stopped"

注意:swarm集群模式,请改用restart_policy

7.4.22 secrets

存储敏感数据,例如密码:

1
2
3
4
5
6
7
8
9
10
11
version: "2.0"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret.txt

7.4.23 security_opt

修改容器默认的 schema 标签。

1
2
3
4
5
security-opt:
- label: user:USER # 设置容器的用户标签
- label: role: ROLE # 设置容器的角色标签
- label: type: TYPE # 设置容器的安全策略标签
- label: level:LEVEL # 设置容器的安全等级标签

7.4.24 stop_grace_period

指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。

1
2
stop_grace_period: 1s  # 等待1秒
stop_grace_period: 1m30s # 等待1分30秒

默认的等待时间时10秒。

7.4.25 stop_signal

设置停止容器的替代信号。默认情况下使用 SIGTERM

以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。

1
stop_signal: SIGUSR1

7.4.26 sysctls

设置容器中的内核参数,可以使用数组或字典格式。

1
2
3
4
5
6
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0

7.4.27 tmpfs

在容器内安装一个临时文件系统。可以是单个值或列表的多个值。

1
2
3
4
tmpfs: /run
tmpfs:
- /run
- /tmp

7.4.28 ulimits

覆盖容器默认的 ulimit。

1
2
3
4
5
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000

7.4.29 volumes

将主机的数据卷或者文件挂载到容器里。

1
2
3
4
5
6
7
8
# yml 配置实例
version: '2.0'
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgres/data"

8. Docker Machine

8.1 简介

Docker Machine 是一种可以让您在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机。

Docker Machine 也可以集中管理所有的 docker 主机,比如快速的给 100 台服务器安装上 docker。

Docker Machine 管理的虚拟主机可以是机上的,也可以是云供应商,如阿里云,腾讯云,AWS,或 DigitalOcean等等。

使用 docker-machine 命令,您可以启动,检查,停止和重新启动托管主机,也可以升级 Docker 客户端和守护程序,以及配置 Docker 客户端与您的主机进行通信。

8.2 安装

安装 Docker Machine 之前你需要先安装 Docker

Docker Machine 可以在多种平台上安装使用,包括 Linux 、MacOS 以及 windows。

8.2.1 macOS安装命令

1
2
3
4
5
6
(base) kungs@kungs-MacPro ~ % curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` >/usr/local/bin/docker-machine && \
> chmod +x /usr/local/bin/docker-machine
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 32.6M 0 97716 0 0 355 0 26:46:17 0:04:34 26:41:43 0

8.2.2 Linux 安装命令

1
2
3
4
5
[root@localhost composeTest]# curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&     chmod +x /tmp/docker-machine &&     sudo cp /tmp/docker-machine /usr/local/bin/docker-machine
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 32.6M 0 97716 0 0 355 0 26:46:17 0:04:34 26:41:43 0

8.2.3 Windows with git bash

1
2
3
4
5
6
7
8
yanpenggong@kungs MINGW64 ~
$ if [[ ! -d "$HOME/bin" ]]; then mkdir -p "$HOME/bin"; fi && \
curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Windows-x86_64.exe > "$HOME/bin/docker-machine.exe" && \
chmod +x "$HOME/bin/docker-machine.exe"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 32.8M 0 111k 0 0 23166 0 0:24:47 0:00:04 0:24:43 34068

否则,直接从发布页面下载其中一个版本。

有关更多安装选项和说明,请参阅安装文档

8.2.4 查看是否安装成功:

1
2
3
[root@localhost composeTest]# docker-machine --version
docker-machine version 0.16.2, build bd45ab13
[root@localhost composeTest]#

注意:各版本更新日志里面也有安装说明:https://github.com/docker/machine/releases

8.3 使用

这里通过 vmware来介绍 docker-machine 的使用方法。其他云服务商操作与此基本一致。具体可以参考每家服务商的指导文档。

8.3.1列出可用的机器

可以看到目前只有这里默认的 default 虚拟机。

1
2
3
[root@localhost composeTest]# docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
[root@localhost composeTest]#

8.3.2 创建机器

创建一台名为 test 的机器。

  • —driver:指定用来创建机器的驱动类型,这里是 virtualbox

    1
    (base) kungs@kungs-MacPro DockerLearning % docker-machine create --driver virtualbox test

    ERROR:

    1
    2
    (base) kungs@kungs-MacPro DockerLearning % docker-machine create --driver virtualbox test
    (base) kungs@kungs-MacPro DockerLearning %

    解决办法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    (base) kungs@kungs-MacPro DockerLearning % brew install virtualbox
    Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
    * base: mirrors.ustc.edu.cn
    * extras: ftp.sjtu.edu.cn
    * updates: mirrors.ustc.edu.cn
    base | 3.6 kB 00:00:00
    docker-ce-stable | 3.5 kB 00:00:00
    extras | 2.9 kB 00:00:00
    updates | 2.9 kB 00:00:00
    (1/2): docker-ce-stable/7/x86_64/primary_db | 91 kB 00:00:00
    (2/2): updates/7/x86_64/primary_db | 19 MB 00:00:06
    (base) kungs@kungs-MacPro DockerLearning %
  • —driver:指定用来创建机器的驱动类型,这里是 vmware

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    (base) kungs@kungs-MacPro DockerLearning % docker-machine create --driver=vmware yanpenggong1
    Running pre-create checks...
    Creating machine...
    (yanpenggong1) Copying /Users/kungs/.docker/machine/cache/boot2docker.iso to /Users/kungs/.docker/machine/machines/yanpenggong1/boot2docker.iso...
    (yanpenggong1) Creating SSH key...
    (yanpenggong1) Creating VM...
    (yanpenggong1) Starting yanpenggong1...
    (yanpenggong1) Waiting for VM to come online...
    Waiting for machine to be running, this may take a few minutes...
    Detecting operating system of created instance...
    Waiting for SSH to be available...
    Detecting the provisioner...
    Provisioning with boot2docker...
    Copying certs to the local machine directory...
    Copying certs to the remote machine...
    Setting Docker configuration on the remote daemon...
    Checking connection to Docker...
    Docker is up and running!
    To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env yanpenggong1
    (base) kungs@kungs-MacPro DockerLearning % docker-machine ls
    NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
    yanpenggong1 - vmware Running tcp://172.16.247.6:2376 v19.03.12
    (base) kungs@kungs-MacPro DockerLearning %

    ERROR解决办法:

    包的路径:docker-machine-driver-vmware

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (base) kungs@kungs-MacPro DockerLearning % brew install docker-machine-driver-vmware
    ==> Fetching docker-machine-driver-vmware
    ==> Downloading https://mirrors.aliyun.com/homebrew/homebrew-bottles/docker-machine-driver-vmware-0.1.5.monterey.bottle.1.tar.gz
    ######################################################################## 100.0%
    ==> Pouring docker-machine-driver-vmware-0.1.5.monterey.bottle.1.tar.gz
    /usr/local/Cellar/docker-machine-driver-vmware/0.1.5: 5 files, 10MB
    ==> Running `brew cleanup docker-machine-driver-vmware`...
    Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
    Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
    (base) kungs@kungs-MacPro DockerLearning %

8.3.3 查看机器的 ip

1
2
3
(base) kungs@kungs-MacPro DockerLearning % docker-machine ip yanpenggong1
172.16.247.6
(base) kungs@kungs-MacPro DockerLearning %

8.3.4 停止机器

1
2
3
4
(base) kungs@kungs-MacPro DockerLearning % docker-machine stop yanpenggong1 
Stopping "yanpenggong1"...
Machine "yanpenggong1" was stopped.
(base) kungs@kungs-MacPro DockerLearning %

8.3.5 启动机器

1
2
3
4
5
6
7
8
9
(base) kungs@kungs-MacPro DockerLearning % docker-machine start yanpenggong1
Starting "yanpenggong1"...
(yanpenggong1) Starting yanpenggong1...
(yanpenggong1) Waiting for VM to come online...
Machine "yanpenggong1" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
(base) kungs@kungs-MacPro DockerLearning %

8.3.6 进入机器

1
2
3
4
5
6
7
8
9
10
11
12
(base) kungs@kungs-MacPro DockerLearning % docker-machine ssh yanpenggong1
( '>')
/) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
(/-_--_-\) www.tinycorelinux.net

chmod: /mnt/hgfs/Users: Operation not permitted
fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the 'nonempty' mount option
chmod: /mnt/hgfs/Users: Operation not permitted
fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the 'nonempty' mount option
docker@yanpenggong1:~$

8.3.7 docker-machine 命令参数说明

激活docker的指定环境eval $(docker-machine env 创建的环境名),实例:

1
2
3
4
5
(base) kungs@kungs-MacPro DockerLearning %  eval $(docker-machine env yanpenggong1)
(base) kungs@kungs-MacPro DockerLearning % docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
yanpenggong1 * vmware Running tcp://172.16.247.6:2376 v19.03.12
(base) kungs@kungs-MacPro DockerLearning %

演示情况:

1
2
3
4
5
6
7
8
9
10
11
12
(base) kungs@kungs-MacPro DockerLearning % docker-machine ls                       
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
yanpenggong1 - vmware Running tcp://172.16.247.6:2376 v19.03.12
(base) kungs@kungs-MacPro DockerLearning % eval $(docker-machine env yanpenggong1)
(base) kungs@kungs-MacPro DockerLearning % docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
yanpenggong1 * vmware Running tcp://172.16.247.6:2376 v19.03.12
(base) kungs@kungs-MacPro DockerLearning % echo $DOCKER_HOST
tcp://172.16.247.6:2376
(base) kungs@kungs-MacPro DockerLearning % docker-machine active
yanpenggong1
(base) kungs@kungs-MacPro DockerLearning %
ID 参数 参数说明
1 active 查看当前激活状态的 Docker 主机。
2 config 查看当前激活状态 Docker 主机的连接信息。
3 create 创建 Docker 主机
4 env 显示连接到某个主机需要的环境变量
5 inspect 以 json 格式输出指定Docker的详细信息
6 ip 获取指定 Docker 主机的地址
7 kill 直接杀死指定的 Docker 主机
8 ls 列出所有的管理主机
9 provision 重新配置指定主机
10 regenerate-certs 某个主机重新生成 TLS 信息
11 restart 重启指定的主机
12 rm 删除某台 Docker 主机,对应的虚拟机也会被删除
13 ssh 通过 SSH 连接到主机上,执行命令
14 scp 在 Docker 主机之间以及 Docker 主机和本地主机之间通过 scp 远程复制数据
15 mount 使用 SSHFS 从计算机装载或卸载目录
16 start 启动一个指定的 Docker 主机,如果对象是个虚拟机,该虚拟机将被启动
17 status 获取指定 Docker 主机的状态(包括:Running、Paused、Saved、Stopped、Stopping、Starting、Error)等
18 stop 停止一个指定的 Docker 主机
19 upgrade 将一个指定主机的 Docker 版本更新为最新
20 url 获取指定 Docker 主机的监听 URL
21 version 显示 Docker Machine 的版本或者主机 Docker 版本
22 help 显示帮助信息

9. Swarm集群管理

==这块内容都是基于macbook下的Docker进行操作的。==

9.1 简介

Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。

支持的工具包括但不限于以下各项:

  • Dokku
  • Docker Compose
  • Docker Machine
  • Jenkins

9.2 原理

swarm 集群由管理节点(manager)工作节点(work node)构成。

  • swarm mananger:负责整个集群的管理工作包括集群配置、服务管理等所有跟集群有关的工作。
  • work node:即图中的 available node,主要负责运行相应的服务来执行任务(task)。

9.3 使用

以下示例,以 Docker Machinevmware 进行介绍,确保你的主机已安装 vmware

9.3.1 创建 swarm 集群管理节点(manager)

创建 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
(base) kungs@kungs-MacPro DockerLearning % docker-machine create -driver vmware swarm-manager
Running pre-create checks...
Creating machine...
(swarm-manager) Copying /Users/kungs/.docker/machine/cache/boot2docker.iso to /Users/kungs/.docker/machine/machines/swarm-manager/boot2docker.iso...
(swarm-manager) Creating SSH key...
(swarm-manager) Creating VM...
(swarm-manager) Starting swarm-manager...
(swarm-manager) Waiting for VM to come online...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env swarm-manager
(base) kungs@kungs-MacPro DockerLearning % docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
swarm-manager - vmware Running tcp://172.16.247.7:2376 v19.03.12
yanpenggong1 * vmware Running tcp://172.16.247.6:2376 v19.03.12
(base) kungs@kungs-MacPro DockerLearning %

初始化 swarm 集群,进行初始化的这台机器,就是集群的管理节点。其中docker swarm init --advertise-addr 172.16.247.7对应的ip是创建机器时分配的 ip。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(base) kungs@kungs-MacPro DockerLearning % docker-machine ssh swarm-manager    
( '>')
/) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
(/-_--_-\) www.tinycorelinux.net

docker@swarm-manager:~$ docker swarm init --advertise-addr 172.16.247.7
Swarm initialized: current node (qrywiizkesql8crxvyy9maafb) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-0wstyhdwc045fcam3n3r6yocmrnlj3eyr0ywkjxni2jp4lk0z3-5jzty2vwepgh1vrnfxplfzq7a 172.16.247.7:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

docker@swarm-manager:~$

以上输出,证明已经初始化成功。需要把以下这行复制出来,在增加工作节点时会用到:

1
docker swarm join --token SWMTKN-1-0wstyhdwc045fcam3n3r6yocmrnlj3eyr0ywkjxni2jp4lk0z3-5jzty2vwepgh1vrnfxplfzq7a 172.16.247.7:2377

9.3.2 创建 swarm 集群工作节点(worker)

这里直接创建好俩台机器,swarm-worker1swarm-worker2

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
(base) kungs@kungs-MacPro DockerLearning % docker-machine create -driver vmware swarm-worker1
Running pre-create checks...
Creating machine...
(swarm-worker1) Copying /Users/kungs/.docker/machine/cache/boot2docker.iso to /Users/kungs/.docker/machine/machines/swarm-worker1/boot2docker.iso...
(swarm-worker1) Creating SSH key...
(swarm-worker1) Creating VM...
(swarm-worker1) Starting swarm-worker1...
(swarm-worker1) Waiting for VM to come online...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env swarm-worker1
(base) kungs@kungs-MacPro DockerLearning % docker-machine create -driver vmware swarm-worker2
Running pre-create checks...
Creating machine...
(swarm-worker2) Copying /Users/kungs/.docker/machine/cache/boot2docker.iso to /Users/kungs/.docker/machine/machines/swarm-worker2/boot2docker.iso...
(swarm-worker2) Creating SSH key...
(swarm-worker2) Creating VM...
(swarm-worker2) Starting swarm-worker2...
(swarm-worker2) Waiting for VM to come online...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env swarm-worker2
(base) kungs@kungs-MacPro DockerLearning % docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
swarm-manager - vmware Running tcp://172.16.247.7:2376 v19.03.12
swarm-worker1 - vmware Running tcp://172.16.247.8:2376 v19.03.12
swarm-worker2 - vmware Running tcp://172.16.247.9:2376 v19.03.12
yanpenggong1 * vmware Running tcp://172.16.247.6:2376 v19.03.12
(base) kungs@kungs-MacPro DockerLearning %

分别进入两个机器里,指定添加至上一步中创建的集群,这里会用到上一步复制的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(base) kungs@kungs-MacPro DockerLearning % docker-machine ssh swarm-worker1
( '>')
/) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
(/-_--_-\) www.tinycorelinux.net

<tyhdwc045fcam3n3r6yocmrnlj3eyr0ywkjxni2jp4lk0z3-5jzty2vwepgh1vrnfxplfzq7a 172.16.247.7:2377
This node joined a swarm as a worker.
docker@swarm-worker1:~$ exit
logout
(base) kungs@kungs-MacPro DockerLearning % docker-machine ssh swarm-worker2
( '>')
/) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
(/-_--_-\) www.tinycorelinux.net

<tyhdwc045fcam3n3r6yocmrnlj3eyr0ywkjxni2jp4lk0z3-5jzty2vwepgh1vrnfxplfzq7a 172.16.247.7:2377
This node joined a swarm as a worker.
docker@swarm-worker2:~$ exit
logout
(base) kungs@kungs-MacPro DockerLearning %

以上数据输出说明已经添加成功。

上图中,由于上一步复制的内容比较长,会被自动截断,实际上在图运行的命令如下:

1
2
docker@swarm-worker2:~$ docker swarm join --token SWMTKN-1-0wstyhdwc045fcam3n3r6yocmrnlj3eyr0ywkjxni2jp4lk0z3-5jzty2vwepgh1vrnfxplfzq7a 172.16.247.7:2377
(base) kungs@kungs-MacPro DockerLearning %

9.3.3 查看集群信息

激活swarm模式

1
2
3
4
5
6
7
(base) kungs@kungs-MacPro DockerLearning % eval $(docker-machine env swarm-manager)
(base) kungs@kungs-MacPro DockerLearning % docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
qrywiizkesql8crxvyy9maafb * swarm-manager Ready Active Leader 19.03.12
rr74dtx0mq67hskuaxt6kgx0w swarm-worker1 Ready Active 19.03.12
am79rf9q1mo0tvu0otketbf4q swarm-worker2 Ready Active 19.03.12
(base) kungs@kungs-MacPro DockerLearning %

进入管理节点,执行: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
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
(base) kungs@kungs-MacPro DockerLearning % docker info                     
Client:
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc., v0.8.2)
compose: Docker Compose (Docker Inc., v2.7.0)
extension: Manages Docker extensions (Docker Inc., v0.2.8)
sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
scan: Docker Scan (Docker Inc., v0.17.0)

Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.12
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: active
NodeID: qrywiizkesql8crxvyy9maafb
Is Manager: true
ClusterID: xgdh712ll4k6nraf2heear3tm
Managers: 1
Nodes: 3
Default Address Pool: 10.0.0.0/8
SubnetSize: 24
Data Path Port: 4789
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 10
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Force Rotate: 0
Autolock Managers: false
Root Rotation In Progress: false
Node Address: 172.16.247.7
Manager Addresses:
172.16.247.7:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 4.19.130-boot2docker
Operating System: Boot2Docker 19.03.12 (TCL 10.1)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 984.3MiB
Name: swarm-manager
ID: XJDY:TYXT:LFCV:CYTK:IDRY:BVD2:AWQO:FYBY:RY6D:YI2D:YC4Z:6LJL
Docker Root Dir: /mnt/sda1/var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
provider=vmware
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine

(base) kungs@kungs-MacPro DockerLearning %

其中

1
2
3
4
5
6
Swarm: active  # docker engine有没有激活swarm模式, 默认是没有(inactive)
NodeID: qrywiizkesql8crxvyy9maafb
Is Manager: true
ClusterID: xgdh712ll4k6nraf2heear3tm
Managers: 1 # 管理节点
Nodes: 3 # 三个节点

9.3.4 部署服务到集群中

注意:跟集群管理有关的任何操作,都是在管理节点上操作的。

以下例子,在一个工作节点上创建一个名为 helloworld 的服务,这里是随机指派给一个工作节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(base) kungs@kungs-MacPro DockerLearning % docker-machine ls                       
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
swarm-manager * vmware Running tcp://172.16.247.7:2376 v19.03.12
swarm-worker1 - vmware Running tcp://172.16.247.8:2376 v19.03.12
swarm-worker2 - vmware Running tcp://172.16.247.9:2376 v19.03.12
yanpenggong1 - vmware Running tcp://172.16.247.6:2376 v19.03.12
(base) kungs@kungs-MacPro DockerLearning %
(base) kungs@kungs-MacPro DockerLearning %
(base) kungs@kungs-MacPro DockerLearning % docker-machine ssh swarm-manager
( '>')
/) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
(/-_--_-\) www.tinycorelinux.net

docker@swarm-manager:~$ docker service create --replicas 1 --name helloworld alpine ping docker.com
05o7ocmbmpm28xcfeu8ci4cml
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
docker@swarm-manager:~$

9.3.5 查看服务部署情况

查看 helloworld 服务运行在哪个节点上,可以看到目前是在 swarm-worker2 节点:

1
2
3
4
docker@swarm-manager:~$ docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bpopbylx99di helloworld.1 alpine:latest swarm-worker2 Running Running about a minute ago
docker@swarm-manager:~$

查看 helloworld 部署的具体信息:

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
docker@swarm-manager:~$ docker service inspect --pretty helloworld                                                                          

ID: 05o7ocmbmpm28xcfeu8ci4cml
Name: helloworld
Service Mode: Replicated
Replicas: 1
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: alpine:latest@sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a
Args: ping docker.com
Init: false
Resources:
Endpoint Mode: vip

docker@swarm-manager:~$

9.3.6 扩展集群服务

将上述的 helloworld 服务扩展到俩个节点。

1
2
3
4
5
6
7
8
9
10
docker@swarm-manager:~$ docker service ps helloworld 
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bpopbylx99di helloworld.1 alpine:latest swarm-worker2 Running Running about an hour ago
docker@swarm-manager:~$ docker service scale helloworld=2
helloworld scaled to 2
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
docker@swarm-manager:~$

可以看到已经从一个节点,扩展到两个节点。

1
2
3
4
5
docker@swarm-manager:~$ docker service ps helloworld     
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bpopbylx99di helloworld.1 alpine:latest swarm-worker2 Running Running about an hour ago
vr81swcln6s9 helloworld.2 alpine:latest swarm-manager Running Running 45 seconds ago
docker@swarm-manager:~$

9.3.7 删除服务

1
2
3
4
5
docker@swarm-manager:~$ docker service rm helloworld 
helloworld
docker@swarm-manager:~$ docker service ps helloworld
no such service: helloworld
docker@swarm-manager:~$

命令 docker service ps helloworld 查看是否已删除

9.3.8 滚动升级服务

介绍 redis 版本如何滚动升级至更高版本。这里创建一个 3.0.5 版本的 redis。

1
2
3
4
5
6
7
8
9
10
11
12
docker@swarm-manager:~$ docker service create --replicas 1 --name redis --update-delay 10s redis:3.0.5 
image redis:3.0.5 could not be accessed on a registry to record
its digest. Each node will access redis:3.0.5 independently,
possibly leading to different nodes running different
versions of the image.

t25x2wtwzxlkaybsijmshdjel
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
docker@swarm-manager:~$

滚动升级 redis 。

1
2
3
4
5
docker@swarm-manager:~$ docker service ps redis                                                       
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
k9yx1lkg8mef redis.1 redis:3.0.7 swarm-manager Running Running 10 seconds ago
ouanlbtgnjo9 \_ redis.1 redis:3.0.5 swarm-manager Shutdown Shutdown 10 seconds ago
docker@swarm-manager:~$

看图可以知道 redis 的版本已经从 3.0.5 升级到了 3.0.8,说明服务已经升级成功。

9.3.9 停止某个节点接收新的任务

查看所有的节点:

1
2
3
4
5
6
docker@swarm-manager:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
qrywiizkesql8crxvyy9maafb * swarm-manager Ready Active Leader 19.03.12
rr74dtx0mq67hskuaxt6kgx0w swarm-worker1 Ready Active 19.03.12
am79rf9q1mo0tvu0otketbf4q swarm-worker2 Ready Active 19.03.12
docker@swarm-manager:~$

可以看到目前所有的节点都是 Active, 可以接收新的任务分配。

停止节点 swarm-worker2:

1
2
3
4
5
6
7
8
docker@swarm-manager:~$ docker node update --availability drain swarm-worker2
swarm-worker2
docker@swarm-manager:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
qrywiizkesql8crxvyy9maafb * swarm-manager Ready Active Leader 19.03.12
rr74dtx0mq67hskuaxt6kgx0w swarm-worker1 Ready Active 19.03.12
am79rf9q1mo0tvu0otketbf4q swarm-worker2 Ready Drain 19.03.12
docker@swarm-manager:~$

注意:swarm-worker2 状态变为 Drain。不会影响到集群的服务,只是 swarm-worker2 节点不再接收新的任务,集群的负载能力有所下降。

可以通过以下命令重新激活节点:

1
2
3
4
5
6
7
8
docker@swarm-manager:~$ docker node update --availability active swarm-worker2
swarm-worker2
docker@swarm-manager:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
qrywiizkesql8crxvyy9maafb * swarm-manager Ready Active Leader 19.03.12
rr74dtx0mq67hskuaxt6kgx0w swarm-worker1 Ready Active 19.03.12
am79rf9q1mo0tvu0otketbf4q swarm-worker2 Ready Active 19.03.12
docker@swarm-manager:~$

10. Docker 安装软件

10.1 Docker 安装 Centos

Ubuntu 是基于 Debian 的 Linux 操作系统。

10.1.1 查看可用的 Ubuntu 版本

访问 Ubuntu 镜像库地址: https://hub.docker.com/_/ubuntu?tab=tags&page=1。

也可以在下拉列表中找到其他想要的版本。

10.1.2 拉取最新版的 Ubuntu 镜像

docker pull ubuntudocker pull ubuntu:latest

1
2
3
4
5
6
7
8
[root@localhost DockerTest]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
6e3729cf69e0: Pull complete
Digest: sha256:27cb6e6ccef575a4698b66f5de06c7ecd61589132d5a91d098f7f3f9285415a9
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
[root@localhost DockerTest]#

10.1.3 查看本地镜像

1
2
3
4
[root@localhost DockerTest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
[root@localhost DockerTest]#

可以看到我们已经安装了最新版本的 ubuntu。

10.1.4 运行容器,并且可以通过 exec 命令进入 ubuntu 容器

1
2
3
[root@localhost DockerTest]# docker run -itd --name ubuntu-test1 ubuntu
c281416b5c63869c864b8521819bf4c25e8097eff3bf273bee752ae41f265301
[root@localhost DockerTest]#

10.1.5安装成功

通过 docker ps 命令查看容器的运行信息:

1
2
3
4
[root@localhost DockerTest]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c281416b5c63 ubuntu "bash" About a minute ago Up About a minute ubuntu-test1
[root@localhost DockerTest]#

10.2 Docker 安装CentOS

CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux(RHEL) 依照开放源代码规定发布的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定性的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。

10.2.1 查看可用的 CentOS 版本

访问 CentOS 镜像库地址:https://hub.docker.com/_/centos?tab=tags&page=1。

10.2.2 拉取指定版本的 CentOS 镜像,这里我们安装指定版本为例(centos7):

1
2
3
4
5
6
7
[root@localhost DockerTest]# docker pull centos:centos7
centos7: Pulling from library/centos
2d473b07cdd5: Pull complete
Digest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
Status: Downloaded newer image for centos:centos7
docker.io/library/centos:centos7
[root@localhost DockerTest]#

10.2.3 查看本地镜像

1
2
3
4
5
[root@localhost DockerTest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
centos centos7 eeb6ee3f44bd 16 months ago 204MB
[root@localhost DockerTest]#

10.2.4 运行容器,并且可以通过 exec 命令进入 CentOS 容器。

1
2
3
[root@localhost DockerTest]# docker run -itd --name centos-test centos:centos7
81cbdd935383d55fd41a7947e580310920d0e948d1d8bea80a696b767f437a33
[root@localhost DockerTest]#

10.2.5 安装成功

通过 docker ps 命令查看容器的运行信息:

1
2
3
4
5
[root@localhost DockerTest]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81cbdd935383 centos:centos7 "/bin/bash" 18 seconds ago Up 13 seconds centos-test
c281416b5c63 ubuntu "bash" 31 minutes ago Up 31 minutes ubuntu-test1
[root@localhost DockerTest]#

10.3 Docker 安装 Nginx

Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务 。

10.3.1 查看可用的 Nginx 版本

访问 Nginx 镜像库地址: https://hub.docker.com/_/nginx?tab=tags。

docker search nginx 命令来查看可用版本:

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 DockerTest]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 17948 [OK]
linuxserver/nginx An Nginx container, brought to you by LinuxS… 183
bitnami/nginx Bitnami nginx Docker Image 150 [OK]
ubuntu/nginx Nginx, a high-performance reverse proxy & we… 75
bitnami/nginx-ingress-controller Bitnami Docker Image for NGINX Ingress Contr… 23 [OK]
rancher/nginx-ingress-controller 11
kasmweb/nginx An Nginx image based off nginx:alpine and in4
ibmcom/nginx-ingress-controller Docker Image for IBM Cloud Private-CE (Commu… 4
bitnami/nginx-exporter 3
bitnami/nginx-ldap-auth-daemon 3
rancher/nginx 2
circleci/nginx This image is for internal use 2
rancher/nginx-ingress-controller-defaultbackend 2
rapidfort/nginx RapidFort optimized, hardened image for NGINX 2
vmware/nginx 2
vmware/nginx-photon 1
bitnami/nginx-intel 1
wallarm/nginx-ingress-controller Kubernetes Ingress Controller with Wallarm e… 1
ibmcom/nginx-ingress-controller-ppc64le Docker Image for IBM Cloud Private-CE (Commu… 0
rancher/nginx-conf 0
rapidfort/nginx-official RapidFort optimized, hardened image for NGIN… 0
ibmcom/nginx-ppc64le Docker image for nginx-ppc64le 0
rancher/nginx-ssl 0
rapidfort/nginx-ib RapidFort optimized, hardened image for NGIN… 0
continuumio/nginx-ingress-ws 0
[root@localhost DockerTest]#

10.3.2 取最新版的 Nginx 镜像

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost DockerTest]# docker pull nginx:latest
latest: Pulling from library/nginx
8740c948ffd4: Pull complete
d2c0556a17c5: Pull complete
c8b9881f2c6a: Pull complete
693c3ffa8f43: Pull complete
8316c5e80e6d: Pull complete
b2fe3577faa4: Pull complete
Digest: sha256:b8f2383a95879e1ae064940d9a200f67a6c79e710ed82ac42263397367e7cc4e
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@localhost DockerTest]#

10.3.3 查看本地镜像是否已安装了 nginx:

1
2
3
4
5
6
[root@localhost DockerTest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest a99a39d070bf 6 days ago 142MB
ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
centos centos7 eeb6ee3f44bd 16 months ago 204MB
[root@localhost DockerTest]#

可以看到我们已经安装了最新版本(latest)的 nginx 镜像。

10.3.4 运行容器

1
2
3
[root@localhost DockerTest]# docker run --name nginx-test -p 8080:80 -d nginx
5f1b0abb64ab9704b2f6f175f1d6e5fd5e1c36b39740c3c4341743d821129a12
[root@localhost DockerTest]#

参数说明:

  • —name nginx-test:容器名称。
  • -p 8080:80: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
  • -d nginx: 设置容器在在后台一直运行。

10.3.5 安装成功

通过浏览器可以直接访问 8080 端口的 nginx 服务:

10.4 Docker 安装 Node.js

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,是一个让 JavaScript 运行在服务端的开发平台。

10.4.1 查看可用的 Node 版本

访问 Node 镜像库地址: https://hub.docker.com/_/node?tab=tags。

docker search node 命令来查看可用版本:

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 DockerTest]# docker search node
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
node Node.js is a JavaScript-based platform for s… 12278 [OK]
mongo-express Web-based MongoDB admin interface, written w… 1274 [OK]
nodered/node-red Low-code programming for event-driven applic… 545
nodered/node-red-docker Deprecated - older Node-RED Docker images. 357 [OK]
circleci/node Node.js is a JavaScript-based platform for s… 130
kindest/node sigs.k8s.io/kind node image 78
bitnami/node Bitnami Node.js Docker Image 69 [OK]
cimg/node The CircleCI Node.js Docker Convenience Imag… 14
opendronemap/nodeodm Automated build for NodeODM 10 [OK]
bitnami/node-exporter Bitnami Node Exporter Docker Image 9 [OK]
appdynamics/nodejs-agent Agent for monitoring Node.js applications 5
wallarm/node Wallarm: end-to-end API security solution 5 [OK]
nodered/node-red-dev Dev/Test builds for Node-RED project (NOT st… 4
sysdig/node-image-analyzer In cluster component that allows scanning im… 2
okteto/node 2
openwhisk/nodejs6action Apache OpenWhisk runtime for Node.js v6 Acti… 2 [OK]
bitnami/node-snapshot 1
ibmcom/node-exporter-ppc64le Docker Image for IBM Cloud Private-CE (Commu… 0
ibmcom/node-exporter Docker Image for IBM Cloud Private-CE (Commu… 0
docker/node-agent-k8s 0
ibmcom/nodejs-mobile-foundation 0
rancher/node-simulator 0
ibmcom/node-for-redis 0
purestorage/node-config image for configuring node to install tools … 0
vmware/node Node.js base built on top of Photon OS 0 [OK]
[root@localhost DockerTest]#

10.4.2 取最新版的 node 镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost DockerTest]# docker pull node:latest
latest: Pulling from library/node
bbeef03cda1f: Pull complete
f049f75f014e: Pull complete
56261d0e6b05: Pull complete
9bd150679dbd: Pull complete
5b282ee9da04: Pull complete
8bc43c905b24: Pull complete
3ce9e21024ae: Pull complete
36d91be124f1: Pull complete
7d6b04e90455: Pull complete
Digest: sha256:c1d6d7364e956b061d62241c362b3cd0856beba066ec60e25523a169e2137623
Status: Downloaded newer image for node:latest
docker.io/library/node:latest
[root@localhost DockerTest]#

10.4.3查看本地镜像是否已安装了 node

1
2
3
4
5
6
7
[root@localhost DockerTest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
node latest 51bd6c84a7f2 6 days ago 998MB
nginx latest a99a39d070bf 6 days ago 142MB
ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
centos centos7 eeb6ee3f44bd 16 months ago 204MB
[root@localhost DockerTest]#

可以看到我们已经安装了最新版本(latest)的 node 镜像。

10.4.4 运行容器

1
2
3
[root@localhost DockerTest]# docker run -itd --name node-test node
5c3af81aab8da4da7d4bed00142711c9f565557eae37b9ce2ca2799e35f6eed3
[root@localhost DockerTest]#

参数说明:

  • —name node-test:容器名称。

10.4.5 安装成功

1
2
3
4
[root@localhost DockerTest]# docker exec -it node-test /bin/bash
root@5c3af81aab8d:/# node -v
v19.4.0
root@5c3af81aab8d:/#

11. Docker命令大全

11.1 容器生命周期管理

11.1.1 run

创建一个新的容器并运行一个命令

  1. 语法

    1
    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

    OPTIONS说明:

    • -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
    • -d: 后台运行容器,并返回容器ID;
    • -i: 以交互模式运行容器,通常与 -t 同时使用;
    • -P: 随机端口映射,容器内部端口随机映射到主机的端口
    • -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
    • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
    • —name=”nginx-lb”: 为容器指定一个名称;
    • —dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
    • —dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
    • -h “mars”: 指定容器的hostname;
    • -e username=”ritchie”: 设置环境变量;
    • —env-file=[]: 从指定文件读入环境变量;
    • —cpuset=”0-2” or —cpuset=”0,1,2”: 绑定容器到指定CPU运行;
    • -m :设置容器使用内存最大值;
    • —net=”bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
    • —link=[]: 添加链接到另一个容器;
    • —expose=[]: 开放一个端口或一组端口;
    • —volume , -v: 绑定一个卷
  2. 实例

    使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。

    1
    docker run --name mynginx -d nginx:latest

    使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。

    1
    docker run -P -d nginx:latest

    使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。

    1
    docker run -p 80:80 -v /data:/data -d nginx:latest

    绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。

    1
    $ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash

    使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。

    1
    2
    [root@localhost DockerTest]# docker run -it nginx:latest /bin/bash
    root@9f7e293c70ab:/#

    在 Docker 容器退出时,默认容器内部的文件系统仍然被保留,以方便调试并保留用户数据。

    但是,对于 foreground 容器,由于其只是在开发调试过程中短期运行,其用户数据并无保留的必要,因而可以在容器启动时设置 —rm 选项,这样在容器退出时就能够自动清理容器内部的文件系统。

    1
    docker run --rm yanpenggong1

    1
    docker run --rm=true yanpenggong1

    ==注意==:—rm 选项不能与 -d 同时使用(或者说同时使用没有意义),即只能自动清理 foreground 容器,不能自动清理detached容器。

    ==注意==,—rm 选项也会清理容器的匿名data volumes。

    执行 docker run 命令带 —rm命令选项,等价于在容器退出后,执行 docker rm -v

11.1.2 start|stop|restart

  1. 语法

    • 启动一个或多个已经被停止的容器

      1
      docker start [OPTIONS] CONTAINER [CONTAINER...]
    • 停止一个运行中的容器

      1
      docker stop [OPTIONS] CONTAINER [CONTAINER...]
    • 重启容器

      1
      docker restart [OPTIONS] CONTAINER [CONTAINER...]
  2. 实例

    • 启动已被停止的容器 yanpenggong1

      1
      docker start yanpenggong1
    • 停止运行中的容器 yanpenggong1

      1
      docker stop yanpenggong1
    • 重启容器 yanpenggong1

      1
      docker restart yanpenggong1

11.1.3 kill

杀掉一个运行中的容器

  1. 语法

    1
    docker kill [OPTIONS] CONTAINER [CONTAINER...]

    OPTIONS说明:

    • -s : 向容器发送一个信号
  2. 实例

    杀掉运行中的容器mynginx

    1
    2
    [root@localhost DockerTest]# docker kill -s KILL mynginx
    mynginx

11.1.4 rm

删除一个或多个容器

  1. 语法

    1
    docker rm [OPTIONS] CONTAINER [CONTAINER...]

    OPTIONS说明:

    • -f : 通过 SIGKILL 信号强制删除一个运行中的容器。
    • -l : 移除容器间的网络连接,而非容器本身。
    • -v : 删除与容器关联的卷。
  2. 实例

    • 强制删除容器 db01、db02:

      1
      docker rm -f db01 db02
    • 移除容器 nginx01 对容器 db01 的连接,连接名 db:

      1
      docker rm -l db 
    • 删除容器 nginx01, 并删除容器挂载的数据卷:

      1
      docker rm -v nginx01
  • 删除所有已经停止的容器:

    1
    docker rm $(docker ps -a -q)

11.1.5 pause|unpause

  1. 语法

    • 暂停容器中所有的进程。

      1
      docker pause CONTAINER [CONTAINER...]
    • 恢复容器中所有的进程。

      1
      docker unpause CONTAINER [CONTAINER...]
  2. 实例

    • 暂停数据库容器db01提供服务。

      1
      docker pause db01
    • 恢复数据库容器 db01 提供服务。

      1
      docker unpause db01

11.1.6 create

创建一个新的容器但不启动它

用法同 docker run

  1. 语法

    1
    docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
  2. 实例

    使用docker镜像 nginx:latest 创建一个容器,并将容器命名为yanpenggong1

    1
    2
    3
    [root@localhost DockerTest]# docker create  --name yanpenggong1  nginx:latest
    ab1aa65cb3d1d6180de62b890a9caddaada09e8edaf43f1facd3872eb1053784
    [root@localhost DockerTest]#

11.1.7 exec

在运行的容器中执行命令

  1. 语法

    1
    docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

    OPTIONS说明:

    • -d :分离模式: 在后台运行
    • -i :即使没有附加也保持STDIN 打开
    • -t :分配一个伪终端
  2. 实例

    前期准备工作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [root@localhost DockerTest]# docker exec -it yanpenggong1 /bin/bash
    root@ab1aa65cb3d1:/# apt-get update
    ...
    root@ab1aa65cb3d1:/# apt-get upgrade
    Reading package lists... Done
    Building dependency tree... Done
    Reading state information... Done
    Calculating upgrade... Done
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
    root@ab1aa65cb3d1:/# apt-get install vim
    ...
    root@ab1aa65cb3d1:/# vim /root/yanpenggong.sh
    root@ab1aa65cb3d1:/# cat /root/yanpenggong.sh
    echo "Welcome yanpenggong, Come on!"

    在容器 mynginx 中以交互模式执行容器内 /root/yanpenggong1.sh 脚本:

    1
    2
    3
    [root@localhost DockerTest]# docker exec -it yanpenggong1 /bin/bash /root/yanpenggong.sh
    Welcome yanpenggong, Come on!
    [root@localhost DockerTest]#

    在容器 mynginx 中开启一个交互模式的终端:

    1
    2
    [root@localhost DockerTest]# docker exec -it yanpenggong1 /bin/bash
    root@ab1aa65cb3d1:/#

    也可以通过 docker ps -a 命令查看已经在运行的容器,然后使用容器 ID 进入容器。

    查看已经在运行的容器 ID:

    1
    2
    3
    4
    5
    6
    [root@localhost DockerTest]# docker ps -a 
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
    ...
    ab1aa65cb3d1 nginx:latest "/docker-entrypoint.…" 2 hours ago Up 30 minutes 80/tcp yanpenggong1
    ...
    [root@localhost DockerTest]#

    第一列的 ab1aa65cb3d1 就是容器 ID。

    通过 exec 命令对指定的容器执行 bash:

    1
    2
    [root@localhost DockerTest]# docker exec -it ab1aa65cb3d1 /bin/bash
    root@ab1aa65cb3d1:/#

11.2 容器操作

11.2.1 ps

列出容器

  1. 语法

    1
    docker ps [OPTIONS]

    OPTIONS说明:

    • -a :显示所有的容器,包括未运行的。

    • -f :根据条件过滤显示的内容。

  • —format :指定返回值的模板文件。

  • -l :显示最近创建的容器。

  • -n :列出最近创建的n个容器。

  • —no-trunc :不截断输出。

  • -q :静默模式,只显示容器编号。

  • -s :显示总的文件大小。

  1. 实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@localhost DockerTest]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    565fab9cc1d6 nginx "/docker-entrypoint.…" 2 hours ago Up 2 hours 80/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp nginx-yanpenggong
    ab1aa65cb3d1 nginx:latest "/docker-entrypoint.…" 2 hours ago Up 45 minutes 80/tcp yanpenggong1
    d4048088ff57 php:8.2.1-fpm "docker-php-entrypoi…" 19 hours ago Up 19 hours 9000/tcp myphp-fpm
    5c3af81aab8d node "docker-entrypoint.s…" 21 hours ago Up 21 hours node-test
    5f1b0abb64ab nginx "/docker-entrypoint.…" 22 hours ago Up 22 hours 0.0.0.0:8080->80/tcp, :::8080->80/tcp nginx-test
    81cbdd935383 centos:centos7 "/bin/bash" 22 hours ago Up 22 hours centos-test
    c281416b5c63 ubuntu "bash" 22 hours ago Up 22 hours ubuntu-test1
    [root@localhost DockerTest]#

    输出详情介绍:

    • CONTAINER ID: 容器 ID。

    • IMAGE: 使用的镜像。

    • COMMAND: 启动容器时运行的命令。

    • CREATED: 容器的创建时间。

    • STATUS: 容器状态。状态有7种:

      • created(已创建)

      • restarting(重启中)

      • running(运行中)

      • removing(迁移中)

      • paused(暂停)

      • exited(停止)

      • dead(死亡)

    • PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。

    • NAMES: 自动分配的容器名称。

    列出最近创建的5个容器信息。

    1
    2
    3
    4
    5
    6
    7
    8
    [root@localhost DockerTest]# docker ps -n 5
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    565fab9cc1d6 nginx "/docker-entrypoint.…" 2 hours ago Up 2 hours 80/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp nginx-yanpenggong
    e7ed1ae97d71 nginx:latest "/docker-entrypoint.…" 2 hours ago Exited (0) 2 hours ago friendly_pascal
    ab1aa65cb3d1 nginx:latest "/docker-entrypoint.…" 2 hours ago Up 46 minutes 80/tcp yanpenggong1
    9ee8936ebfb4 nginx:latest "/docker-entrypoint.…" 2 hours ago Exited (0) 2 hours ago cool_herschel
    9f7e293c70ab nginx:latest "/docker-entrypoint.…" 2 hours ago Exited (127) 2 hours ago angry_liskov
    [root@localhost DockerTest]#

    列出所有创建的容器ID。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [root@localhost DockerTest]# docker ps -a -q
    565fab9cc1d6
    e7ed1ae97d71
    ab1aa65cb3d1
    9ee8936ebfb4
    9f7e293c70ab
    e9ec935b0a03
    d4048088ff57
    5c3af81aab8d
    5f1b0abb64ab
    81cbdd935383
    c281416b5c63
    [root@localhost DockerTest]#

    根据条件过滤显示的内容:

    • 根据标签过滤

      1
      2
      3
      4
      5
      6
      7
      8
      9
      [root@localhost DockerTest]# docker run -d --name=nginx-labelset --label color=blue nginx
      76febf58a85a95ae00dc36ac7397fa4b95e666090686a02dc5e1e9d344b5da38
      [root@localhost DockerTest]# docker ps --filter "label=color"
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      76febf58a85a nginx "/docker-entrypoint.…" 22 seconds ago Up 21 seconds 80/tcp nginx-labelset
      [root@localhost DockerTest]# docker ps --filter "label=color=blue"
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      76febf58a85a nginx "/docker-entrypoint.…" 28 seconds ago Up 27 seconds 80/tcp nginx-labelset
      [root@localhost DockerTest]#
    • 根据名称过滤

      1
      2
      3
      4
      [root@localhost DockerTest]# docker ps --filter "name=nginx-labelset"
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      76febf58a85a nginx "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp nginx-labelset
      [root@localhost DockerTest]#
    • 根据状态过滤

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      [root@localhost DockerTest]# docker ps -a --filter "exited=0"
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      e7ed1ae97d71 nginx:latest "/docker-entrypoint.…" 2 hours ago Exited (0) 2 hours ago friendly_pascal
      9ee8936ebfb4 nginx:latest "/docker-entrypoint.…" 2 hours ago Exited (0) 2 hours ago cool_herschel
      [root@localhost DockerTest]# docker ps --filter status=running
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      76febf58a85a nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp nginx-labelset
      565fab9cc1d6 nginx "/docker-entrypoint.…" 2 hours ago Up 2 hours 80/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp nginx-yanpenggong
      ab1aa65cb3d1 nginx:latest "/docker-entrypoint.…" 2 hours ago Up 51 minutes 80/tcp yanpenggong1
      d4048088ff57 php:8.2.1-fpm "docker-php-entrypoi…" 19 hours ago Up 19 hours 9000/tcp myphp-fpm
      5c3af81aab8d node "docker-entrypoint.s…" 22 hours ago Up 22 hours node-test
      5f1b0abb64ab nginx "/docker-entrypoint.…" 22 hours ago Up 22 hours 0.0.0.0:8080->80/tcp, :::8080->80/tcp nginx-test
      81cbdd935383 centos:centos7 "/bin/bash" 22 hours ago Up 22 hours centos-test
      c281416b5c63 ubuntu "bash" 22 hours ago Up 22 hours ubuntu-test1
      [root@localhost DockerTest]# docker ps --filter status=paused
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      [root@localhost DockerTest]#
    • 根据镜像过滤

      • 镜像名称

        1
        2
        3
        [root@localhost DockerTest]# docker ps --filter ancestor=yanpenggong1
        CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
        [root@localhost DockerTest]#
      • 镜像ID

        1
        2
        3
        [root@localhost DockerTest]# docker ps --filter ancestor=ab1aa65cb3d1
        CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
        [root@localhost DockerTest]#
    • 根据启动顺序过滤

      1
      2
      [root@localhost DockerTest]# docker ps --filter before=565fab9cc1d6
      [root@localhost DockerTest]# docker ps --filter since=565fab9cc1d6

11.2.2 inspect

获取容器/镜像的元数据。

  1. 语法

    1
    docker inspect [OPTIONS] NAME|ID [NAME|ID...]

    OPTIONS说明:

    • -f :指定返回值的模板文件。
    • -s :显示总的文件大小。
    • —type :为指定类型返回 JSON。
  2. 实例

    获取镜像 mysql:5.7 的元信息。

    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    [root@localhost DockerTest]# docker inspect mysql:5.7
    [
    {
    "Id": "sha256:e982339a20a53052bd5f2b2e8438b3c95c91013f653ee781a67934cd1f9f9631",
    "RepoTags": [
    "mysql:5.7"
    ],
    "RepoDigests": [
    "mysql@sha256:f04fc2e2f01e65d6e2828b4cce2c4761d9258aee71d989e273b2ae309f44a945"
    ],
    "Parent": "",
    "Comment": "",
    "Created": "2023-01-17T21:08:43.190102558Z",
    "Container": "0986b6641b52d0f008c86df95549764df209daf54453c8ae1585823822ea24e7",
    "ContainerConfig": {
    "Hostname": "0986b6641b52",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "ExposedPorts": {
    "3306/tcp": {},
    "33060/tcp": {}
    },
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "GOSU_VERSION=1.14",
    "MYSQL_MAJOR=5.7",
    "MYSQL_VERSION=5.7.41-1.el7",
    "MYSQL_SHELL_VERSION=8.0.32-1.el7"
    ],
    "Cmd": [
    "/bin/sh",
    "-c",
    "#(nop) ",
    "CMD [\"mysqld\"]"
    ],
    "Image": "sha256:dbef667589a9b91b3a5c92717cd272365c6af916b218e357277837b0f447e3e3",
    "Volumes": {
    "/var/lib/mysql": {}
    },
    "WorkingDir": "",
    "Entrypoint": [
    "docker-entrypoint.sh"
    ],
    "OnBuild": null,
    "Labels": {}
    },
    "DockerVersion": "20.10.12",
    "Author": "",
    "Config": {
    "Hostname": "",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "ExposedPorts": {
    "3306/tcp": {},
    "33060/tcp": {}
    },
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "GOSU_VERSION=1.14",
    "MYSQL_MAJOR=5.7",
    "MYSQL_VERSION=5.7.41-1.el7",
    "MYSQL_SHELL_VERSION=8.0.32-1.el7"
    ],
    "Cmd": [
    "mysqld"
    ],
    "Image": "sha256:dbef667589a9b91b3a5c92717cd272365c6af916b218e357277837b0f447e3e3",
    "Volumes": {
    "/var/lib/mysql": {}
    },
    "WorkingDir": "",
    "Entrypoint": [
    "docker-entrypoint.sh"
    ],
    "OnBuild": null,
    "Labels": null
    },
    "Architecture": "amd64",
    "Os": "linux",
    "Size": 451547844,
    "VirtualSize": 451547844,
    "GraphDriver": {
    "Data": {
    "LowerDir": "/var/lib/docker/overlay2/ef0961e2e6aab1506df05b62e97e01d08e701b726b54537b24b9c4c16c024b2a/diff:/var/lib/docker/overlay2/614ebd76596a654735feb8e2f02179b830dc01e18fc73ff51ba369eb9d4305f1/diff:/var/lib/docker/overlay2/beff48d6417ae0ec536cf6885716e36cba4816b436419774c952e6c975d286a2/diff:/var/lib/docker/overlay2/c4877779ab5e00499e5a0cbf2e316c3ff3067a5355ee24d2b249564c15f5650e/diff:/var/lib/docker/overlay2/b1804f8b6eab76ec28f336e6deba72d9d6b081732f77774dd64ae60f6ccd6ca6/diff:/var/lib/docker/overlay2/fde9ec916ffc6d5a4eb7002f98541a1a5e1512e247ba1c6dcd0209cad5583957/diff:/var/lib/docker/overlay2/41e4c8924e80a6a72a376bc9a3be6ae1fde0874652918e5c5fd803e023c18845/diff:/var/lib/docker/overlay2/ad8ede93da1142c1dc043658204ab5fd2402b8fd2a24ce921406e3fa8e3a1987/diff:/var/lib/docker/overlay2/63d5fabc079fd5e454df0710c2dcbb2ee39d190c44f97a84016fc133ea9ac25f/diff:/var/lib/docker/overlay2/cc89d6ef19a9bbf01a30cc7b5eb97142cc9239359ceb99545c1a770360aea90a/diff",
    "MergedDir": "/var/lib/docker/overlay2/c310ac5e33624289534acb8d52701991e2342bad5a12698f493858d666aa3d6e/merged",
    "UpperDir": "/var/lib/docker/overlay2/c310ac5e33624289534acb8d52701991e2342bad5a12698f493858d666aa3d6e/diff",
    "WorkDir": "/var/lib/docker/overlay2/c310ac5e33624289534acb8d52701991e2342bad5a12698f493858d666aa3d6e/work"
    },
    "Name": "overlay2"
    },
    "RootFS": {
    "Type": "layers",
    "Layers": [
    "sha256:62d9c4cbe8f4b26952ebb533b5336bf7af791db2b4288df65c9a685e1f2530cd",
    "sha256:49769e21013b6fea06035a5dcdbed32ce7c17b66b8a19eab8ce626a492d4e045",
    "sha256:1a26f263a6af50cde950eb9059948fbc1ae332b27d4f248064838e8233d98781",
    "sha256:1ab9edd16f9eb635e5240ae4167f8556b742f3b95047c98d43893f2e2bffe064",
    "sha256:56a71f69f1a80e8e96b53f062f47abb507c71dd418a8cf9037dd141e45dd2b96",
    "sha256:45968403dd22f9dfd92bc4c0a3349a0919abe64a62ebf85ecd3dbc386e17b15d",
    "sha256:f4bb02745d0337d503a510f28b98ac101bb9916eff4bd51b6ea108fffc01b567",
    "sha256:c1f1b5039e40f8c152f16f83d2bd382aea116e5d26779096dfb87a612f4366c8",
    "sha256:e974776afbe2457e7c63f3d6b8c66aa4942414252d5af613904eacb11d0f4b44",
    "sha256:868b2e381adfd7f4f912f3add73f60e9ec7f3c18937d7f08ffec29d60a24b0e7",
    "sha256:5c542b9ec644bfc9eeace71cf555f9b7ca6ad7e657eb7863aebc1367e1b101d7"
    ]
    },
    "Metadata": {
    "LastTagTime": "0001-01-01T00:00:00Z"
    }
    }
    ]
    [root@localhost DockerTest]#

    获取正在运行的容器 mysql-test 的 IP,注意这里mysql-test是容器名称。

    1
    2
    3
    [root@localhost DockerTest]# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql-test
    172.17.0.10
    [root@localhost DockerTest]#

11.2.3 top

查看容器中运行的进程信息,支持 ps 命令参数。

  1. 语法

    1
    docker top [OPTIONS] CONTAINER [ps OPTIONS]

    容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看 container 中正在运行的进程。

  2. 实例

    查看容器mysql-test 的进程信息。

    1
    2
    3
    4
    [root@localhost DockerTest]# docker top mysql-test
    UID PID PPID C STIME TTY TIME CMD
    polkitd 42708 42687 0 00:43 pts/0 00:00:09 mysqld
    [root@localhost DockerTest]#

    查看所有运行容器的进程信息。

    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
    [root@localhost DockerTest]# for i in  `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i; done

    UID PID PPID C STIME TTY TIME CMD
    polkitd 42708 42687 0 00:43 pts/0 00:00:09 mysqld

    UID PID PPID C STIME TTY TIME CMD
    root 39930 39910 0 Jan17 ? 00:00:00 nginx: master process nginx -g daemon off;
    101 39980 39930 0 Jan17 ? 00:00:00 nginx: worker process
    101 39981 39930 0 Jan17 ? 00:00:00 nginx: worker process

    UID PID PPID C STIME TTY TIME CMD
    root 34104 34083 0 Jan17 ? 00:00:00 nginx: master process nginx -g daemon off;
    101 34173 34104 0 Jan17 ? 00:00:00 nginx: worker process
    101 34174 34104 0 Jan17 ? 00:00:00 nginx: worker process

    UID PID PPID C STIME TTY TIME CMD
    root 36525 36505 0 Jan17 ? 00:00:00 nginx: master process nginx -g daemon off;
    101 36575 36525 0 Jan17 ? 00:00:00 nginx: worker process
    101 36576 36525 0 Jan17 ? 00:00:00 nginx: worker process

    UID PID PPID C STIME TTY TIME CMD
    root 31274 31254 0 Jan17 ? 00:00:08 php-fpm: master process (/usr/local/etc/php-fpm.conf)
    33 31320 31274 0 Jan17 ? 00:00:00 php-fpm: pool www
    33 31321 31274 0 Jan17 ? 00:00:00 php-fpm: pool www

    UID PID PPID C STIME TTY TIME CMD
    root 23383 23361 0 Jan17 pts/0 00:00:00 node

    UID PID PPID C STIME TTY TIME CMD
    root 22888 22868 0 Jan17 ? 00:00:00 nginx: master process nginx -g daemon off;
    101 22952 22888 0 Jan17 ? 00:00:00 nginx: worker process
    101 22953 22888 0 Jan17 ? 00:00:00 nginx: worker process

    UID PID PPID C STIME TTY TIME CMD
    root 22489 22469 0 Jan17 pts/0 00:00:00 /bin/bash

    UID PID PPID C STIME TTY TIME CMD
    root 22094 22073 0 Jan17 pts/0 00:00:00 bash
    [root@localhost DockerTest]#

11.2.4 attach/exec

连接到正在运行中的容器。

  1. 语法

    1
    docker attach [OPTIONS] CONTAINER

    attach 上去的容器必须正在运行,可以同时连接上同一个container来共享屏幕(与screen命令的attach类似)。

    官方文档中说attach后可以通过CTRL-C来detach,但实际上经过我的测试,如果container当前在运行bash,CTRL-C自然是当前行的输入,没有退出;如果container当前正在前台运行进程,如输出nginx的access.log日志,CTRL-C不仅会导致退出容器,而且还stop了。这不是我们想要的,detach的意思按理应该是脱离容器终端,但容器依然运行。好在attach是可以带上--sig-proxy=false来确保CTRL-DCTRL-C不会关闭容器。

  2. 实例

    容器mynginx将访问日志指到标准输出,连接到容器查看访问信息。

    当docker容器在 “-d”守护态运行的时候,比如通过supervisord控制两个程序非守护态运行:
    ssh -D
    tomcat
    那么这个时候,用户就无法直接进入到容器中去,docker attach 容器id 就会一直卡着。
    因为此时容器运行的进程是ssh,而不是/bin/bash 也没有虚拟终端(-it)参数,所以是进入不到的,
    那么这种情况下,该如何attach进去并进入到一个/bin/bash里呢?

    ==可以用docker exec -it containerID /bin/bash方式进入容器==

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    [root@localhost DockerTest]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    d5a81f38372c mysql:5.7 "docker-entrypoint.s…" 3 hours ago Up 16 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-test
    76febf58a85a nginx "/docker-entrypoint.…" 5 hours ago Up 5 hours 80/tcp nginx-labelset
    565fab9cc1d6 nginx "/docker-entrypoint.…" 7 hours ago Up 7 hours 80/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp nginx-yanpenggong
    ab1aa65cb3d1 nginx:latest "/docker-entrypoint.…" 7 hours ago Up 5 hours 80/tcp yanpenggong1
    d4048088ff57 php:8.2.1-fpm "docker-php-entrypoi…" 24 hours ago Up 24 hours 9000/tcp myphp-fpm
    5c3af81aab8d node "docker-entrypoint.s…" 26 hours ago Up 26 hours node-test
    5f1b0abb64ab nginx "/docker-entrypoint.…" 26 hours ago Up 26 hours 0.0.0.0:8080->80/tcp, :::8080->80/tcp nginx-test
    81cbdd935383 centos:centos7 "/bin/bash" 26 hours ago Up 26 hours centos-test
    c281416b5c63 ubuntu "bash" 27 hours ago Up 27 hours
    [root@localhost DockerTest]# docker exec -it d5a81f38372c /bin/bash
    bash-4.2# exit
    exit
    [root@localhost DockerTest]# docker exec -it mysql-test /bin/bash
    bash-4.2#

11.2.5 events

从服务器获取实时事件

  1. 语法

    1
    docker events [OPTIONS]

    OPTIONS说明:

    • -f :根据条件过滤事件;
    • —since :从指定的时间戳后显示所有事件;
    • —until :流水时间显示到指定的时间为止;
  2. 实例

    • 显示docker 2016年7月1日后的所有事件。

      1
      2
      3
      4
      5
      6
      [root@localhost DockerTest]# docker events  --since="1467302400"
      2023-01-17T00:36:22.632702912-05:00 image untag sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de (name=sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de)
      2023-01-17T00:36:22.725821259-05:00 image delete sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de (name=sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de)
      2023-01-17T00:36:53.327637992-05:00 image untag sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557 (name=sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557)
      2023-01-17T00:36:54.752238644-05:00 image delete sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557 (name=sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557)
      ...
    • 显示docker 镜像为mysql:5.6 2016年7月1日后的相关事件。

      1
      2
      3
      4
      5
      6
      7
      [root@localhost DockerTest]# docker events  --since="1467302400"
      2023-01-17T00:36:22.632702912-05:00 image untag sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de (name=sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de)
      2023-01-17T00:36:22.725821259-05:00 image delete sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de (name=sha256:157dcdf23d6c0ebe14bedd910dfa29d224f75ed104757c7866fa708eaefd16de)
      2023-01-17T00:36:53.327637992-05:00 image untag sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557 (name=sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557)
      2023-01-17T00:36:54.752238644-05:00 image delete sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557 (name=sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557)
      2023-01-17T00:37:43.600321934-05:00 container destroy 795555d12b2a0c537b6d8a972241a1f24a27538b241b25afa13c4c45637389de (com.docker.compose.config-hash=ae53e06d500b53a458b03065a6c547dcb1f49fca00638ae785ee3a2f3bbb81eb, com.docker.compose.container-number=1, com.docker.compose.depends_on=, com.docker.compose.image=sha256:8ace02fae412cc7d1ac5b7a10f7f5b7b2a1e1ae6bdc31a92a190a1a8415d412b, com.docker.compose.oneoff=False, com.docker.compose.project=composetest, com.docker.compose.project.config_files=/root/yanpenggong/DEMO/DockerTest/composeTest/docker-compose.yml, com.docker.compose.project.working_dir=/root/yanpenggong/DEMO/DockerTest/composeTest, com.docker.compose.service=redis, com.docker.compose.version=2.14.0, image=redis:alpine, name=composetest-redis-1)
      ...

    如果指定的时间是到秒级的,需要将时间转成时间戳。如果时间为日期的话,可以直接使用,如—since=”2016-07-01”。

    1
    2
    3
    4
    5
    6
    7
    [root@localhost DockerTest]# docker events -f "image"="mysql:5.7" --since="2016-07-01" 
    2023-01-18T00:39:41.140668490-05:00 image pull mysql:5.7 (name=mysql)
    2023-01-18T00:39:41.682132231-05:00 container create f318356c965ba6403e095fe456b63f6172d475ba1097476d4e30beff7246e58d (image=mysql:5.7, name=stupefied_banach)
    2023-01-18T00:39:42.003726040-05:00 container start f318356c965ba6403e095fe456b63f6172d475ba1097476d4e30beff7246e58d (image=mysql:5.7, name=stupefied_banach)
    2023-01-18T00:39:42.439945201-05:00 container die f318356c965ba6403e095fe456b63f6172d475ba1097476d4e30beff7246e58d (exitCode=1, image=mysql:5.7, name=stupefied_banach)
    2023-01-18T00:40:37.076467617-05:00 container start f318356c965ba6403e095fe456b63f6172d475ba1097476d4e30beff7246e58d (image=mysql:5.7, name=stupefied_banach)
    ...

11.2.6 logs

获取容器的日志

  1. 语法

    1
    docker logs [OPTIONS] CONTAINER

    OPTIONS说明:

    • -f : 跟踪日志输出
    • —since :显示某个开始时间的所有日志
    • -t : 显示时间戳
    • —tail :仅列出最新N条容器日志
  2. 实例

    跟踪查看容器mysql-test 的日志输出。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    [root@localhost DockerTest]# docker logs -f mysql-test
    2023-01-18 05:43:33+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.41-1.el7 started.
    2023-01-18 05:43:34+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
    2023-01-18 05:43:34+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.41-1.el7 started.
    2023-01-18 05:43:34+00:00 [Note] [Entrypoint]: Initializing database files
    2023-01-18T05:43:34.342035Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
    2023-01-18T05:43:34.580669Z 0 [Warning] InnoDB: New log files created, LSN=45790
    2023-01-18T05:43:34.613971Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
    2023-01-18T05:43:34.679346Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 0c59ef46-96f3-11ed-adba-0242ac11000a.
    2023-01-18T05:43:34.680219Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
    2023-01-18T05:43:34.769058Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
    2023-01-18T05:43:34.769079Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
    2023-01-18T05:43:34.769519Z 0 [Warning] CA certificate ca.pem is self signed.
    2023-01-18T05:43:34.832020Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
    2023-01-18 05:43:36+00:00 [Note] [Entrypoint]: Database files initialized
    2023-01-18 05:43:36+00:00 [Note] [Entrypoint]: Starting temporary server
    2023-01-18 05:43:36+00:00 [Note] [Entrypoint]: Waiting for server startup
    2023-01-18T05:43:36.752707Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
    2023-01-18T05:43:36.754485Z 0 [Note] mysqld (mysqld 5.7.41) starting as process 124 ...
    2023-01-18T05:43:36.757512Z 0 [Note] InnoDB: PUNCH HOLE support available
    2023-01-18T05:43:36.757535Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
    2023-01-18T05:43:36.757538Z 0 [Note] InnoDB: Uses event mutexes
    ...

    查看容器mysql-test 从2016年7月1日后的最新10条日志。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@localhost DockerTest]# docker logs --since="2022-12-30" --tail=10 mysql-test
    2023-01-18T08:42:41.892365Z 0 [Warning] CA certificate ca.pem is self signed.
    2023-01-18T08:42:41.892405Z 0 [Note] Skipping generation of RSA key pair as key files are present in data directory.
    2023-01-18T08:42:41.892692Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
    2023-01-18T08:42:41.892740Z 0 [Note] IPv6 is available.
    2023-01-18T08:42:41.892749Z 0 [Note] - '::' resolves to '::';
    2023-01-18T08:42:41.892771Z 0 [Note] Server socket created on IP: '::'.
    2023-01-18T08:42:41.894066Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
    2023-01-18T08:42:41.901316Z 0 [Note] Event Scheduler: Loaded 0 events
    2023-01-18T08:42:41.901805Z 0 [Note] mysqld: ready for connections.
    Version: '5.7.41' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
    [root@localhost DockerTest]#

11.2.7 wait

阻塞运行直到容器停止,然后打印出它的退出代码。

  1. 语法

    1
    docker wait [OPTIONS] CONTAINER [CONTAINER...]
  2. 实例

    1
    2
    3
    [root@localhost DockerTest]# docker wait mysql-test
    0
    [root@localhost DockerTest]#

    注意:这里在运行停止容器后才会出现返回的0

11.2.8 export

将文件系统作为一个tar归档文件导出到 STDOUT

  1. 语法

    1
    docker export [OPTIONS] CONTAINER

    OPTIONS说明:

    • -o :将输入内容写到文件。
  2. 实例

    将id为d5a81f38372c的容器按日期保存为tar文件。在本地会发现多了一个mysql-20230118.tar文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [root@localhost DockerTest]# docker ps 
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    d5a81f38372c mysql:5.7 "docker-entrypoint.s…" 4 hours ago Up 1 second 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-test
    76febf58a85a nginx "/docker-entrypoint.…" 5 hours ago Up 5 hours 80/tcp nginx-labelset
    565fab9cc1d6 nginx "/docker-entrypoint.…" 7 hours ago Up 7 hours 80/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp nginx-yanpenggong
    ab1aa65cb3d1 nginx:latest "/docker-entrypoint.…" 7 hours ago Up 6 hours 80/tcp yanpenggong1
    d4048088ff57 php:8.2.1-fpm "docker-php-entrypoi…" 24 hours ago Up 24 hours 9000/tcp myphp-fpm
    5c3af81aab8d node "docker-entrypoint.s…" 27 hours ago Up 27 hours node-test
    5f1b0abb64ab nginx "/docker-entrypoint.…" 27 hours ago Up 27 hours 0.0.0.0:8080->80/tcp, :::8080->80/tcp nginx-test
    81cbdd935383 centos:centos7 "/bin/bash" 27 hours ago Up 27 hours centos-test
    c281416b5c63 ubuntu "bash" 28 hours ago Up 28 hours ubuntu-test1
    [root@localhost DockerTest]# docker export -o mysql-`date +%Y%m%d`.tar d5a81f38372c
    [root@localhost DockerTest]#

11.2.9 port

用于列出指定的容器的端口映射,或者查找将 PRIVATE_PORT NAT 到面向公众的端口。

  1. 语法

    1
    docker port [OPTIONS] CONTAINER [PRIVATE_PORT[/PROTO]]
  2. 实例

    查看容器 mysql-test 的端口映射情况:

    1
    2
    3
    4
    [root@localhost DockerTest]# docker port mysql-test
    3306/tcp -> 0.0.0.0:3306
    3306/tcp -> :::3306
    [root@localhost DockerTest]#

11.2.10 stats

显示容器资源的使用情况,包括:CPU、内存、网络 I/O 等。

  1. 语法

    1
    docker stats [OPTIONS] [CONTAINER...]

    OPTIONS 说明:

    • —all , -a :显示所有的容器,包括未运行的。
    • —format :指定返回值的模板文件。
    • —no-stream :展示当前状态就直接退出了,不再实时更新。
    • —no-trunc :不截断输出。
  2. 实例

    列出所有在运行的容器信息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@localhost DockerTest]# docker stats
    CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
    d5a81f38372c mysql-test 0.10% 175.8MiB / 1.777GiB 9.66% 656B / 0B 3.28MB / 25.4MB 27
    76febf58a85a nginx-labelset 0.00% 2.016MiB / 1.777GiB 0.11% 656B / 0B 139kB / 24.6kB 3
    565fab9cc1d6 nginx-yanpenggong 0.00% 3.027MiB / 1.777GiB 0.17% 8.84MB / 211kB 1.2MB / 22.5kB 3
    ab1aa65cb3d1 yanpenggong1 0.00% 3.398MiB / 1.777GiB 0.19% 20.2MB / 399kB 54.1MB / 84.2MB 3
    d4048088ff57 myphp-fpm 0.01% 4.734MiB / 1.777GiB 0.26% 740B / 0B 0B / 0B 3
    5c3af81aab8d node-test 0.00% 11.73MiB / 1.777GiB 0.64% 782B / 0B 12.7MB / 0B 11
    5f1b0abb64ab nginx-test 0.00% 1.996MiB / 1.777GiB 0.11% 3.45kB / 2.85kB 0B / 15.4kB 3
    81cbdd935383 centos-test 0.00% 392KiB / 1.777GiB 0.02% 824B / 0B 0B / 0B 1
    c281416b5c63 ubuntu-test1 0.00% 560KiB / 1.777GiB 0.03% 1.27kB / 0B 0B / 0B 1

    输出详情介绍:

    • CONTAINER ID 与 NAME: 容器 ID 与名称。

    • CPU % 与 MEM %: 容器使用的 CPU 和内存的百分比。

    • MEM USAGE / LIMIT: 容器正在使用的总内存,以及允许使用的内存总量。

    • NET I/O: 容器通过其网络接口发送和接收的数据量。

    • BLOCK I/O: 容器从主机上的块设备读取和写入的数据量。

    • PIDs: 容器创建的进程或线程数。

    根据容器等 ID 或名称现实信息:

    1
    2
    3
    4
    [root@localhost DockerTest]# docker stats mysql-test 76febf58a85a
    CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
    d5a81f38372c mysql-test 0.11% 175.8MiB / 1.777GiB 9.66% 656B / 0B 3.28MB / 25.4MB 27
    76febf58a85a nginx-labelset 0.00% 2.016MiB / 1.777GiB 0.11% 656B / 0B 139kB / 24.6kB 3

    以 JSON 格式输出:

    1
    2
    3
    [root@localhost DockerTest]# docker stats mysql-test --no-stream --format "{{ json . }}"
    {"BlockIO":"3.28MB / 25.4MB","CPUPerc":"0.08%","Container":"mysql-test","ID":"d5a81f38372c","MemPerc":"9.66%","MemUsage":"175.8MiB / 1.777GiB","Name":"mysql-test","NetIO":"656B / 0B","PIDs":"27"}
    [root@localhost DockerTest]#

    输出指定的信息:

    1
    2
    3
    4
    5
    6
    [root@localhost DockerTest]# docker stats --all --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}" d5a81f38372c nginx-labelset yanpenggong1 centos-test
    CONTAINER CPU % MEM USAGE / LIMIT
    d5a81f38372c 0.10% 175.8MiB / 1.777GiB
    nginx-labelset 0.00% 2.016MiB / 1.777GiB
    yanpenggong1 0.00% 3.398MiB / 1.777GiB
    centos-test 0.00% 392KiB / 1.777GiB

11.3 容器rootfs命令

11.3.1 commit

从容器创建一个新的镜像。

  1. 语法

    1
    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

    OPTIONS说明:

    • -a :提交的镜像作者;
    • -c :使用Dockerfile指令来创建镜像;
    • -m :提交时的说明文字;
    • -p :在commit时,将容器暂停。
  2. 实例

    将容器a404c6c174a2 保存为新的镜像,并添加提交人信息和说明信息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@localhost DockerTest]# docker commit -a "yanpenggong" -m "my apache" mysql-test  mysql:v1
    sha256:aafc21722e07a2c532b197fc85860ad0416a741659d20bd62680e75cceffd5b7
    [root@localhost DockerTest]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    mysql v1 aafc21722e07 25 seconds ago 452MB
    mysql 5.7 e982339a20a5 12 hours ago 452MB
    php 8.2.1-fpm 6c2e0d7fb356 7 days ago 450MB
    node latest 51bd6c84a7f2 7 days ago 998MB
    nginx latest a99a39d070bf 7 days ago 142MB
    ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
    centos centos7 eeb6ee3f44bd 16 months ago 204MB
    [root@localhost DockerTest]#

11.3.2 cp

用于容器与主机之间的数据拷贝。

  1. 语法

    • 将容器中的目录拷贝到主机中

      1
      docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
    • 将主机中的目录拷贝到容器中

      1
      docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

    OPTIONS说明:

    • -L :保持源目标中的链接
  2. 实例

    • 将主机./GGG/pythonFile目录拷贝到容器aafc21722e07/GGG目录下。

      1
      [root@localhost DockerTest]# docker cp ./GGG/pythonFile aafc21722e07:/GGG/
    • 将主机./GGG/pythonFile目录拷贝到容器aafc21722e07中,目录重命名为GGG

      1
      [root@localhost DockerTest]# docker cp ./GGG/pythonFile aafc21722e07:/GGG
    • 将容器aafc21722e07/GGG目录拷贝到主机的./tmp目录中。

      1
      [root@localhost DockerTest]# docker cp aafc21722e07:/GGG ./temp/

11.3.3 diff

检查容器里文件结构的更改。

  1. 语法

    1
    docker diff [OPTIONS] CONTAINER
  2. 实例

    查看容器mysql-test的文件结构更改。

    1
    2
    3
    4
    5
    6
    7
    8
    [root@localhost DockerTest]# docker diff mysql-test
    A /logs
    A /mysql_data
    C /run
    C /run/mysqld
    A /run/mysqld/mysqld.pid
    A /run/mysqld/mysqld.sock
    C /tmp

11.4 镜像仓库

11.4.1 login

  1. 语法

    • 登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub

      1
      docker login [OPTIONS] [SERVER]
  • 登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub

    1
    docker logout [OPTIONS] [SERVER]

    OPTIONS说明:

  • -u :登陆的用户名

  • -p :登陆的密码
  1. 实例

    • 登陆到Docker Hub

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      [root@localhost DockerTest]# docker login
      Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
      Username: kungs
      Password:
      WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
      Configure a credential helper to remove this warning. See
      https://docs.docker.com/engine/reference/commandline/login/#credentials-store

      Login Succeeded
      [root@localhost DockerTest]#
    • 登出Docker Hub

      1
      2
      3
      [root@localhost DockerTest]# docker logout
      Removing login credentials for https://index.docker.io/v1/
      [root@localhost DockerTest]#

11.4.2 pull

从镜像仓库中拉取或者更新指定镜像

  1. 语法

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

    OPTIONS说明:

    • -a :拉取所有 tagged 镜像
    • —disable-content-trust :忽略镜像的校验,默认开启
  2. 实例

    从Docker Hub下载 python 最新版镜像。\

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    [root@localhost DockerTest]# docker pull python
    Using default tag: latest
    latest: Pulling from library/python
    bbeef03cda1f: Already exists
    f049f75f014e: Already exists
    56261d0e6b05: Already exists
    9bd150679dbd: Already exists
    5b282ee9da04: Already exists
    03f027d5e312: Pull complete
    db6ee1ace097: Pull complete
    0a86d528f1ea: Pull complete
    4cfb032ae58b: Pull complete
    Digest: sha256:a3c0c6766535f85f18e7304d3a0111de5208d73935bcf1b024217005ad5ce195
    Status: Downloaded newer image for python:latest
    docker.io/library/python:latest
    [root@localhost DockerTest]#

    从Docker Hub下载REPOSITORYpython 的所有镜像。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    [root@localhost DockerTest]# docker pull -a python
    2: Pulling from library/python
    7e2b2a5af8f6: Pull complete
    09b6f03ffac4: Pull complete
    dc3f0c679f0f: Pull complete
    fd4b47407fc3: Pull complete
    b32f6bf7d96d: Pull complete
    6f4489a7e4cf: Pull complete
    af4b99ad9ef0: Pull complete
    39db0bc48c26: Pull complete
    acb4a89489fc: Pull complete
    Digest: sha256:cfa62318c459b1fde9e0841c619906d15ada5910d625176e24bf692cf8a2601d
    2-alpine: Pulling from library/python
    aad63a933944: Pull complete
    259d822268fb: Pull complete
    10ba96d218d3: Pull complete
    44ba9f6a4209: Pull complete
    Digest: sha256:724d0540eb56ffaa6dd770aa13c3bc7dfc829dec561d87cb36b2f5b9ff8a760a
    ...
    [root@localhost DockerTest]#

    获取指定编译平台的镜像:

    1
    docker pull --platform=arm64|amd64... image_name

11.4.3 push

将本地的镜像上传到镜像仓库,要先登陆到镜像仓库

  1. 语法

    1
    docker push [OPTIONS] NAME[:TAG]

    OPTIONS说明:

    • —disable-content-trust :忽略镜像的校验,默认开启
  2. 实例

    上传本地镜像mysql:v1 到镜像仓库中。

    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
    [root@localhost DockerTest]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    mysql v1 aafc21722e07 21 minutes ago 452MB
    python latest b44268c8cbc0 10 hours ago 932MB
    mysql 5.7 e982339a20a5 13 hours ago 452MB
    php 8.2.1-fpm 6c2e0d7fb356 7 days ago 450MB
    node latest 51bd6c84a7f2 7 days ago 998MB
    nginx latest a99a39d070bf 7 days ago 142MB
    ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
    centos centos7 eeb6ee3f44bd 16 months ago 204MB
    python 2-alpine3.10 dc740d648004 2 years ago 68.9MB
    python 2-alpine 8579e446340f 2 years ago 71.1MB
    python 2-alpine3.11 8579e446340f 2 years ago 71.1MB
    python 2 68e7be49c28c 2 years ago 902MB
    python 2-alpine3.8 fcbce699af86 3 years ago 58.4MB
    python 2-alpine3.6 dd4c05fcb8d5 3 years ago 56.5MB
    python 2-alpine3.7 ec0218200ad6 3 years ago 58.2MB
    python 2-alpine3.4 5fdd069daf25 4 years ago 73.5MB
    [root@localhost DockerTest]# docker push mysql:v1
    The push refers to repository [docker.io/library/mysql]
    d9cfab7e0ea4: Preparing
    5c542b9ec644: Preparing
    868b2e381adf: Preparing
    e974776afbe2: Preparing
    c1f1b5039e40: Preparing
    f4bb02745d03: Waiting
    45968403dd22: Waiting
    56a71f69f1a8: Waiting
    1ab9edd16f9e: Waiting
    1a26f263a6af: Waiting
    49769e21013b: Waiting
    62d9c4cbe8f4: Waiting
    denied: requested access to the resource is denied
    [root@localhost DockerTest]#

从Docker Hub查找镜像

  1. 语法

    1
    docker search [OPTIONS] TERM

    OPTIONS说明:

    • —automated :只列出 automated build类型的镜像;
    • —no-trunc :显示完整的镜像描述;
    • -f <过滤条件>:列出收藏数不小于指定值的镜像。
  2. 实例

    从 Docker Hub 查找所有镜像名包含 python,并且收藏数大于 10 的镜像

    1
    2
    3
    4
    5
    6
    7
    8
    [root@localhost DockerTest]# docker search -f stars=10 python
    NAME DESCRIPTION STARS OFFICIAL AUTOMATED
    python Python is an interpreted, interactive, objec… 8323 [OK]
    pypy PyPy is a fast, compliant alternative implem… 355 [OK]
    circleci/python Python is an interpreted, interactive, objec… 61
    hylang Hy is a Lisp dialect that translates express… 53 [OK]
    bitnami/python Bitnami Python Docker Image 25 [OK]
    [root@localhost DockerTest]#

    参数说明:

    • NAME: 镜像仓库源的名称

    • DESCRIPTION: 镜像的描述

    • OFFICIAL: 是否 docker 官方发布

    • stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。

    • AUTOMATED: 自动构建。

11.5 本地镜像管理

11.5.1 images

列出本地镜像。

  1. 语法

    1
    docker images [OPTIONS] [REPOSITORY[:TAG]]

    OPTIONS说明:

    • -a :列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);
    • —digests :显示镜像的摘要信息;
    • -f :显示满足条件的镜像;
    • —format :指定返回值的模板文件;
    • —no-trunc :显示完整的镜像信息;
    • -q :只显示镜像ID。
  2. 实例

    • 查看本地镜像列表。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      [root@localhost DockerTest]# docker images
      REPOSITORY TAG IMAGE ID CREATED SIZE
      mysql v1 aafc21722e07 27 minutes ago 452MB
      python latest b44268c8cbc0 10 hours ago 932MB
      mysql 5.7 e982339a20a5 13 hours ago 452MB
      php 8.2.1-fpm 6c2e0d7fb356 7 days ago 450MB
      node latest 51bd6c84a7f2 7 days ago 998MB
      nginx latest a99a39d070bf 7 days ago 142MB
      ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
      centos centos7 eeb6ee3f44bd 16 months ago 204MB
      python 2-alpine3.10 dc740d648004 2 years ago 68.9MB
      python 2-alpine 8579e446340f 2 years ago 71.1MB
      python 2-alpine3.11 8579e446340f 2 years ago 71.1MB
      python 2 68e7be49c28c 2 years ago 902MB
      python 2-alpine3.8 fcbce699af86 3 years ago 58.4MB
      python 2-alpine3.6 dd4c05fcb8d5 3 years ago 56.5MB
      python 2-alpine3.7 ec0218200ad6 3 years ago 58.2MB
      python 2-alpine3.4 5fdd069daf25 4 years ago 73.5MB
      [root@localhost DockerTest]#
    • 列出本地镜像中 REPOSITORY 为centos的镜像列表。

      1
      2
      3
      4
      [root@localhost DockerTest]# docker images centos
      REPOSITORY TAG IMAGE ID CREATED SIZE
      centos centos7 eeb6ee3f44bd 16 months ago 204MB
      [root@localhost DockerTest]#

11.5.2 rmi

删除本地一个或多个镜像。

  1. 语法

    1
    docker rmi [OPTIONS] IMAGE [IMAGE...]

    OPTIONS说明:

    • -f :强制删除;
    • —no-prune :不移除该镜像的过程镜像,默认移除;
  2. 实例

    强制删除本地镜像mysql:v2

    1
       
  1. prune 命令用来删除不再使用的 docker 对象。

    删除所有未被 tag 标记和未被容器使用的镜像:

    1
    2
    3
    $ docker image prune
    WARNING! This will remove all dangling images.
    Are you sure you want to continue? [y/N] y

    删除所有未被容器使用的镜像:

    1
    $ docker image prune -a

    删除所有停止运行的容器:

    1
    $ docker container prune

    删除所有未被挂载的卷:

    1
    $ docker volume prune

    删除所有网络:

    1
    $ docker network prune

    删除 docker 所有资源:

    1
    $ docker system prune
  2. docker system prune 命令:

    1
    2
    3
    4
    5
    This will remove:
    - all stopped containers
    - all networks not used by at least one container
    - all dangling images
    - all dangling build cache

    删除停止的容器、删除所有未被容器使用的网络、删除所有none的镜像。

11.5.3 tag

标记本地镜像,将其归入某一仓库。

  1. 语法

    1
    docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
  2. 实例

    将镜像centos:centos7标记为yanpenggong/centos:centos7 镜像。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    [root@localhost DockerTest]# docker tag centos:centos7 yanpenggong/centos:centos7
    [root@localhost DockerTest]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    mysql v1 aafc21722e07 17 hours ago 452MB
    python latest b44268c8cbc0 27 hours ago 932MB
    mysql 5.7 e982339a20a5 29 hours ago 452MB
    php 8.2.1-fpm 6c2e0d7fb356 7 days ago 450MB
    node latest 51bd6c84a7f2 7 days ago 998MB
    nginx latest a99a39d070bf 7 days ago 142MB
    ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
    centos centos7 eeb6ee3f44bd 16 months ago 204MB
    yanpenggong/centos centos7 eeb6ee3f44bd 16 months ago 204MB
    python 2-alpine3.10 dc740d648004 2 years ago 68.9MB
    python 2-alpine 8579e446340f 2 years ago 71.1MB
    python 2-alpine3.11 8579e446340f 2 years ago 71.1MB
    python 2 68e7be49c28c 2 years ago 902MB
    python 2-alpine3.8 fcbce699af86 3 years ago 58.4MB
    python 2-alpine3.6 dd4c05fcb8d5 3 years ago 56.5MB
    python 2-alpine3.7 ec0218200ad6 3 years ago 58.2MB
    python 2-alpine3.4 5fdd069daf25 4 years ago 73.5MB
    [root@localhost DockerTest]#

11.5.4 build

用于使用 Dockerfile 创建镜像。

  1. 语法

    1
    docker build [OPTIONS] PATH | URL | -

    OPTIONS说明:

    • —build-arg=[] :设置镜像创建时的变量;
    • —cpu-shares :设置 cpu 使用权重;
    • —cpu-period :限制 CPU CFS周期;
    • —cpu-quota :限制 CPU CFS配额;
    • —cpuset-cpus :指定使用的CPU id;
    • —cpuset-mems :指定使用的内存 id;
    • —disable-content-trust :忽略校验,默认开启;
    • -f :指定要使用的Dockerfile路径;
    • —force-rm :设置镜像过程中删除中间容器;
    • —isolation :使用容器隔离技术;
    • —label=[] :设置镜像使用的元数据;
    • -m :设置内存最大值;
    • —memory-swap :设置Swap的最大值为内存+swap,”-1”表示不限swap;
    • —no-cache :创建镜像的过程不使用缓存;
    • —pull :尝试去更新镜像的新版本;
    • —quiet, -q :安静模式,成功后只输出镜像 ID;
    • —rm :设置镜像成功后删除中间容器;
    • —shm-size :设置/dev/shm的大小,默认值是64M;
    • —ulimit :Ulimit配置。
    • —squash :将 Dockerfile 中所有的操作压缩为一层。
    • —tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
    • —network: 默认 default。在构建期间设置RUN指令的网络模式
  2. 实例

    使用当前目录的 Dockerfile 创建镜像,标签为 yanpenggong/centos:centos7

    1
    [root@localhost DockerTest]# docker build -t yanpenggong/centos:centos7 . 

    使用URL github.com/creack/docker-firefox 的 Dockerfile 创建镜像。

    1
    [root@localhost DockerTest]# docker build github.com/creack/docker-firefox

    也可以通过 -f Dockerfile 文件的位置:

    1
    [root@localhost DockerTest]# docker build -f /path/to/a/Dockerfile .

    在 Docker 守护进程执行 Dockerfile 中的指令前,首先会对 Dockerfile 进行语法检查,有语法错误时会返回:

    1
    2
    3
    [root@localhost DockerTest]# docker build -t test/myapp .
    Sending build context to Docker daemon 2.048 kB
    Error response from daemon: Unknown instruction: RUNCMD

11.5.5 history

查看指定镜像的创建历史。

  1. 语法

    1
    docker history [OPTIONS] IMAGE

    OPTIONS说明:

    • -H :以可读的格式打印镜像大小和日期,默认为true;
    • —no-trunc :显示完整的提交记录;
    • -q :仅列出提交记录ID。
  2. 实例

    查看本地镜像yanpenggong/centos:centos7的创建历史。

    1
    2
    3
    4
    5
    6
    [root@localhost DockerTest]# docker history yanpenggong/centos:centos7
    IMAGE CREATED CREATED BY SIZE COMMENT
    eeb6ee3f44bd 16 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
    <missing> 16 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
    <missing> 16 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
    [root@localhost DockerTest]#

11.5.6 save

将指定镜像保存成 tar 归档文件。

  1. 语法

    1
    docker save [OPTIONS] IMAGE [IMAGE...]

    OPTIONS 说明:

    • -o :输出到的文件。
  2. 实例

    将镜像 yanpenggong/centos:centos7 生成 my_centos_v1.tar 文档

    1
    2
    3
    4
    [root@localhost DockerTest]# docker save -o my_centos_v1.tar yanpenggong/centos:centos7
    [root@localhost DockerTest]# ll my_centos_v1.tar
    -rw-------. 1 root root 211696640 Jan 18 21:23 my_centos_v1.tar
    [root@localhost DockerTest]#

export 和 import 导出的是一个容器的快照, 不是镜像本身, 也就是说没有 layer。

dockerfile 里的 workdir, entrypoint 之类的所有东西都会丢失,commit 过的话也会丢失。

快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也更大。

  • docker save 保存的是镜像(image),docker export 保存的是容器(container);
  • docker load 用来载入镜像包,docker import 用来载入容器包,但两者都会恢复为镜像;
  • docker load 不能对载入的镜像重命名,而 docker import 可以为镜像指定新名称。

11.5.7 load

导入使用 docker save 命令导出的镜像。

  1. 语法

    1
    docker load [OPTIONS]

    OPTIONS 说明:

    • —input , -i : 指定导入的文件,代替 STDIN。
    • —quiet , -q : 精简输出信息。
  2. 实例

    导入镜像:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [root@localhost DockerTest]# docker image ls
    REPOSITORY TAG IMAGE ID CREATED SIZE
    [root@localhost DockerTest]# docker load < busybox.tar.gz
    Loaded image: busybox:latest
    [root@localhost DockerTest]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    busybox latest 769b9341d937 7 weeks ago 2.489 MB
    [root@localhost DockerTest]# docker load --input fedora.tar
    Loaded image: fedora:rawhide
    Loaded image: fedora:20
    [root@localhost DockerTest]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    busybox latest 769b9341d937 7 weeks ago 2.489 MB
    fedora rawhide 0d20aec6529d 7 weeks ago 387 MB
    fedora 20 58394af37342 7 weeks ago 385.5 MB
    fedora heisenbug 58394af37342 7 weeks ago 385.5 MB
    fedora latest 58394af37342 7 weeks ago 385.5 MB
    [root@localhost DockerTest]#

11.5.8 import

从归档文件中创建镜像。

  1. 语法

    1
    docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

    OPTIONS说明:

    • -c :应用docker 指令创建镜像;
    • -m :提交时的说明文字;
  2. 实例

    从镜像归档文件my_centos_v1.tar创建镜像,命名为yanpenggong/centos:v1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [root@localhost DockerTest]# docker import my_centos_v1.tar yanpenggong/centos:v1
    sha256:623ecbbf2e8d746fdfc3e62f8eb4e1268c9bd43e6f3e6ad5c08b52cc2c01e7ca
    [root@localhost DockerTest]# docker image ls
    REPOSITORY TAG IMAGE ID CREATED SIZE
    yanpenggong/centos v1 623ecbbf2e8d 3 seconds ago 212MB
    mysql v1 aafc21722e07 17 hours ago 452MB
    python latest b44268c8cbc0 27 hours ago 932MB
    mysql 5.7 e982339a20a5 29 hours ago 452MB
    php 8.2.1-fpm 6c2e0d7fb356 7 days ago 450MB
    node latest 51bd6c84a7f2 7 days ago 998MB
    nginx latest a99a39d070bf 7 days ago 142MB
    ubuntu latest 6b7dfa7e8fdb 5 weeks ago 77.8MB
    centos centos7 eeb6ee3f44bd 16 months ago 204MB
    yanpenggong/centos centos7 eeb6ee3f44bd 16 months ago 204MB
    [root@localhost DockerTest]#

11.6 info|version

11.6.1 info

显示 Docker 系统信息,包括镜像和容器数。

  1. 语法

    1
    docker info [OPTIONS]
  2. 实例

    查看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
    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
    [root@localhost DockerTest]# docker info
    Client:
    Context: default
    Debug Mode: false
    Plugins:
    app: Docker App (Docker Inc., v0.9.1-beta3)
    buildx: Docker Buildx (Docker Inc., v0.9.1-docker)
    scan: Docker Scan (Docker Inc., v0.23.0)

    Server:
    Containers: 13
    Running: 9
    Paused: 0
    Stopped: 4
    Images: 16
    Server Version: 20.10.22
    Storage Driver: overlay2
    Backing Filesystem: xfs
    Supports d_type: true
    Native Overlay Diff: true
    userxattr: false
    Logging Driver: json-file
    Cgroup Driver: cgroupfs
    Cgroup Version: 1
    Plugins:
    Volume: local
    Network: bridge host ipvlan macvlan null overlay
    Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
    Swarm: inactive
    Runtimes: io.containerd.runtime.v1.linux runc io.containerd.runc.v2
    Default Runtime: runc
    Init Binary: docker-init
    containerd version: 5b842e528e99d4d4c1686467debf2bd4b88ecd86
    runc version: v1.1.4-0-g5fd4c4d
    init version: de40ad0
    Security Options:
    seccomp
    Profile: default
    Kernel Version: 3.10.0-1160.81.1.el7.x86_64
    Operating System: CentOS Linux 7 (Core)
    OSType: linux
    Architecture: x86_64
    CPUs: 2
    Total Memory: 1.777GiB
    Name: localhost
    ID: V755:HONZ:LVHJ:WBDK:OTF4:B7TK:QTMF:RLPZ:Z55T:4PAM:EE6C:SQFK
    Docker Root Dir: /var/lib/docker
    Debug Mode: false
    Username: kungs
    Registry: https://index.docker.io/v1/
    Labels:
    Experimental: false
    Insecure Registries:
    127.0.0.0/8
    Live Restore Enabled: false

    [root@localhost DockerTest]#

11.6.2 version

显示 Docker 版本信息。

  1. 语法

    1
    docker version [OPTIONS]

    OPTIONS说明:

    • -f :指定返回值的模板文件。
  2. 实例

    显示 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
    [root@localhost DockerTest]# docker version
    Client: Docker Engine - Community
    Version: 20.10.22
    API version: 1.41
    Go version: go1.18.9
    Git commit: 3a2c30b
    Built: Thu Dec 15 22:30:24 2022
    OS/Arch: linux/amd64
    Context: default
    Experimental: true

    Server: Docker Engine - Community
    Engine:
    Version: 20.10.22
    API version: 1.41 (minimum version 1.12)
    Go version: go1.18.9
    Git commit: 42c8b31
    Built: Thu Dec 15 22:28:33 2022
    OS/Arch: linux/amd64
    Experimental: false
    containerd:
    Version: 1.6.15
    GitCommit: 5b842e528e99d4d4c1686467debf2bd4b88ecd86
    runc:
    Version: 1.1.4
    GitCommit: v1.1.4-0-g5fd4c4d
    docker-init:
    Version: 0.19.0
    GitCommit: de40ad0
    [root@localhost DockerTest]#

12. Docker在线资源及国内镜像

12.1 Docker资源

12.2 Docker国内镜像