编辑
2023-08-09
操作系统
0
请注意,本文编写于 435 天前,最后修改于 80 天前,其中某些信息可能已经过时。

目录

简介
目标
适用场景
VM对比
名词解释
核心组件
引擎
镜像
容器
仓库
网络
底层技术
Namespace(命名空间)
Cgroups(控制组)
联合文件系统
常见命令
实战流程
编写Dockerfile文件
构建镜像
推送镜像
Docker Compose

简介

Docker 是一个开源的应用容器引擎,使用go语言实现,它诞生于2013年,最早是dotCloud公司内部的一个项目,后来加入了Linux基金会,并采用Apache 2.0协议进行管理,代码托管在GitHub上。 Docker提供了一种轻量级操作系统虚拟化解决方案。它基于Linux容器(LXC)技术,在LXC之上,Docker进行了进一步的封装,让用户无需处理容器管理,使得操作变得更加简单。 它允许开发者将他们的应用程序和依赖包打包到一个可移植的镜像中,应用程序运行在容器中,每个容器都有自己独立的沙箱环境,相互之间没有任何接口。这意味着容器之间的应用程序不会相互干扰,提供了更高的安全性和隔离性。

目标

Docker 是容器技术的一种体现,而容器技术的根本是为了抹平软件运行的环境差异。

Docker通过build命令将应用程序和其依赖构建成镜像文件,镜像是只读的,这意味着构建完成后,镜像不会再发生任何变化。如此,基于该镜像启动的容器环境必然一致。同理,跑在这个容器中的应用程序所处环境也一致。

通过这种容器化技术,开发者可以更加方便地部署和管理应用程序,提高开发效率和应用的可移植性。容器是完全使用沙箱机制,相互之间不会有任何接口。

它有几个特性

  • 容器化
  • 环境一致性
  • 快速部署和启动
  • 资源利用率和可扩展性
  • 跨平台和可移植性

适用场景

Docker 在许多场景下都能提供价值,特别是在需要快速部署、一致性环境、资源隔离和持续集成部署等方面具有明显优势。

  • 持续集成和持续部署(CI/CD):Docker 可以与持续集成/持续部署工具集成,实现自动化的构建、测试和部署流程。开发团队可以快速地交付新功能和修复bug。CI/CD pipeline 也可以利用 Docker 容器的轻量级和快速启动特性,加速构建和部署过程。
  • 微服务架构:非常适合构建和管理微服务架构中的各个微服务。每个微服务可以打包为一个独立的容器,这些容器可以独立部署和扩展,而不需要影响其他服务。通过 Docker 容器编排工具如 Kubernetes 进行管理和扩展。通过多容器运行多服务的形式对复杂项目进行拆解。
  • 应用程序部署:简化了应用程序的部署过程。传统的应用程序部署可能涉及在目标服务器上安装和配置各种依赖项,这是一个复杂且容易出错的过程。使用Docker,开发人员可以将应用程序及其所有依赖项打包到一个可移植的Docker容器中,然后将其部署到任何运行Docker的环境中。
  • 开发环境管理:开发团队可以使用 Docker 来创建一致的开发环境,避免开发者之间由于本地环境不同而导致的问题。每个开发者可以在自己的机器上运行包含应用程序、数据库、缓存等组件的 Docker 容器,保证开发环境的一致性。

VM对比

新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统,避免引导。docker是利用宿主机的操作系统,省略了这个复杂的过程,它和vm的差异主要体现在

  • VM(VMware)在宿主机器、宿主机器操作系统的基础上创建虚拟层、虚拟化的操作系统、虚拟化的仓库,然后再安装应用。
  • Container(Docker容器),在宿主机器、宿主机器操作系统上创建Docker引擎,在引擎的基础上再安装应用。

