您现在的位置是:首页 >学无止境 >Docker 教程网站首页学无止境

Docker 教程

编程洪同学 2024-06-17 11:19:27
简介Docker 教程

请添加图片描述

??‍? 热爱摄影的程序员
??‍? 喜欢编码的设计师
?? 擅长设计的剪辑师
??‍? 一位高冷无情的编码爱好者
大家好,我是中国 IT 工程师摘星人
欢迎分享 / 收藏 / 赞 / 在看!

这份 Docker 教程是一份简明扼要的指南,旨在帮助初学者快速入门 Docker 容器化技术。通过清晰的步骤和示例,您将学习如何安装和配置 Docker,创建和管理容器,以及部署应用程序。教程涵盖了常用的 Docker 命令和概念,并介绍了容器网络、数据管理和镜像构建等关键主题。无论您是开发人员、系统管理员还是对容器化技术感兴趣的任何人,本教程都将为您提供实用的知识和技能,助您在 Docker 领域迈出坚实的第一步。

文章目录

1 Docker 概述

Docker 是一种开源的容器化平台,用于构建、分发和运行应用程序。它允许开发者将应用程序及其依赖项打包成一个称为容器的轻量级、可移植的单元。
Docker 的核心概念是容器,它是一个独立且可执行的软件包,包含了应用程序的所有必要组件和配置。容器隔离了应用程序与其运行环境,使得应用程序能够在不同的计算机上以一致的方式运行,而不受底层操作系统和硬件的影响。
使用 Docker,开发者可以通过 Dockerfile 描述应用程序的构建过程,定义所需的依赖项和配置。然后,使用 Docker 命令将 Dockerfile 构建成一个镜像,镜像是容器的基础,类似于一个应用程序的模板。镜像可以被分发和共享,可以在任何支持 Docker 的环境中运行。
通过 Docker,开发者可以实现快速、一致和可重复的应用程序部署。应用程序及其依赖项打包成容器后,可以在不同的环境中轻松部署和扩展。Docker 还提供了一系列工具和功能,如容器编排、网络管理和存储管理,以帮助简化应用程序的管理和运维。
总而言之,Docker 提供了一种轻量级、可移植和可扩展的应用程序打包和部署解决方案,使开发者能够更高效地构建、交付和运行应用程序。
2022-09-07-09.jpeg

2 Docker 的应用场景

Docker 在软件开发和运维中有广泛的应用场景,包括以下几个方面:

  1. 应用程序打包和交付:Docker 提供了一种将应用程序及其依赖项打包成容器的方式,使得应用程序可以在不同的环境中以一致的方式运行。这使得应用程序的部署和交付变得更加简单和可靠。
  2. 环境一致性和隔离:Docker 容器提供了隔离的运行环境,使得应用程序与其依赖项相互隔离,并与底层操作系统和硬件解耦。这种隔离性和一致性可以确保应用程序在不同的环境中具有相同的行为,减少了由环境差异引起的问题。
  3. 持续集成和持续部署:Docker 可以与持续集成和持续部署(CI/CD)工具集成,实现自动化的构建、测试和部署流程。开发者可以使用 Docker 来创建包含应用程序和测试环境的容器,从而简化 CI/CD 流程并提高开发效率。
  4. 微服务架构:Docker 的轻量级和可扩展性使其成为构建和管理微服务架构的理想选择。每个微服务可以打包为一个独立的容器,便于部署、扩展和管理。Docker 还提供了容器编排工具(如 Docker Compose 和 Kubernetes),用于管理多个容器的编排和协调。
  5. 跨平台和跨云的应用部署:由于 Docker 容器的可移植性,应用程序可以在不同的操作系统和云平台上运行,而无需修改代码。这使得应用程序在多云环境中部署变得更加简单和灵活。

总之,Docker 在构建、交付和运行应用程序方面具有广泛的应用场景,可以提高开发效率、简化部署流程,并支持现代化的应用架构和多云环境。

3 Docker 的优点

Docker 具有以下几个主要优点:

  1. 轻量和快速启动:Docker 容器是轻量级的,只包含应用程序及其运行所需的依赖项,不需要额外的操作系统。这使得容器的启动速度非常快,并且占用的系统资源较少。
  2. 环境一致性和隔离性:Docker 容器提供了隔离的运行环境,使应用程序与其依赖项相互隔离,并与底层操作系统和硬件解耦。这种隔离性和一致性确保应用程序在不同的环境中具有相同的行为,减少了由环境差异引起的问题。
  3. 可移植性:Docker 容器可以在不同的操作系统和云平台上运行,而无需修改代码。这种可移植性使得应用程序在不同的环境中部署变得更加简单和灵活。
  4. 快速部署和扩展:Docker 容器可以快速部署和启动,无需手动配置和安装依赖项。同时,Docker 提供了扩展性的特性,可以根据需求快速增加或减少容器的数量,实现弹性的应用程序部署和管理。
  5. 持续集成和持续部署:Docker 可以与持续集成和持续部署(CI/CD)工具集成,实现自动化的构建、测试和部署流程。使用 Docker,开发者可以创建包含应用程序和测试环境的容器,从而简化 CI/CD 流程并提高开发效率。
  6. 生态系统和社区支持:Docker 拥有庞大的生态系统和活跃的社区支持,提供了丰富的工具、库和文档资源。这使得开发者能够更轻松地获取帮助、分享经验并使用各种扩展和集成功能。

综上所述,Docker 的轻量性、环境一致性、可移植性、快速部署和扩展性,以及与持续集成和持续部署的集成能力,使其成为现代应用程序开发和部署的强大工具。

Docker 为什么比虚拟机快?
Docker 比虚拟机快的主要原因有以下几点:

  1. 轻量级:Docker 容器是轻量级的,它们共享宿主操作系统的内核,不需要额外的操作系统实例。相比之下,虚拟机需要独立的操作系统,包括内核和系统资源的复制,因此虚拟机更为庞大和笨重。
  2. 快速启动:Docker 容器的启动速度非常快。由于容器共享宿主操作系统的内核,不需要启动完整的操作系统实例,因此容器的启动时间通常只需几秒钟。相比之下,虚拟机的启动时间通常需要数十秒甚至数分钟。
  3. 资源利用率高:Docker 容器可以共享宿主操作系统的资源,包括内存、CPU 和存储等。相比之下,虚拟机需要独立分配一定的资源给每个虚拟机实例,这导致了资源利用率的浪费。
  4. 更少的性能开销:由于 Docker 容器直接运行在宿主操作系统上,与宿主系统之间的通信开销较小,不需要进行硬件级别的虚拟化。相比之下,虚拟机需要通过虚拟化层与宿主系统通信,增加了一定的性能开销。
  5. 更高的可扩展性:由于 Docker 容器的轻量性和快速启动特性,它们可以更容易地进行扩展和部署。在大规模的应用部署中,Docker 容器可以更快速地启动和复制,以适应变化的负载需求。

