覆盖容器默认值

解释

当 Docker 容器启动时,它会执行应用程序或命令。容器从其镜像的配置中获取此可执行文件(脚本或文件)。容器附带通常运行良好的默认设置,但您可以根据需要更改它们。这些调整有助于容器的程序完全按照您希望的方式运行。

例如,如果您有一个侦听标准端口的现有数据库容器,并且您想要运行同一数据库容器的新实例,那么您可能希望更改新容器侦听的端口设置,以便它不会与现有容器冲突。有时,如果程序需要更多资源来处理繁重的工作负载,或者设置环境变量以提供程序正常运行所需的特定配置详细信息,则可能需要增加容器的可用内存。

docker runCommand 提供了一种强大的方法来覆盖这些默认值并根据您的喜好定制容器的行为。该命令提供了几个标志,允许您动态自定义容器行为。

以下是实现这一目标的几种方法。

覆盖网络端口

有时,您可能希望使用单独的数据库实例进行开发和测试。在同一端口上运行这些数据库实例可能会发生冲突。您可以使用-p选项docker run将容器端口映射到主机端口,从而允许您运行容器的多个实例而不会发生任何冲突。

$ docker run -d -p HOST_PORT:CONTAINER_PORT postgres

设置环境变量

此选项设置环境变量foo在容器内,值为bar.

$ docker run -e foo=bar postgres env

您将看到如下所示的输出:

HOSTNAME=2042f2e6ebe4
foo=bar

提示

.env文件可以作为一种为 Docker 容器设置环境变量的便捷方法,而不会使命令行中大量-e标志。要使用.env文件中,您可以传递--env-file选项替换为docker run命令。

$ docker run --env-file .env postgres env

限制容器使用资源

您可以使用--memory--cpus带有docker run命令来限制容器可以使用的 CPU 和内存量。例如,您可以为 Python API 容器设置内存限制,以防止其消耗主机上的过多资源。命令如下:

$ docker run -e POSTGRES_PASSWORD=secret --memory="512m" --cpus="0.5" postgres

此命令将容器内存使用限制为 512 MB,并将半个内核的 CPU 配额定义为 0.5。

监控实时资源使用情况

您可以使用docker stats命令监控正在运行的容器的实时资源使用情况。这有助于您了解分配的资源是否足够或是否需要调整。

通过有效地使用这些docker run标志,您可以定制容器化应用程序的行为以满足您的特定要求。

试用

在本动手指南中,您将了解如何使用docker run命令覆盖容器默认值。

  1. 下载并安装Docker 桌面。

运行 Postgres 数据库的多个实例

  1. 通过以下命令使用 Postgres 镜像启动容器:

    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5432:5432 postgres
    

    这将在后台启动 Postgres 数据库,侦听标准容器端口5432并映射到端口5432在主机上。

  2. 启动映射到其他端口的第二个 Postgres 容器。

    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5433:5432 postgres
    

    这将在后台启动另一个 Postgres 容器,侦听标准 postgres 端口5432在容器中,但映射到 port5433在主机上。您覆盖主机端口只是为了确保这个新容器不会与现有正在运行的容器冲突。

  3. 转到 Docker Desktop 控制面板中的 Containers (容器) 视图,验证两个容器是否都在运行。

    Docker Desktop Dashboard 的屏幕截图,其中显示了正在运行的 Postgres 容器实例

在受控网络中运行 Postgres 容器

默认情况下,当您运行容器时,它们会自动连接到一个称为桥接网络的特殊网络。此桥接网络就像一个虚拟桥接器,允许同一主机上的容器相互通信,同时使它们与外界和其他主机隔离。对于大多数容器交互来说,这是一个方便的起点。但是,对于特定方案,您可能希望对网络配置进行更多控制。

这就是自定义网络的用武之地。您可以通过传递--networkflag 替换为docker run命令。所有没有--network标志附加到默认桥接网络。