优势

  • 启动和停止速度:传统虚拟机(VM)通常需要几分钟来启动,因为它们需要引导一个完整的操作系统。而Docker容器只需启动一个包含应用和其依赖的软件环境的进程,因此启动速度可以在秒级甚至毫秒级实现。
  • 资源需求:虚拟机需要为每个实例分配一整套操作系统及其资源(如CPU、内存和存储),这导致了较高的资源消耗。而Docker容器共享主机的操作系统内核,并只包含应用程序及其依赖项,资源需求显著减少。一台主机上可以运行更多的Docker容器,而不是同等数量的虚拟机。
  • 镜像管理:Docker使用镜像来部署应用,这些镜像可以通过Docker Hub等仓库进行共享和分发。用户可以像使用Git一样拉取、推送和更新镜像,这使得应用的获取和分发变得非常方便。Dockerfile是一种用于定义镜像内容的配置文件,使得创建和维护镜像变得简单且可重复。
  • 自动化创建和部署:Dockerfile允许用户通过编写脚本来自动化地创建镜像。这不仅提高了效率,还保证了环境的一致性,因为每次构建都是基于相同的Dockerfile。此外,结合CI/CD工具链,Docker可以大幅简化持续集成和持续部署的流程。
  • 高效资源利用:由于Docker容器与宿主机共享操作系统内核,容器本身几乎不消耗额外的系统资源。这种共享机制使得容器能够高效地利用系统资源,同时确保应用性能不会受到显著影响。
  • 安全性:Docker利用Linux内核的namespaces和cgroups机制实现隔离,以确保容器之间的独立运作。

docker 属于操作系统层面的虚拟化技术。隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。容器本质是一个受限制的进程,它没办法像直接运行在主机上的进程那样获取主机上的进程、环境变量、网络等信息。 虚拟化技术指的是通过隐藏特定计算平台的实际物理特性,为用户提供抽象、统一、模拟的计算环境。这种计算环境,也被称为虚拟机**。** Docker 是对Linux容器的一种封装,具有高性能,低开销,接口简单易用等特点。真正使其超过其他同类产品,迅速占领市场,成为目前最流行的Linux容器技术解决方案的根本是Docker引入了镜像功能。 与系统级别的虚拟机不同,容器技术的虚拟其实是进程级别的。虚拟机是通过在宿主机上启动一个虚拟机监视器 HyperVisor 来管理控制虚拟机的,最经典的 HyperVisor 就是 VirtualBox。与容器相比,虚拟机包含了整个客户操作系统,这也是二者性能差异的主要成因。

名词解释

  • Dockerd:运行于服务器上的后台守护进程(daemon),负责实现容器镜像的拉取和管理以及容器创建、运行等各类操作。Dockerd 向外提供 RESTful API。
  • Containerd:另一个后台守护进程,是真正实现容器创建、运行、销毁等各类操作的组件,containerd 向外暴露 grpc 接口来提供容器操作能力。dockerd 在启动时会自动启动 containerd 作为其容器管理工具,containerd 也可以独立运行。
  • Runc:实现了容器的底层功能,例如创建、运行等。通过调用内核接口为容器创建和管理 cgroup、namespace 等功能,实现容器的核心特性。runc 内通过调用内置的 libcontainer 库功能来操作内核特性。

核心组件

Docker是一个Client-Server结构的系统,包括客户端和服务端,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问Docker守护进程。

关系图

  • Docker容器是从镜像(Image)创建而来。镜像是一个只读的模板,包含了运行应用程序所需的文件系统和运行时配置。镜像通常由 Dockerfile 定义构建而成,其中包含了应用程序的依赖和设置。
  • 当使用镜像创建容器时,Docker 在镜像的基础上创建一个可写的容器层。这个容器层包含了镜像的内容,并允许容器内的应用程序进行文件的读写操作。这种分层的结构使得容器可以轻松地与其他容器共享基础镜像,同时确保每个容器都有独立的文件系统层用于存储修改和数据。
  • 在创建容器时,Docker 会根据镜像的定义设置容器的配置参数。这些参数包括环境变量、网络设置、卷挂载等,这些配置可以通过 docker run 命令的选项进行指定或通过 Docker Compose 文件进行管理。
  • 容器创建完成,Docker 会在容器内部启动应用程序。在启动过程中,Docker 会根据容器的配置为应用程序分配资源,例如 CPU、内存等。应用程序开始运行后,它可以访问容器的文件系统和配置的资源,从而执行其指定的功能或服务。

引擎

Docker的核心组件,负责整个容器化流程的管理和执行。它包括三个主要部分:Docker守护进程(Docker Daemon)、Docker客户端(Docker Client)和 Docker API。

  • Docker守护进程(Docker Daemon):Docker守护进程是Docker Engine的后台服务,运行在主机上。它负责监听客户端的请求,管理容器的创建、启动、停止和删除等操作。守护进程还负责与容器运行时进行交互,监控容器的状态,处理容器的文件系统、网络和资源管理等任务。
  • Docker客户端(Docker Client):Docker客户端是与Docker守护进程进行交互的命令行工具或API。客户端可以通过命令行界面(CLI)或使用Docker提供的API发送请求给Docker守护进程,从而管理和操作Docker容器。客户端可以运行在与守护进程相同的主机上,也可以远程连接到远程守护进程。
  • Docker API:Docker守护进程提供了一组RESTful API,允许外部应用程序通过HTTP/HTTPS与守护进程进行通信。通过API,应用程序可以管理容器、镜像和其他Docker相关资源,实现与Docker的集成和自动化操作。