总体而言,Docker 容器相对于虚拟机具有更高的性能和更低的资源开销,这使得它们成为构建和部署应用程序的更快速和高效的选择。然而,虚拟机仍然在某些场景下具有优势,例如需要隔离完全独立的操作系统环境或运行不同类型的操作系统时。

4 Docker 的基本组成

4.1 Docker 引擎(Docker Engine)

Docker 引擎是 Docker 的核心组件,负责管理和运行容器。它包括一个守护进程(Docker daemon)和一个命令行接口工具(Docker CLI)。Docker 引擎与宿主操作系统交互,负责创建、启动、停止和销毁容器,并提供容器的管理和监控功能。

4.2 Docker 镜像(Docker Image)

Docker 镜像是容器的基础,类似于一个应用程序的模板。镜像包含了应用程序运行所需的所有文件、依赖项和配置。开发者可以使用 Dockerfile 描述应用程序的构建过程,并通过 Docker 命令将 Dockerfile 构建成一个镜像。镜像可以被分发和共享,并可以用来创建和运行容器。

4.3 Docker 容器(Docker Container)

Docker 容器是 Docker 镜像的实例化运行。每个容器都是一个独立且可执行的软件包,包含了应用程序及其运行所需的依赖项。容器隔离了应用程序与其运行环境,使得应用程序能够在不同的计算机上以一致的方式运行。容器可以通过 Docker 引擎进行创建、启动、停止和销毁。

4.4 Docker 仓库(Docker Registry)

Docker 仓库是用于存储和共享 Docker 镜像的中央存储库。Docker 官方提供了公共的 Docker 仓库,称为 Docker Hub,开发者可以在其中找到各种镜像。此外,还可以搭建私有的 Docker 仓库,用于存储和管理自己的镜像。常用的私有仓库包括 Docker Trusted Registry(DTR)和第三方工具如 Harbor。
docker 仓库.png

除了以上核心组件外,Docker 还提供了其他一些工具和功能,如:

  • Docker Compose:用于定义和管理多个容器组成的应用程序的工具。通过编写一个 YAML 文件,可以定义多个服务和容器之间的关系,以及其依赖项和配置。
  • Docker Swarm:用于构建和管理容器集群的原生容器编排工具。Docker Swarm 允许将多个 Docker 主机组成一个集群,实现容器的高可用性和负载均衡。
  • Kubernetes:一种开源的容器编排平台,用于自动化容器的部署、扩展和管理。Docker 可以与 Kubernetes 集成,共同用于构建和管理复杂的容器化应用程序。

综上所述,Docker 的基本组成包括 Docker 引擎、Docker镜像、Docker 容器和 Docker 仓库,它们共同构成了 Docker 的核心功能和基础架构。通过使用这些组件,开发者可以方便地打包、分发和运行应用程序,并实现快速部署和扩展。此外,Docker 还提供了一些附加工具和功能,如 Docker Compose、Docker Swarm 和 Kubernetes,以满足更复杂的应用场景和需求。这些组件和工具的综合使用使得 Docker 成为一个强大而受欢迎的容器化平台。

5 安装 Docker 引擎

Docker 引擎的安装在不同操作系统上大相径庭,笔者只使用 CentOS 进行安装,其他操作系统安装步骤详见官网。官网-Install Docker Engine

5.1 安装条件

5.1.1 操作系统要求

要安装 Docker Engine,您需要 CentOS 7、CentOS 8 (stream) 或 CentOS 9 (stream) 的维护版本。存档版本不受支持或测试。
centos-extras 必须启用存储库。此存储库默认启用,但如果您已禁用它,则需要 重新启用它
推荐使用 overlay2 存储驱动。

5.1.2 卸载旧版本

旧版本的 Docker 被称为 dockerdocker-engine。如果安装了这些,请卸载它们以及相关的依赖项。

sudo yum remove docker 
                docker-client 
                docker-client-latest 
                docker-common 
                docker-latest 
                docker-latest-logrotate 
                docker-logrotate 
                docker-engine

如果 yum 报告没有安装这些包,那也没关系。
/var/lib/docker/ 的内容,包括图像、容器、卷和网络,都被保留。Docker Engine 包现在被称为 docker-ce

5.2 安装方法

您可以根据需要以不同的方式安装 Docker Engine:

  • 大多数用户设置 Docker 的存储库并从中安装,以便于安装和升级任务。这是推荐的方法。
  • 一些用户下载 RPM 包并手动安装它并完全手动管理升级。这在诸如在无法访问 Internet 的气隙系统上安装 Docker 等情况下很有用。
  • 在测试和开发环境中,一些用户选择使用自动化便利脚本来安装 Docker。

5.2.1 使用存储库安装

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

1. 设置存储库

安装 yum-utils 包(提供 yum-config-manager 实用程序)并设置存储库。已经替换成阿里镜像源。

sudo yum install -y yum-utils
sudo yum-config-manager 
--add-repo 
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

image.png

2. 安装 Docker 引擎

  1. 安装最新版本的 Docker Engine、Containerd 和 Docker Compose 或进入下一步安装特定版本(安装期间需要按 y 确认):
sudo yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin 

image.png
image.png
如果提示接受 GPG 密钥,请验证指纹是否匹配 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35,如果是,则接受它。此命令会安装 Docker,但不会启动 Docker。它还会创建一个 docker 组,但是默认情况下它不会将任何用户添加到该组中。

  1. 要安装特定版本的 Docker Engine,请在repo中列出可用的版本,然后选择并安装:

a.列出并排序回购协议中可用的版本。这个例子根据版本号对结果进行排序,从最高到最低,并被截断:

yum list docker-ce --showduplicates | sort -r  
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.1.ce-3.el7                    docker-ce-stable 
docker-ce.x86_64  18.06.0.ce-3.el7                    docker-ce-stable 

返回的列表取决于启用了哪些存储库,并且特定于您的 CentOS 版本(.el7在本例中由后缀表示)。
image.png