按照步骤了解如何将 Postgres 容器连接到自定义网络。

  1. 使用以下命令创建新的自定义网络:

    $ docker network create mynetwork
    
  2. 通过运行以下命令验证网络:

    $ docker network ls
    

    此命令列出所有网络,包括新创建的 “mynetwork”。

  3. 使用以下命令将 Postgres 连接到自定义网络:

    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5434:5432 --network mynetwork postgres
    

    这将在后台启动 Postgres 容器,映射到主机端口 5434 并附加到mynetwork网络。您传递了--network参数,通过将容器连接到自定义 Docker 网络来覆盖容器默认值,以便更好地隔离并与其他容器通信。您可以使用docker network inspect命令查看容器是否绑定到这个新的桥接网络。

    默认网桥网络和自定义网络之间的主要区别

    1. DNS 解析:默认情况下,连接到默认桥接网络的容器可以相互通信,但只能通过 IP 地址进行通信。(除非您使用--link选项,该选项被视为旧版)。由于各种技术缺陷,不建议用于生产。在自定义网络上,容器可以按名称或别名相互解析。
    2. 隔离:所有没有--networkspecified 附加到默认桥接网络,因此可能存在风险,因为不相关的容器随后能够进行通信。使用自定义网络可提供一个分区网络,在该网络中,只有连接到该网络的容器才能进行通信,从而提供更好的隔离。

管理资源

默认情况下,容器的资源使用不受限制。但是,在共享系统上,有效管理资源至关重要。重要的是,不要让正在运行的容器消耗过多的主机内存。

这就是docker runCommand 再次闪耀。它提供像--memory--cpus以限制容器可以使用的 CPU 和内存量。

$ docker run -d -e POSTGRES_PASSWORD=secret --memory="512m" --cpus=".5" postgres

--cpusflag 指定容器的 CPU 配额。在这里,它被设置为半个 CPU 核心 (0.5),而--memoryflag 指定容器的内存限制。在本例中,它设置为 512 MB。

覆盖 Docker Compose 中的默认 CMD 和 ENTRYPOINT

有时,您可能需要覆盖默认命令 (CMD) 或入口点 (ENTRYPOINT),尤其是在使用 Docker Compose 时。

  1. 创建一个compose.yml文件,其中包含以下内容:

    services:
      postgres:
        image: postgres
        entrypoint: ["docker-entrypoint.sh", "postgres"]
        command: ["-h", "localhost", "-p", "5432"]
        environment:
          POSTGRES_PASSWORD: secret 

    Compose 文件定义了一个名为postgres使用官方 Postgres 镜像,设置入口点脚本,并使用密码身份验证启动容器。

  2. 通过运行以下命令启动服务:

    $ docker compose up -d
    

    此命令启动 Docker Compose 文件中定义的 Postgres 服务。

  3. 使用 Docker Desktop Dashboard 验证身份验证。

    打开 Docker Desktop Dashboard,选择 Postgres 容器,然后选择 Exec 以进入容器 shell。您可以键入以下命令以连接到 Postgres 数据库:

    # psql -U postgres
    
    Docker Desktop Dashboard 选择 Postgres 容器并使用 EXEC 按钮进入其 shell 的屏幕截图

    注意

    PostgreSQL 镜像在本地设置信任身份验证,因此您可能会注意到从 localhost(在同一容器内)连接时不需要密码。但是,如果从其他主机/容器连接,则需要密码。

用 Override the default CMD and ENTRYPOINT withdocker run

您也可以直接使用docker run命令替换为以下命令:

$ docker run -e POSTGRES_PASSWORD=secret postgres docker-entrypoint.sh -h localhost -p 5432

此命令运行 Postgres 容器,设置用于密码身份验证的环境变量,覆盖默认启动命令并配置主机名和端口映射。

其他资源

后续步骤

现在,您已经了解了如何覆盖容器默认值,是时候学习如何持久化容器数据了。