镜像

镜像是一个完整的文件系统,它包含了容器运行时所需要的所有依赖项:代码、运行时、库、环境变量和配置文件等。镜像是容器的基础,每个容器启动时都会基于一个镜像来创建。镜像可以基于另一个镜像构建,这种镜像的继承和定制过程称为镜像的层叠和分层构建。 Docker 镜像包含以下几个重要组成部分:

  • 基础文件系统:镜像中包含一个或多个文件系统层,这些层构成了容器的根文件系统。这些层可以是基于其他镜像的增量变化,这种机制被称为联合文件系统(UnionFS)。
  • 运行时配置:镜像中还包含了容器运行时需要的配置信息,例如环境变量、启动命令等。
  • 元数据:镜像也包含一些描述和配置镜像本身的元数据,比如作者信息、创建时间、依赖关系等。

镜像定义:可以通过Dockerfile定义,其中包含了构建镜像所需的指令和配置信息。 获取方式:可以从Docker Hub等镜像仓库获取,也可以通过本地构建。

容器

镜像和容器的关系就好像类和实例的关系。容器是镜像的一个运行时实例。每个容器都基于一个镜像创建,类似于类的实例化过程。容器可以独立运行,并且可以根据需要启动、停止或删除。可以理解为容器 = 容器层(可写)+ 镜像(只读)。 容器是在隔离的环境中运行的进程,具有自己的文件系统、网络空间和进程空间。

写时复制 写时复制(Copy-on-Write,CoW)技术在容器化技术中起到了关键作用,特别是在提高磁盘利用率和确保容器间隔离性方面有显著的优势。 原理:当容器启动时,Docker 使用写时复制机制。如果容器需要修改镜像中的文件,Docker 并不会直接修改镜像的源文件。相反,它会将需要修改的文件从镜像的只读层复制到容器的可读写层中。这样,容器在修改文件时实际上是在自己的独立文件系统层上进行操作,而不会影响到其他容器或原始镜像。 它的优势在于

  • 对于读操作而言,多个容器可以同时读取相同的镜像文件,因为它们共享的是镜像的只读部分。这种共享使得 Docker 在处理大规模部署时能够节省大量的存储空间和加载时间。
  • 即使多个容器同时访问同一个镜像资源,由于每个容器都有自己的写入层,任何写操作也不会影响其他容器或镜像的源文件。这种隔离性保证了容器间的资源状态和数据的一致性,避免了竞争条件和数据污染问题。
  • 当多个容器同时操作同一文件时,每个容器都会在自己的容器空间中创建自己的读写层,这些层是相互隔离的。因此,每个容器对文件的修改只影响自己的写入层,不会影响其他容器的写入层或原始镜像。这种隔离性非常重要,特别是在微服务架构和容器编排系统(如 Kubernetes)中,能够保证各个服务或任务之间的互不干扰。

生命周期 每一个容器完整生命周期都具有创建,运行,停止,暂停,删除这五个状态。

  • 创建(Create):容器的生命周期始于创建。创建容器可以通过运行 docker create 命令,该命令根据指定的镜像创建一个新的容器实例。在创建时,Docker 会为容器分配一个唯一的标识符(Container ID)和一个可读写层,这个层基于容器镜像的只读层(Image Layer)。
  • 启动(Start):创建容器后,可以使用 docker start 命令启动它。在启动过程中,Docker 会根据容器的配置和指令来设置其运行环境,包括网络设置、挂载的文件系统等。启动后,容器中的应用程序开始运行,开始处理请求或执行指定的任务。
  • 运行(Run):一旦容器启动并成功运行,它将处于运行状态。在这个阶段,容器会持续执行其定义的任务或服务,直到遇到停止条件。
  • 停止(Stop):可以使用 docker stop 命令来停止容器的运行。停止容器会发送一个信号给容器内的应用程序,通知它们停止运行并进行清理。容器的状态从运行状态转变为停止状态,但是容器的状态和数据仍然保留在本地存储中。
  • 删除(Delete):通过 docker rm 命令可以删除停止的容器。删除容器将释放其占用的系统资源,并且容器的数据将不再可访问。如果需要,可以在删除之前进行数据备份或导出操作。
  • 重启(Restart):Docker 还提供了 docker restart 命令,可以快速重新启动一个已经停止的容器,这是在某些情况下重新启动服务的便捷方式。

