覆盖容器默认值

解释

当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 文件,您可以在 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 仪表板中的容器视图,验证两个容器是否都在运行。

    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 resolution: By default, containers connected to the default bridge network can communicate with each other, but only by IP address. (unless you use --link option which is considered legacy). It is not recommended for production use due to the various technical shortcomings. On a custom network, containers can resolve each other by name or alias.
    2. Isolation: All containers without a --network specified are attached to the default bridge network, hence can be a risk, as unrelated containers are then able to communicate. Using a custom network provides a scoped network in which only containers attached to that network are able to communicate, hence providing better isolation.

管理资源

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

这是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 镜像在本地设置了信任认证,因此您可能会注意到从本地主机(同一容器内)连接时不需要密码。但是,如果从不同的主机/容器连接,则需要密码。

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

你也可以直接使用docker run命令来覆盖默认值,命令如下:

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

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

其他资源

下一步

既然你已经了解了如何覆盖容器默认设置,现在是时候学习如何持久化容器数据了。