b.通过它的完全限定包名安装一个特定的版本,这是包名(docker-ce)加上版本字符串(第二列),从第一个冒号(:)开始,直到第一个连字符,由连字符(-)分隔。例如,docker-ce-18.09.1。

sudo yum install docker-ce-18.09.1 docker-ce-cli-18.09.1 containerd.io docker-compose-plugin

此命令会安装 Docker,但不会启动 Docker。它还会创建一个 docker 组,但是默认情况下它不会将任何用户添加到该组中。

  1. 检查是否安装成功
docker -v

image.png

  1. 启动 Docker。
sudo systemctl start docker 

image.png

  1. 通过运行 hello-world 镜像来验证 Docker 引擎是否已正确安装。
sudo docker run hello-world 

此命令下载测试映像并在容器中运行它。当容器运行时,它会打印一条消息并退出。
这将安装并运行 Docker 引擎。用于 sudo 运行 Docker 命令。继续Linux 后安装以允许非特权用户运行 Docker 命令和其他可选配置步骤。
image.png

3. 升级 Docker 引擎

要升级 Docker Engine,请按照安装说明,选择您要安装的新版本。

5.2.2 从包安装

1. 安装步骤

如果您不能使用 Docker 的存储库来安装 Docker,您可以下载该 .rpm 版本的文件并手动安装。每次升级 Docker Engine 时都需要下载一个新文件。
(1)前往 https://download.docker.com/linux/centos/ 并选择您的 CentOS 版本。然后浏览x86_64/stable/Packages/ 并下载 .rpm 要安装的 Docker 版本的文件。
(2)安装 Docker Engine,将下面的路径更改为您下载 Docker 包的路径。

sudo yum install /path/to/package.rpm 

Docker 已安装但未启动。该docker组已创建,但没有用户添加到该组。
(3)启动 Docker。

sudo systemctl start docker 

(4)通过运行 hello-world 镜像来验证 Docker 引擎是否已正确安装。

sudo docker run hello-world 

此命令下载测试映像并在容器中运行它。当容器运行时,它会打印一条消息并退出。
这将安装并运行 Docker 引擎。用于 sudo 运行 Docker 命令。继续执行 Linux 的安装后步骤以允许非特权用户运行 Docker 命令和其他可选配置步骤。

2. 升级 Docker 引擎

要升级 Docker Engine,请下载较新的包文件并重复 安装过程,使用 yum -y upgrade 代替 yum -y install,并指向新文件。

5.2.3 使用便捷脚本安装

Docker 在 get.docker.com上提供了一个方便的脚本, 可以快速、非交互地将 Docker 安装到开发环境中。不建议将便利脚本用于生产环境,但可以用作示例来创建适合您需求的供应脚本。另请参阅 使用存储库 安装步骤以了解使用包存储库安装的安装步骤。该脚本的源代码是开源的,可以 docker-install在 GitHub 上的存储库中找到
在本地运行脚本之前,请务必检查从 Internet 下载的脚本。在安装之前,请让自己熟悉便捷脚本的潜在风险和限制:

  • 该脚本需要 rootsudo 特权才能运行。
  • 该脚本会尝试检测您的 Linux 发行版和版本并为您配置包管理系统,并且不允许您自定义大多数安装参数。
  • 该脚本会在不要求确认的情况下安装依赖项和建议。这可能会安装大量软件包,具体取决于主机的当前配置。
  • 默认情况下,该脚本安装 Docker、containerd 和 runc 的最新稳定版本。使用此脚本配置机器时,可能会导致 Docker 的主要版本升级意外。在部署到生产系统之前,始终在测试环境中测试(主要)升级。
  • 该脚本并非旨在升级现有的 Docker 安装。使用脚本更新现有安装时,可能无法将依赖项更新到预期版本,从而导致使用过时的版本。

提示:运行前预览脚本步骤
您可以使用 DRY_RUN=1 选项运行脚本以了解脚本在安装期间将执行的步骤:

curl -fsSL https://get.docker.com -o get-docker.sh 
DRY_RUN=1 sh ./get-docker.sh 

此示例从 get.docker.com 下载脚本 并运行它以在 Linux 上安装最新的稳定版本的 Docker:

curl -fsSL https://get.docker.com -o get-docker.sh 
sudo sh get-docker.sh Executing docker install script, commit: 7cae5f8b0decc17d6571f9f52eb840fbc13b2737 <...> 

安装了 Docker。该 docker 服务在基于 Debian 的发行版上自动启动。在 RPM 基于发行版(例如 CentOS、Fedora、RHEL 或 SLES)上,您需要使用适当的 systemctlorservice 命令手动启动它。如消息所示,默认情况下,非 root 用户无法运行 Docker 命令。
以非特权用户身份使用 Docker,还是以无根模式安装?
安装脚本需要 root 或 sudo 具有安装和使用 Docker 的权限。如果要授予非 root 用户对 Docker 的访问权限,请参阅 Linux 的安装后步骤。Docker 也可以在没有root权限的情况下安装,或者配置为以无根模式运行。有关在无根模式下运行 Docker 的说明,请参阅以 非 root 用户身份运行 Docker 守护程序(无根模式)

1. 安装预发行版

Docker 还在 test.docker.com 上提供了一个方便的脚本,用于在 Linux 上安装 Docker 的预发行版。此脚本等同于 中的脚本 get.docker.com,但将您的包管理器配置为启用来自我们的包存储库的“测试”通道,其中包括 Docker 的稳定版和预发布版(测试版、发布候选版)。使用此脚本可以提前访问新版本,并在发布稳定之前在测试环境中对其进行评估。
要从“测试”频道在 Linux 上安装最新版本的 Docker,请运行:

curl -fsSL https://test.docker.com -o test-docker.sh $ sudo sh test-docker.sh <...> 

2. 使用便利脚本后升级 Docker

如果您使用便捷脚本安装 Docker,则应直接使用包管理器升级 Docker。重新运行便利脚本没有任何好处,如果它尝试重新添加已经添加到主机的存储库,可能会导致问题。

6 卸载 Docker 引擎

  1. 卸载 Docker Engine、CLI、Containerd 和 Docker Compose 软件包:
sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin 
  1. 主机上的映像、容器、卷或自定义配置文件不会自动删除。要删除所有映像、容器和卷:
sudo rm -rf /var/lib/docker $ sudo rm -rf /var/lib/containerd 

您必须手动删除任何已编辑的配置文件。

7 Docker 镜像加速