仓库

仓库可看成一个代码控制中心,可以用来存储和分发 Docker 镜像的地方。最常用的是Docker Hub,它是一个公共的镜像仓库,包含了大量的官方和社区维护的镜像。除了公共仓库,还可以搭建私有的Docker仓库,用于存储和分享自定义的镜像。

Docker Hub 是最广泛使用的公共镜像仓库,由 Docker 官方维护。Docker Hub 包含大量的官方镜像(由 Docker 官方团队维护)和社区镜像(由开源社区或个人开发者维护)。用户可以在 Docker Hub 上搜索、下载、发布和分享 Docker 镜像。它还提供自动构建、镜像扫描等功能。

网络

Docker 网络允许容器之间进行通信,也能通过端口映射将容器的端口映射到主机上,实现与外部网络的连接。Docker 提供了多种网络驱动程序,以适应不同的需求和使用场景。 常见的 Docker 网络驱动程序如下

  • Bridge Network(桥接网络):容器会被连接到默认的桥接网络 bridge。容器通过桥接网络可以相互通信,并且与主机系统隔离。适合单机环境中的容器通信。
  • Host Network(主机模式):容器将直接使用主机的网络栈。这意味着容器将与主机共享 IP 地址和端口空间。
  • Overlay Network(覆盖网络):允许容器跨多个 Docker 主机通信,非常适合分布式应用和容器编排工具
  • None Network(无网络):容器启动后没有任何网络连接。适用于不需要网络连接的应用或需要完全隔离的场景。
  • Macvlan Network:允许容器具有自己的 MAC 地址,使得它们看起来像网络上的物理设备。

除此之外,Docker提供了网络命名空间的隔离机制,使得每个容器拥有独立的网络栈。守护进程为每个容器分配一个唯一的IP地址,并为容器设置网络接口和网络路由规则。

Docker卷是用于在容器中持久化存储数据的一种机制。通过挂载卷到容器的特定路径上,可以实现容器内数据的共享和存储。 Docker卷可以是主机上的目录,也可以使用Docker卷插件提供的其他存储后端。当使用主机上的目录作为卷时,容器中的数据会直接存储在主机上的相应路径下。这样的话,即使容器被删除或重新创建,数据仍然可以被保留下来。 另一种方式是使用Docker卷插件提供的其他存储后端,例如网络存储或云存储。这些存储后端可以提供更高级的功能,如备份、快照、复制等。使用这种方式,卷中的数据可以被持久化存储在一个独立于主机的存储系统中,从而实现跨多个容器的数据共享和持久化。 总之,Docker卷是一种非常有用的功能,可以帮助我们在容器中方便地进行数据的共享和持久化存储,无论是使用主机上的目录还是其他存储后端。通过数据卷(Volume)和绑定挂载(Bind Mount)我们实现了数据的持久化和共享。

底层技术

要实现一个完整的容器,我们需要容器提供隔离机制、资源分配、网络通信等能力。docker 需要依赖以下三项关键的Linux技术:Namespace、Cgroups 和UnionFS(联合文件系统)。让我们逐一解释它们的作用:

Namespace(命名空间)

Namespace 是 Linux 内核用来隔离内核资源的一种方式。提供了一种机制,可以将系统资源隔离给特定的进程组。通过使用命名空间,不同的容器可以拥有各自独立的系统视图,包括进程ID、网络接口、用户ID、文件名、网络访问和进程间通信等,使得进程只能访问与自身相关的那部分资源,其他资源不可见。 主要涉及以下六种命名空间:

  • PID Namespace:隔离进程ID,确保容器内的进程ID不会与其他容器或主机冲突。
  • Net Namespace:隔离网络设备,允许每个容器有自己的虚拟网络接口、IP地址和路由表。
  • Mount Namespace:隔离文件系统挂载点,使得容器可以拥有独立的文件系统视图。
  • UTS Namespace:隔离主机名和域名,为每个容器提供独立的主机名。
  • IPC Namespace:隔离进程间通信资源(如信号量、消息队列等)。
  • User Namespace:隔离用户和用户组ID,使得容器内的用户ID和主机上的用户ID可以不同。

Cgroups(控制组)

