覆盖容器默认值

说明

当 Docker 容器启动时,它会执行应用程序或命令。容器从其镜像的配置中获取此可执行文件(脚本或文件)。容器附带默认设置,这些设置通常可以正常工作,但您可以在需要时更改它们。这些调整有助于容器的程序按照您的预期运行。

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

docker run 命令提供了一种强大的方法来覆盖这些默认值,并根据您的喜好定制容器的行为。该命令提供了几个标志,让您能够即时定制容器的行为。

以下是您可以实现此目的的一些方法。

覆盖网络端口

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

$ 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

限制容器消耗资源

您可以使用 docker run 命令中的 --memory--cpus 标志来限制容器可以使用的 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 Desktop。

运行多个 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,但映射到主机上的端口 5433。您覆盖主机端口只是为了确保此新容器不会与正在运行的现有容器冲突。

  3. 通过转到 Docker 仪表板的**容器**视图,验证这两个容器是否正在运行。

    A screenshot of Docker Dashboard showing the running instances of Postgres containers

在受控网络中运行 Postgres 容器

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

自定义网络此时就派上用场了。您可以通过将 --network 标志与 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. 隔离:所有未指定 --network 的容器都将附加到默认桥接网络,因此存在风险,因为无关的容器能够相互通信。使用自定义网络提供一个范围网络,其中只有附加到该网络的容器能够相互通信,从而提供更好的隔离。

管理资源

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

这正是 docker run 命令再次发挥作用的地方。它提供了 --memory--cpus 等标志来限制容器可以使用的 CPU 和内存。

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

--cpus 标志指定容器的 CPU 配额。此处将其设置为半个 CPU 核心 (0.5),而 --memory 标志指定容器的内存限制。在本例中,将其设置为 512 MB。

覆盖 Docker Compose 中的默认 CMD 和 ENTRYPOINT

有时,您可能需要覆盖 Docker 镜像中定义的默认命令 (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 仪表板验证身份验证。

    打开 Docker 仪表板,选择**Postgres** 容器,然后选择**Exec** 进入容器 shell。您可以键入以下命令来连接到 Postgres 数据库

    # psql -U postgres
    
    A screenshot of the Docker Dashboard selecting the Postgres container and entering into its shell using EXEC button

    注意

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

使用 docker run 覆盖默认 CMD 和 ENTRYPOINT

您也可以使用以下命令,通过 `docker run` 命令直接覆盖默认设置

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

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

其他资源

下一步

现在您已经了解了如何覆盖容器默认设置,接下来学习如何持久化容器数据。