国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:

  • 科大镜像:https://docker.mirrors.ustc.edu.cn/
  • 网易:https://hub-mirror.c.163.com/
  • 阿里云:https://<你的ID>.mirror.aliyuncs.com
  • 七牛云加速器:https://reg-mirror.qiniu.com

当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。

7.1 安装/升级 Docker 客户端

推荐安装 1.10.0 以上版本的 Docker 客户端,参考文档 docker-ce

7.2 配置镜像加速器

来到阿里云控制台,选择镜像加速器,这里选择 CentOS
image.png
针对 Docker 客户端版本大于 1.10.0 的用户
您可以通过修改 daemon 配置文件 /etc/docker/daemon.json 来使用加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
	"registry-mirrors": ["https://4ko04ci6.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

image.png

7.3 检查加速器是否生效

docker info

image.png
看到底部 Registry Mirrors 为自己阿里云的加速器地址即配置成功。
image.png

8 基础操作命令

值得注意的是,在使用 docker 命令的时候会提示权限不足,必须要用 root 才行。
原因是:Docker 守护进程启动的时候,会默认赋予名字为 docker 的用户组读写 Unix socket 的权限,因此只要创建 docker 用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问 Unix socket 了,进而也就可以执行 Docker 相关命令。

'Got permission denied while trying to connect to the Docker daemon socket a

依次执行如下命令,即可解决

sudo groupadd docker     #添加docker用户组
sudo gpasswd -a $USER docker     #将登陆用户加入到docker用户组中
newgrp docker     #更新用户组
docker ps    #测试docker命令是否可以使用sudo正常使用

image.png
启动 Docker

systemctl start docker

停止Docker

systemctl stop docker

重启 Docker

systemctl restart docker

查看 Docker 状态

systemctl status docker

开机启动

systemctl enable docker

查看 Docker 客户端的所有命令选项

docker

查看 Docker 概要信息

docker info

查看 Docker 总体帮助文档

docker --help

查看 Docker 命令帮助文档

docker 具体命令 --help

查看镜像/容器/数据卷所占空间

docker system df

image.png

9 镜像的使用

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

9.1 列出镜像列表

我们可以使用 **docker images** 来列出本地主机上的镜像。
image.png
各个选项说明:

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

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
所以,我们如果要使用版本为 15.10 的 ubuntu 系统镜像来运行容器时,命令如下:

docker run -t -i ubuntu:15.10 /bin/bash 

9.2 获取新的镜像

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

docker pull ubuntu:15.0.1

9.3 查找镜像

我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 **docker search** 命令搜索 httpd 来寻找适合我们的镜像。

docker search httpd

image.png
**NAME:**镜像仓库源的名称
**DESCRIPTION:**镜像的描述
**OFFICIAL:**是否 docker 官方发布
**STARS:**类似 Github 里面的 star,表示点赞、喜欢的意思。
**AUTOMATED:**自动构建。

9.4 删除镜像

镜像删除使用 **docker rmi** 命令,比如我们删除 hello-world 镜像,注意由镜像产生的容器要先删除,才能删除镜像:

docker images
docker rmi 1c100148faab
docker images

image.png

9.5 创建镜像

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

  1. 从已经创建的容器中更新镜像,并且提交这个镜像
  2. 使用 Dockerfile 指令来创建一个新的镜像

9.5.1 更新镜像

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

docker run -itd ubuntu /bin/bash

image.png
在运行的容器内使用 **apt-get update** 命令进行更新。
此时 ID 为 a531997c8283 的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。

docker commit -m="has update" -a="hayden" a531997c8283 hayden/ubuntu:v2
docker images

各个参数说明:

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

image.png
使用我们的新镜像 **hayden/ubuntu** 来启动一个容器

docker run -itd hayden/ubuntu:v2 /bin/bash
docker ps

image.png

9.5.2 构建镜像

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

vim Dockerfile 

FROM    centos:7.9
MAINTAINER      Fisher "fisher@sudops.com"

RUN     /bin/echo 'admin:admin' |chpasswd
RUN     useradd admin
RUN     /bin/echo 'admin:admin' |chpasswd
RUN     /bin/echo -e "LANG="en_US.UTF-8"" >/etc/default/local
EXPOSE  22
EXPOSE  80
CMD     /usr/sbin/sshd -D

image.png
image.png
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的
第一条 FROM,指定使用哪个镜像源
RUN 指令告诉 docker 在镜像内执行命令,安装了什么
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像

docker build -t hayden/centos:7 ./

参数说明:

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

9.5.3 设置镜像标签

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

docker images
docker tag 8c11a2e777fe hayden/ubuntu:dev
docker images

image.png

其中, 表示该镜像为虚悬镜像(dangling image),即仓库名和标签为 的镜像,一般是构建或删除操作错误产生的。
可以使用如下命令查看 docker 下所有虚悬镜像:
docker images ls -f dangling=true
因为虚悬镜像是一种错误镜像,已经失去其价值,且占用磁盘容量,所以可以使用如下命令将其删除:
docker image prune # 删除所有虚悬镜像

10 容器的使用

10.1 获取镜像

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

docker pull ubuntu

10.2 启动容器

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

docker run -it ubuntu /bin/bash

10.2.1 普通运行

使用 **docker run** 命令来在容器内运行一个应用程序

docker images
docker ps
docker run ubuntu /bin/echo "hello docker"

image.png
各个参数解析:

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

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

  • -a

all显示所有容器(默认显示正在运行)

  • -f

filter filter根据提供的条件过滤输出
使用Go模板打印精美的容器

  • -n

last int显示n个最近创建的容器(包括所有状态)(默认为-1)

  • -l

latest显示最新创建的容器(包括所有状态)
no-trunc不截断输出

  • -q

quiet只显示容器id

  • -s

size显示文件总大小

10.2.2 交互式运行

我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现**“对话”**的能力:
以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式,shell 为 bash,进入该容器:

docker run -i -t ubuntu /bin/bash

image.png
各个参数解析:

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

注意第二行 root@4b68b729ac81:/#,此时我们已进入一个 ubuntu 系统的容器
我们尝试在容器中运行命令** **cat /proc/version** **ls** **分别查看当前系统的版本信息和当前目录下的文件列表
image.png
我们可以通过运行 exit 命令或者使用 CTRL+D 来退出容器。
image.png

10.2.3 后台运行

使用 -d 参数命令创建一个以进程方式运行的容器

docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

image.png
在输出中,我们没有看到期望的 “hello world”,而是一串长字符
c218b38786adf84f09e238bb17e807c8fdc4ef24fa0d7daa78f7b7d4d0c9423b
这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。
首先,我们需要确认容器有在运行,可以通过 **docker ps** 来查看:
image.png
输出详情介绍:
**CONTAINER ID:**容器 ID。
**IMAGE:**使用的镜像。
**COMMAND:**启动容器时运行的命令。
**CREATED:**容器的创建时间。
**STATUS:**容器状态。
状态有7种:

  • created(已创建)
  • restarting(重启中)
  • running 或 Up(运行中)
  • removing(迁移中)
  • paused(暂停)
  • exited(停止)
  • dead(死亡)

**PORTS:**容器的端口信息和使用的连接类型(tcpudp)。
**NAMES:**自动分配的容器名称。
在宿主主机内使用 **docker logs <CONTAINER ID>** 命令,查看容器内的标准输出:
image.png

10.2.4 启动已停止运行的容器

使用 docker ps -a 查看所有的容器命令如下:

docker ps -a

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

docker start 4b68b729ac81

image.png

10.3 停止容器

我们使用 **docker stop <CONTAINER ID>** 命令来停止容器,通过 **docker ps** 查看,容器已经停止工作:

docker ps
docker stop 4b68b729ac81
docker ps

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

10.4 进入容器

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

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

10.4.1. attach

下面演示了使用 docker attach 命令。如果从这个容器退出,会导致容器的停止

docker ps
docker attach 6df5e70d71f2
docker ps

image.png

10.4.2. exec

下面演示了使用 docker exec 命令。 如果从这个容器退出,容器不会停止

docker ps
docker exec -it 070b481c7588 /bin/bash

image.png

10.5 退出容器

10.5.1 exit

使用 docker run it 进入容器后,使用 exit 退出容器,容器即停止。

10.5.2 Ctrl + P + Q

使用 docker run it 进入容器后,使用组合键 Ctrl + P + Q 退出容器,容器不停止。

10.6 导出和导入容器

10.6.1. 导出容器

如果要导出本地某个容器,可以使用 **docker export**命令。这样将导出容器快照到当前目录下。

docker ps -a
docker export 070b481c7588 > ubuntu.tar
ls

image.png

10.6.2. 导入容器快照

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

cat ./ubuntu.tar | docker import - test/ubuntu:v1
docker images

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

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

10.7 删除容器

删除容器使用 **docker rm** 命令:
image.png
下面的命令可以清理掉所有处于终止状态的容器:

docker container prune

批量删除停止的容器,中间用空格隔开:

docker ps -a
docker rm ad9e18cb3ad4 a531997c8283 a10b4e789568
docker ps -a

image.png
或者通过将上一步操作的内容作为参数,批量删除:

docker rm -f $(docker ps -aq)

11 使用 Web 应用

11.1 运行 web 应用

我们将在 docker 容器中运行一个 Python Flask 应用来运行一个 web 应用。

docker pull training/webapp  # 载入镜像
docker run -d -P training/webapp python app.py
docker ps

image.png
参数说明:

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

11.2 查看 Web 应用容器

使用 docker ps 来查看我们正在运行的容器:
image.png
这里多了端口信息。

PORTS 0.0.0.0:49153->5000/tcp

Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 49153 上。
这时我们可以通过浏览器访问 WEB 应用
image.png
我们也可以通过 -p 参数来设置不一样的端口:

docker run -d -p 5000:5000 training/webapp python app.py #容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
docker ps

image.png

11.3 网络端口的快捷方式

通过 **docker ps** 命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 **docker port**,使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
上面我们创建的 web 应用容器 ID 为 **a7ffb0fd3cc7** 名字为 **unruffled_torvalds**
我可以使用 **docker por**t a7ffb0fd3cc7**docker port unruffled_torvalds** 来查看容器端口的映射情况。

docker port a7ffb0fd3cc7
docker port unruffled_torvalds

image.png

11.4 查看 Web 应用程序日志

docker logs <CONTAINER ID / NAMES> 可以查看容器内部的标准输出。

docker ps
docker logs -f a7ffb0fd3cc7

image.png
**-f:**docker logs 像使用 tail -f 一样来输出容器内部的标准输出。
从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。

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

我们还可以使用 **docker top < CONTAINER ID / NAMES>** 来查看容器内部运行的进程

docker ps
docker top a7ffb0fd3cc7

image.png

11.6 检查 Web 应用程序

使用 **docker inspect** 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

docker ps
docker inspect 

image.png

11.7 停止 Web 应用容器

docker ps
docker stop 
docker ps

image.png

11.8 重启 Web 应用容器

已经停止的容器,我们可以使用命令 **docker start** 来启动。
正在运行的容器,我们可以使用 **docker restart** 命令来重启。

docker ps -a
docker start fe49799fdc01
docker ps

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

docker ps -l

image.png

11.9 移除WEB应用容器

我们可以使用 **docker rm** 命令来删除不需要的容器

docker ps
docker rm a7ffb0fd3cc7

需要注意,删除容器时,容器必须是停止状态,否则会报如下错误
image.png

docker ps
docker stop a7ffb0fd3cc7
docker rm a7ffb0fd3cc7
docker ps
docker ps -a

image.png
image.png

12 容器的连接

12.1 网络端口映射

我们创建了一个 python 应用的容器。

docker run -d -P training/webapp python app.py

image.png
我们也可以使用 **-p** 标识来指定容器端口绑定到主机端口。
两种方式的区别是:

  • -P :是容器内部端口随机映射到主机的端口。
  • -p :是容器内部端口绑定到指定的主机端口。
docker run -d -p 5000:5000 training/webapp python app.py

image.png
另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。这样我们就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。

docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py

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

docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

image.png
**docker port** 命令可以让我们快捷地查看端口的绑定情况。

docker port 1d7a0ab74419

image.png

12.2 容器互联

端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。

12.2.1 容器命名

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

docker run -d -P --name hayden training/webapp python app.py
docker ps

image.png

12.2.2 新建网络

下面先创建一个新的 Docker 网络。

docker network create -d bridge test-net
docker netwoek ls

image.png
参数说明:
-d:参数指定 Docker 网络类型,有 bridge、overlay。
其中 overlay 网络类型用于 Swarm mode,在本小节中你可以忽略它。

12.2.3 连接容器

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

docker run -itd --name test1 --network test-net ubuntu /bin/bash
docker ps

image.png
再运行一个容器并加入到 test-net 网络:

docker run -itd --name test2 --network test-net ubuntu /bin/bash
docker ps

image.png
下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。
image.png
如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping(即学即用:可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)。

apt-get update
apt install -y iputils-ping

image.png
image.png
同理,text2 容器里也需要装上 ping 命令,接着就可以继续 ping 操作了。如图可以证明 test1 容器和 test2 容器建立了互联关系。

docker exec -it test1 /bin/bash
ping test2

docker exec -it test2 /bin/bash
ping test1

image.png
image.png

12.3 配置 DNS

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

sudo vim /etc/docker/daemon.json

{
  "dns" : [
    "114.114.114.114",
    "8.8.8.8"
  ]
}

sudo systemctl restart docker

设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。
配置完,需要重启 docker 才能生效。
image.png
image.png
查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:

docker run -it --rm  ubuntu  cat etc/resolv.conf

image.png
手动指定容器的配置
如果只想在指定的容器设置 DNS,则可以使用以下命令,如果在容器启动时没有指定 –dns–dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS。:

docker run -it --rm -h host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu
cat /etc/hostname
cat /etc/hosts
cat /etc/resolv.conf

image.png

参数说明:
–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。

13 管理仓库(Docker Hub)

仓库(Repository)是集中存放镜像的地方。以下介绍一下 Docker Hub。当然不止 Docker Hub,只是远程的服务商不一样,操作都是一样的。
目前 Docker 官方维护了一个公共仓库 Docker Hub
大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。

13.1 注册

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

13.2 登录

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

docker login

image.png

13.3 退出

docker logout

image.png

13.4 拉取镜像

你可以通过 **docker search** 命令来查找官方仓库中的镜像,并利用 **docker pull** 命令来将它下载到本地。
以 ubuntu 为关键词进行搜索:

docker search ubuntu

image.png

docker pull ubuntu

image.png

13.5 推送镜像

用户登录后,可以通过 **docker push** 命令将自己的镜像推送到 Docker Hub。
以下命令中的 **<username>** 请替换为你的 Docker 账号用户名。

docker tag ubuntu <username>/ubuntu:test-pull
docker image
docker push <username>/ubuntu:test-pull
docker search <username>/ubuntu

image.png

14 容器数据卷

14.1 容器数据卷概念

Docker 容器数据卷(Docker Volume)是指在 Docker 容器中使用的持久化卷。它是一个独立的卷,其中包含了容器所需的数据和配置信息。数据卷可以帮助容器在重启后恢复到之前的状态,或者在容器之间共享数据。
Docker 容器数据卷可以通过多种方式创建,包括:

  1. 使用 Dockerfile 自定义构建镜像时指定数据卷

在 Dockerfile 中,可以使用 COPY 命令将本地文件或目录挂载到容器中,创建一个本地文件系统或者目录作为容器数据卷。例如:

Copy code
FROM ubuntu:latest
COPY /path/to/local/data/mydata /var/lib/data

这样就可以在容器中创建一个名为 /var/lib/data 的数据卷,并将本地的 mydata 文件夹挂载到容器中。 2. 使用 Docker 自带的数据卷功能
Docker 自带了一个名为 local 的数据卷功能,它可以挂载本地文件系统或者目录到容器中。在 Dockerfile 中,可以使用 COPY 命令或者 local 命令来创建本地文件系统或者目录作为容器数据卷。例如:

Copy code
FROM ubuntu:latest
COPY /path/to/local/mydata /var/lib/data

或者

Copy code
RUN mkdir -p /var/lib/data
COPY /path/to/local/mydata /var/lib/data
  1. 使用 Docker 网络功能创建共享卷

除了使用 Dockerfile 和 local 命令创建本地文件系统或者目录作为容器数据卷之外,还可以使用 Docker 网络功能来创建共享卷。在 Docker 网络中,容器可以直接共享卷,而无需将其挂载到宿主机上。 例如,可以使用 Docker Compose 或者 Docker 网络命令 docker network create 来创建一个名为 my-data 的共享卷,并将本地文件系统或者目录挂载到容器中。例如:

Copy code
docker-compose up --build
docker network create my-data
docker-compose up --build --network my-data

这样就可以在容器中创建一个名为 my-data 的共享卷,并将本地的 mydata 文件夹挂载到容器中。

  1. 使用命令创建关联卷
docker run -it --privileged=true -v <宿主机绝对路径>:<容器内目录> 镜像名

总的来说,Docker 容器数据卷是一种可以在容器中持久化数据和配置信息的方式,可以帮助容器在重启后恢复到之前的状态,或者在容器之间共享数据。

14.2 容器数据卷的作用

Docker 容器数据卷(Docker Volume)是指在 Docker 容器中使用的持久化卷。它是一个独立的卷,其中包含了容器所需的数据和配置信息。数据卷可以帮助容器在重启后恢复到之前的状态,或者在容器之间共享数据。 数据卷可以被用来存储应用程序的配置信息、日志文件、数据库数据等。例如,一个数据卷可以被用来保存一个公司内部应用程序的配置信息,并且在多个容器之间共享这些配置信息。在另一个容器中,可以使用相同的配置信息来启动和运行该应用程序。 此外,数据卷还可以被用来在容器之间共享数据。例如,一个容器可以向其他容器共享它的文件系统或者目录,而其他容器可以通过挂载该卷来访问这些文件。这可以使多个容器之间的数据共享更加简单和方便。 总的来说,Docker 容器数据卷是一种非常有用的功能,它可以帮助开发人员和运维人员更好地管理和共享容器中的数据和配置信息。

14.3 数据卷的读写权限

在 Docker 容器中,数据卷的读写权限可以通过以下规则进行控制:

  1. RO 规则:RO 规则表示容器只能够读取其他容器或者主机中的数据卷。具体来说,如果一个容器设置了 RO 规则,那么其他容器或者主机中的数据卷将无法被访问。
  2. RW 规则:RW 规则表示容器可以读取和写入其他容器或者主机中的数据卷。具体来说,如果一个容器设置了 RW 规则,那么其他容器或者主机中的数据卷可以被该容器读取和写入。
  3. Mapping规则:Mapping 规则可以让容器将其他容器或者主机中的卷挂载到本地的卷。具体来说,如果一个容器设置了 Mapping 规则,那么它可以将其他容器或者主机中的卷挂载到本地的卷中,以便在容器中使用这些卷中的数据。

总的来说,Docker 容器中的数据卷可以通过设置读写权限来控制它们的访问范围。RO 规则可以防止容器访问其他容器或者主机中的数据卷,从而保护数据的安全性。RW 规则可以方便地在容器之间共享数据卷中的数据,从而提高数据共享的效率。Mapping 规则可以让容器在本地创建一个与其他容器或者主机中的卷相对应的卷,以便在容器中使用这些卷中的数据。

15 Dockerfile

15.1 Dockerfile 简介

Dockerfile 是一种用于构建 Docker 镜像的文本格式文件。它是 Docker 的核心文件之一,可以指导 Docker 容器的构建和运行。 Dockerfile 包含了一系列指令,这些指令可以让用户定义容器的基本信息、安装软件包、配置环境变量等。例如,Dockerfile 可以用来安装软件包、配置网络连接、挂载文件系统等。 使用 Dockerfile,用户可以轻松地创建和管理 Docker 镜像。当构建 Docker 镜像时,Dockerfile 会自动执行一系列命令,并生成一个可执行的 Docker 镜像。这样,用户就可以在 Docker 容器中使用这个 Docker 镜像。 Dockerfile 是一种非常灵活的文本格式文件,用户可以根据需要自定义 Dockerfile 的内容和规则。同时,Dockerfile 也提供了一些预定义的 Dockerfile 模板,这些模板可以帮助用户快速创建 Docker 镜像。 总的来说,Dockerfile 是一种非常重要的文本格式文件,它可以帮助用户方便地创建和管理 Docker 镜像。通过使用 Dockerfile,用户可以轻松地定义容器的基本信息、安装软件包、配置环境变量等,从而实现 Docker 容器的快速构建和运行。

15.2 Dockerfile 保留字

在 Dockerfile 中,有一些保留字用于指定不同的指令和操作。以下是一些常见的 Dockerfile 保留字的介绍:

  1. FROM:指定基础镜像,即用作新镜像基础的已有镜像。
  2. MAINTAINER(已废弃)/LABEL:指定镜像的作者信息或添加自定义元数据标签。
  3. RUN:在镜像内部执行命令,用于安装软件包、运行脚本等操作。
  4. CMD:设置容器启动时默认执行的命令,可以被 docker run 命令的参数覆盖。
  5. ENTRYPOINT:配置容器启动时要执行的命令,与 CMD 类似,但不会被 docker run 命令的参数覆盖。
  6. COPY/ADD:将本地文件或目录复制到镜像中指定的路径。
  7. ENV:设置环境变量,可以在容器内部使用。
  8. ARG:定义构建时的变量,可通过 --build-arg 选项传递给 docker build 命令。
  9. VOLUME:在容器中创建挂载点,用于持久化存储或与其他容器共享数据。
  10. EXPOSE:声明容器运行时监听的端口。
  11. WORKDIR:设置容器内部的工作目录。
  12. USER:指定容器运行时的用户名或 UID。
  13. HEALTHCHECK:定义容器健康检查的命令。
  14. ONBUILD:指定一个触发器命令,在当前镜像作为基础镜像时执行。
  15. STOPSIGNAL:设置停止容器时发送的信号。

这些保留字在 Dockerfile 中用于组织和描述镜像的构建步骤和运行配置。通过合理使用这些指令,可以创建出满足特定需求的 Docker 镜像。

15.2.1 COPY

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

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

[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

COPY hom* /mydir/
COPY hom?.txt /mydir/

15.2.2 ADD

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

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

15.2.3 CMD

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

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

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:

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

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

15.2.4 ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:

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

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。
示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 

1. 不传参运行

docker run  nginx:test

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

nginx -c /etc/nginx/nginx.conf

2. 传参运行

docker run  nginx:test -c /etc/nginx/new.conf

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

nginx -c /etc/nginx/new.conf

15.2.5 ENV

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

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

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

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"

15.2.6 ARG

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
格式:

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

15.2.7 VOLUME

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

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

格式:

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

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

15.2.8 EXPOSE

仅仅只是声明端口。
作用:

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

格式:

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

15.2.9 WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:

WORKDIR <工作目录路径>

15.2.10 USER

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

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

15.2.11 HEALTHCHECK

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

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

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

15.2.12 ONBUILD

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

ONBUILD <其它指令>

15.2.13 LABEL

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

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

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

LABEL org.opencontainers.image.authors="runoob"

15.3 使用 Dockerfile 定制镜像

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

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

FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html

image.png
image.png

  1. FROM 和 RUN 指令的作用

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
shell 格式:

RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。

exec 格式:

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

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

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 层镜像。可简化为以下格式:

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

15.4 开始构建镜像

在 Dockerfile 文件的存放目录下,执行构建动作。
以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
:最后的 **.** 代表本次执行的上下文路径,即当前目录下。

docker build -t nginx:v3 .

上下文路径
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。

image.png

16 Docker 网络

16.1 Docker 网络概念

Docker 网络是用于在 Docker 容器之间进行通信和连接的一种机制。它提供了一种有效的方式来创建、管理和隔离容器之间的网络环境。
在 Docker 中,可以创建自定义的网络,使得容器可以相互通信,而不依赖于主机网络。这些网络可以是桥接网络、覆盖网络或者其他类型的网络。每个 Docker 容器可以连接到一个或多个网络,这取决于应用程序的需求。
Docker 网络允许容器之间通过使用容器名称或 IP 地址进行通信。可以使用 DNS 来解析容器名称,使得容器可以通过名称进行相互访问。
Docker 网络还提供了一些高级功能,例如在网络层级上实现负载均衡和服务发现。这些功能使得容器的扩展和管理更加方便和灵活。
总结来说,Docker 网络提供了一种简单而强大的方法来创建和管理容器之间的网络连接,从而实现容器化应用程序的部署和通信。
image.png

16.2 Docker 网络常用命令

docker network COMMAND
Commands:
connect 将容器连接到网络
create 创建网络
disconnect 断开容器与网络的连接
inspect 显示一个或多个网络的详细信息
ls 网络列表
prune 删除所有未使用的网络
rm 删除一个或多个网络

以下是 Docker 网络的一些常用基本命令:

  1. 创建网络:
docker network create <network_name>
  1. 查看网络列表:
docker network ls
  1. 查看网络详细信息:
docker network inspect <network_name>
  1. 连接容器到网络:
docker network connect <network_name> <container_name>
  1. 断开容器与网络的连接:
docker network disconnect <network_name> <container_name>
  1. 删除网络:
docker network rm <network_name>

17 Docker Compose

17.1 Docker Compose 概念

Docker Compose 是一种容器化应用程序构建工具。它可以帮助用户在多个容器之间共享文件,并实现容器之间的通信。 Docker Compose 使用 YAML 文件来描述容器之间的依赖关系和配置。它可以让多个容器在相同的文件系统下运行,避免了容器之间的额外网络流量和配置。 使用 Docker Compose,用户可以轻松地创建和管理多个容器之间的依赖关系。在 Compose 文件中,用户可以定义不同容器之间的依赖关系,并为容器定义环境变量和命令。然后,用户可以使用 Docker Compose 命令来启动多个容器,并将它们连接在一起,实现应用程序的构建和部署。 Docker Compose 的使用非常灵活,用户可以使用不同的 Docker 镜像作为基础镜像,也可以使用自定义的容器定义文件。此外,Docker Compose 还提供了许多高级特性,例如容器间的通信、自动化容器配置等。因此,Docker Compose 已成为容器化应用程序构建的一种非常流行的工具。

Docker Compose 使用的三个步骤:

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

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

# yaml 配置实例
version: '3'
services:
  web:
    build: .
    ports:
   - "5000:5000"
    volumes:
   - .:/code
    - logvolume01:/var/log
    links:
   - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

17.2 Compose 的安装

Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases
运行以下命令以下载 Docker Compose 的当前稳定版本:

sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

要安装其他版本的 Compose,请替换 v2.2.2。
Docker Compose 存放在 GitHub,不太稳定。
你可以也通过执行下面的命令,高速安装 Docker Compose。

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

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

sudo chmod +x /usr/local/bin/docker-compose

创建软链:

sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

测试是否安装成功:

docker-compose --version

注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。
macOS
Mac 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Mac 用户不需要单独安装 Compose。Docker 安装说明可以参阅 MacOS Docker 安装
windows PC
Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Windows 用户不需要单独安装 Compose。Docker 安装说明可以参阅Windows Docker 安装

17.3 Compose 的使用

17.3.1 准备

创建一个测试目录:

mkdir composetest
cd composetest

在测试目录中创建一个名为 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.
'.format(count)

在此示例中,redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379。
在 composetest 目录中创建另一个名为 **requirements.txt** 的文件,内容如下:

flask
redis

17.3.2 创建 Dockerfile 文件

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

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]

Dockerfile 内容解释:

  • FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。
  • WORKDIR /code: 将工作目录设置为 /code。
  • 设置 flask 命令使用的环境变量。
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
  • RUN apk add --no-cache gcc musl-dev linux-headers:安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
  • 复制 requirements.txt 并安装 Python 依赖项。
COPY requirements.txt requirements.txt 
RUN pip install -r requirements.txt
  • COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
  • CMD [“flask”, “run”]: 容器提供默认的执行命令为:flask run。

17.3.3 创建 docker-compose.yml

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

# yaml 配置
version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

该 Compose 文件定义了两个服务:web 和 redis。

  • web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
  • redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。

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

在测试目录中,执行以下命令来启动应用程序:

docker-compose up

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

docker-compose up -d

17.4 yml 配置指令参考

17.4.1 version

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

17.4.2 build

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

version: "3.7"
services:
  webapp:
    build: ./dir

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

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:多层构建,可以指定构建哪一层。

17.4.3 cap_add,cap_drop

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

cap_add:
  - ALL # 开启全部权限

cap_drop:
  - SYS_PTRACE # 关闭 ptrace权限

17.4.4 cgroup_parent

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

cgroup_parent: m-executor-abcd

17.4.5 command

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

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

17.4.6 container_name

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

container_name: my-web-container

17.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 之前停止。
version: "3.7"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

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

17.4.8 deploy

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

version: "3.7"
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:访问集群服务的方式。

endpoint_mode: vip 
# Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
endpoint_mode: dnsrr
# DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。

labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。
mode:指定服务提供的模式。

  • replicated:复制服务,复制指定服务到集群的机器上。
  • global:全局服务,服务将部署至集群的每个节点。
  • 图解:下图中黄色的方块是 replicated 模式的运行情况,灰色方块是 global 模式的运行情况。2022-09-11-01.png

replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
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 及更高版本。

17.4.9 devices

指定设备映射列表。

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

17.4.10 dns

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

dns: 8.8.8.8

dns:
  - 8.8.8.8
  - 9.9.9.9

17.4.11 dns_search

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

dns_search: example.com

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

17.4.12 entrypoint

覆盖容器默认的 entrypoint。

entrypoint: /code/entrypoint.sh

也可以是以下格式:

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

17.4.13 env_file

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

env_file: .env

也可以是列表格式:

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

17.4.14 environment

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

environment:
  RACK_ENV: development
  SHOW: 'true'

17.4.15 expose

暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:

expose:
 - "3000"
 - "8000"

17.4.16 extra_hosts

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

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

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

162.242.195.82  somehost
50.31.209.229   otherhost

17.4.17 healthcheck

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

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

17.4.18 image

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

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 镜像id

17.4.19 logging

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

driver: "json-file"
driver: "syslog"
driver: "none"

仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。

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

当达到文件限制上限,会自动删除旧得文件。
syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。

logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

17.4.20 network_mode

设置网络模式。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

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

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
      other-network:
        aliases:
         - alias2
networks:
  some-network:
    # Use a custom driver
    driver: custom-driver-1
  other-network:
    # Use a custom driver which takes special options
    driver: custom-driver-2

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

17.4.21 restart

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

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

17.4.22 secrets

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

version: "3.1"
services:

mysql:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
  secrets:
    - my_secret

secrets:
  my_secret:
    file: ./my_secret.txt

17.4.23 security_opt

修改容器默认的 schema 标签。

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

17.4.24 stop_grace_period

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

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

默认的等待时间是 10 秒。

17.4.25 stop_signal

设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。

stop_signal: SIGUSR1

17.4.26 sysctls

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

sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0

17.4.27 tmpfs

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

tmpfs: /run

tmpfs:
  - /run
  - /tmp

17.4.28 ulimits

覆盖容器默认的 ulimit。

ulimits:
  nproc: 65535
  nofile:
    soft: 20000
    hard: 40000

17.4.29 volumes

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

version: "3.7"
services:
  db:
    image: postgres:latest
    volumes:
      - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
      - "/localhost/data:/var/lib/postgresql/data"
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。