Cgroups 是控制组群,control groups 的缩写,供了一种可以限制、记录和隔离进程组所使用的系统资源(如CPU、内存、磁盘I/O等)的机制。通过Cgroups,管理员可以控制每个容器的资源使用,防止某个容器消耗过多资源影响其他容器。Cgroups 通常用来限制容器的 CPU 和内存等资源的使用。质上来说,cgroups 是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。 主要控制项:

  • CPU:限制和优先级分配。
  • Memory:内存使用限制和监控。
  • Block I/O:磁盘I/O速率限制。
  • Network:网络带宽限制。

联合文件系统

联合文件系统是一种分层、轻量级并且高性能的文件系统,它允许将多个文件系统叠加在一起形成一个单一的虚拟文件系统。它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。 在Docker 的世界中,联合文件系统为容器提供构建层,使得容器可以实现写时复制以及镜像的分层构建和存储。 镜像本身是只读的,在运行某个容器的时候,会在镜像外层附加一个可读写层,这也是基于联合文件系统实现的。 它的主要特点包括:

  • 分层架构:联合文件系统由多个只读层(镜像层)和一个可写层(容器层)组成。镜像层是只读的,用于存储基础镜像的文件和目录,而容器层是可写的,用于记录容器中发生的修改。这种分层架构使得多个容器可以共享相同的只读镜像层,从而节省存储空间。
  • 轻量级:由于联合文件系统只记录了文件和目录的变化,而不是复制整个文件系统的副本,因此它在存储和传输方面非常高效。每个容器只需要保存自己的修改层,而不需要复制整个文件系统。
  • 高性能:联合文件系统使用了写时复制(Copy-on-Write)的机制,即只有在需要修改文件或目录时才进行复制操作。这样可以减少磁盘IO和内存消耗,提高文件系统的性能。
  • 挂载多个目录:联合文件系统可以将不同的目录挂载到同一个虚拟文件系统下。这样可以实现文件系统的合并和共享,使得多个文件系统的内容在逻辑上看起来像是一个统一的文件系统。

下图中每一行命令都会生成一个镜像层,当不同的镜像之间有相同的镜像层时,便可以实现不同的镜像之间共享镜像层的效果。(比如基于base镜像扩展的镜像)

常见命令

bash
docker pull 仓库地址/命名空间/镜像名称:标签

选项参数:

  • 仓库地址:没有显式指定仓库地址时,默认会从DockerHub查找镜像;拉取私有仓库的镜像,需要指定仓库地址。
  • 命名空间:用以区分不同的个人或组织发布的镜像。没有显式指定命名空间时,默认会查找官方团队发布的镜像。
  • 镜像名称:需要拉取的镜像的名称。
  • 标签:没有显式指定标签时,默认会拉取 latest 标签, latest 表示这是最新的版本。

通过 docker pull 拉取镜像并不是必须的,在 docker run 时,如果本地不存在指定镜像,Docker会自动拉取。

bash
# 截图对应命令 docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:latest # 完整命令 docker run [选项参数] 仓库地址/命名空间/镜像名称:标签 [命令行] [命令行参数]

选项参数:

  • --name :设置容器名称,不能重复,这里使用的是 镜像名_版本号 的方式。
  • -p :设置端口映射,将宿主机的 3306 端口映射到容器的 3306 端口,宿主机上的其他进程通过该端口才能访问到容器内的服务。如果不配置端口映射,则只能在容器内部访问服务或通过虚拟网络让容器可以相互通信。
  • -e :设置环境变量,配置 MYSQL_ROOT_PASSWORD=root 用以指定root用户密码,这是由镜像创建者约定的,不同的镜像配置项会有所不同。
  • -v :设置目录挂载,用法参考 目录挂载 章节。
  • -d :让容器在后台运行

镜像推拉命令

bash
# 从 Docker Hub 拉取镜像 docker pull nginx # 将本地镜像推送到 Docker Hub docker tag my-app:latest myusername/my-app:latest docker push myusername/my-app:latest # 启动一个本地的 Docker Registry 容器 docker run -d -p 5000:5000 --name registry registry:2 # 将本地镜像推送到私有 Registry docker tag my-app:latest localhost:5000/my-app:latest docker push localhost:5000/my-app:latest # 从私有 Registry 拉取镜像 docker pull localhost:5000/my-app:latest

docker其它常见命令

bash
# 列出所有容器 docker ps -a # 列出所有镜像 docker image ls docker images # 启动容器 docker start 容器名称/容器ID # 停止容器 docker stop 容器名称/容器ID # 强制停止容器 docker kill 容器名称/容器ID # 重启容器 docker restart 容器名称/容器ID # 删除容器 docker rm 容器名称/容器ID # 删除镜像 docker rmi 容器名称/容器ID

