覆盖容器默认值

说明

当 Docker 容器启动时,它会执行一个应用程序或命令。容器从其镜像的配置中获取这个可执行文件(脚本或文件)。容器带有通常运行良好的默认设置,但如果需要,你可以更改它们。这些调整有助于容器的程序按照你的要求精确运行。

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

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

有几种方法可以实现这一点。

覆盖网络端口

有时您可能希望为开发和测试目的使用单独的数据库实例。在同一端口上运行这些数据库实例可能会产生冲突。您可以使用 -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 文件,可以在 docker run 命令中传递 --env-file 选项。

$ 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 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 Desktop 仪表板中的 Containers 视图验证两个容器是否正在运行。

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

在受控网络中运行 Postgres 容器

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

自定义网络就在这里发挥作用。您可以通过在 docker run 命令中传递 --network 标志来创建自定义网络。所有不带 --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 Desktop 仪表板验证身份。

    打开 Docker Desktop 仪表板,选择 Postgres 容器并选择 Exec 进入容器 shell。您可以输入以下命令连接到 Postgres 数据库:

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

    注意

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

使用 docker run 覆盖默认的 CMD 和 ENTRYPOINT

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

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

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

其他资源

后续步骤

既然您已经了解了如何覆盖容器默认设置,那么现在该学习如何持久化容器数据了。