实战流程

想要通过 Docker 将项目部署到服务器上或是分发项目供他人使用,就需要将项目构建为镜像,通过 Dockerfile 构建镜像是一种常见的做法。Dockerfile 是一个文本文件,其中包含了一系列的命令和参数,用于定义在构建镜像时的操作步骤。通过编写 Dockerfile,你可以指定所需的基础镜像、设置环境变量、运行命令、添加文件等操作,最终将这些步骤打包成一个镜像,方便部署到服务器上或者分发给他人使用。

编写Dockerfile文件

Dockerfile常用指令:

  • FROM:指定基础镜像。所有后续的操作都是基于这个基础镜像进行的。
  • WORKDIR:设定后续命令的执行目录。
  • COPY:复制文件、指定目录中的所有内容(不含目录本身)到镜像中。
  • ADD:复制文件、指定目录中的所有内容(不含目录本身)到镜像中。对tar格式的压缩文件会自动解压。
  • RUN:构建过程中执行命令。比如安装一些软件,创建一些文件等。
  • CMD: 为容器提供默认的执行命令,会被 docker run 的命令行参数覆盖。
  • ENTRYPOINT: 为容器提供默认的执行命令,不会被 docker run 的命令行参数覆盖。
  • EXPOSE: 公开容器的一个端口供外部访问。
bash
# 使用基础镜像 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 复制项目文件到工作目录 COPY . . # 安装依赖 RUN pip install -r requirements.txt # 暴露端口 EXPOSE 8000 # 启动应用 CMD ["python", "app.py"]

构建镜像

写好 Dockerfile 后,就可以通过该文件构建镜像了。

bash
docker build -t 仓库地址/命名空间/镜像名:标签 . docker build -t 仓库地址/命名空间/镜像名:标签 -f /path/myDockerfile .

选项参数:

  • -t 指定镜像名称(如果不推送到私有仓库,仅本地使用, 仓库地址/命名空间/ 可以省略)。
  • -f 指定 Dockerfile 所在的目录,也可以指定 自定义名称的Dockerfile ( -f 参数可省略)。
  • . 使用当前目录下作为上下文环境, COPY 等命令会从该目录查找文件。未指定 -f 参数时,则使用上下文环境中名为 Dockerfile 的文件。

推送镜像

每次发布更改内容都需要打包镜像后上传到生产环境再部署很麻烦,将镜像推送到私有仓库,并在生产环境直接从仓库中拉取镜像更加高效。

bash
# 登录仓库 docker login 仓库地址 docker tag myapp:latest myusername/myapp:latest # 推送镜像 仓库地址/命名空间/镜像名:标签 docker push myusername/myapp:latest

Docker Compose

当项目依赖的服务较多时,每个容器都要单独配置运行,指定网络。使用Docker Compose,可以通过一个YAML文件定义服务,并同时运行它们。使用 Docker Compose 可以大大简化管理和部署多个服务的过程。Docker Compose 允许你通过一个 YAML 文件定义所有相关的服务、网络、卷等配置,并通过一个命令同时启动这些服务。 Docker Compose 将所管理的容器分为三层:工程(Project)、服务(Service)、容器(Container)。

  • 所有服务在工程中共享同样的网络、卷等资源。
  • 各个服务之间可以互相通信。
  • 属于同一服务的所有容器都有统一的配置,容器间有一定的隔离性。

在要部署项目的目录创建一个 docker-compose.yml 文件:

bash
version: '3' services: web: image: myusername/myapp:latest ports: - "8000:8000" depends_on: - db environment: - DATABASE_HOST=db - DATABASE_PORT=5432 networks: - mynetwork db: image: postgres:13 environment: POSTGRES_USER: exampleuser POSTGRES_PASSWORD: examplepass POSTGRES_DB: exampledb volumes: - db-data:/var/lib/postgresql/data networks: - mynetwork volumes: db-data: networks: mynetwork:

在 docker-compose.yml 文件所在的目录执行

bash
docker compose up -d

docker compose up 根据 docker-compose.yml 文件内容启动、创建、连接服务。 -d 参数表示以后台方式运行。 -f 如果文件名称不是 docker-compose.yml ,可以通过 -f 命令指定,使用方法与 构建镜像 章节一致。 每次更改了 docker-compose.yml 文件,都需要重新运行 docker-compose up -d 命令以应用更改。

本文作者:sora

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!