覆盖容器默认设置
解释
当 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
Tip
.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 命令覆盖容器默认设置。
- 下载并安装 Docker Desktop。
运行 Postgres 数据库的多个实例
-
使用以下命令使用 Postgres 镜像 启动一个容器:
$ docker run -d -e POSTGRES_PASSWORD=secret -p 5432:5432 postgres这将在后台启动 Postgres 数据库,监听容器标准端口
5432并映射到主机的端口5432。 -
启动第二个 Postgres 容器,映射到不同的端口。
$ docker run -d -e POSTGRES_PASSWORD=secret -p 5433:5432 postgres这将在后台启动另一个 Postgres 容器,在容器内监听标准 postgres 端口
5432,但映射到主机的端口5433。您覆盖了主机端口,只是为了确保这个新容器不会与现有的正在运行的容器发生冲突。 -
通过转到 Docker Desktop 仪表板中的 Containers(容器)视图,验证两个容器是否都在运行。
在受控网络中运行 Postgres 容器
默认情况下,当您运行容器时,它们会自动连接到一个名为桥接网络(bridge network)的特殊网络。这个桥接网络就像一个虚拟网桥,允许同一主机上的容器相互通信,同时将它们与外部世界和其他主机隔离开来。对于大多数容器交互来说,这是一个方便的起点。然而,在特定场景下,您可能希望对网络配置有更多控制。
这就是自定义网络的用武之地。您可以通过在 docker run 命令中传递 --network 标志来创建自定义网络。所有没有 --network 标志的容器都连接到默认的桥接网络。
请按照以下步骤了解如何将 Postgres 容器连接到自定义网络。
-
使用以下命令创建一个新的自定义网络:
$ docker network create mynetwork -
通过运行以下命令验证网络:
$ docker network ls此命令列出所有网络,包括新创建的 "mynetwork"。
-
使用以下命令将 Postgres 连接到自定义网络:
$ docker run -d -e POSTGRES_PASSWORD=secret -p 5434:5432 --network mynetwork postgres这将在后台启动 Postgres 容器,映射到主机端口 5434,并附加到
mynetwork网络。您传递了--network参数以覆盖容器默认设置,将容器连接到自定义 Docker 网络,以便更好地隔离并与其他容器通信。您可以使用docker network inspect命令查看容器是否绑定到这个新的桥接网络。默认桥接网络和自定义网络之间的关键区别
- DNS 解析:默认情况下,连接到默认桥接网络的容器可以相互通信,但只能通过 IP 地址。(除非您使用
--link选项,但这被认为是遗留的)。由于各种 技术缺陷,不建议在生产环境中使用。在自定义网络上,容器可以通过名称或别名相互解析。 - 隔离:所有未指定
--network的容器都连接到默认桥接网络,因此可能存在风险,因为不相关的容器也能够通信。使用自定义网络可提供一个范围限定的网络,只有连接到该网络的容器才能通信,从而提供更好的隔离。
- DNS 解析:默认情况下,连接到默认桥接网络的容器可以相互通信,但只能通过 IP 地址。(除非您使用
管理资源
默认情况下,容器的资源使用不受限制。但是,在共享系统上,有效管理资源至关重要。不要让正在运行的容器消耗过多的主机内存。
这就是 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 时。
-
创建一个包含以下内容的
compose.yml文件:services: postgres: image: postgres:18 entrypoint: ["docker-entrypoint.sh", "postgres"] command: ["-h", "localhost", "-p", "5432"] environment: POSTGRES_PASSWORD: secretCompose 文件定义了一个名为
postgres的服务,该服务使用官方 Postgres 镜像,设置一个入口点脚本,并使用密码认证启动容器。 -
通过运行以下命令启动服务:
$ docker compose up -d此命令启动 Docker Compose 文件中定义的 Postgres 服务。
-
使用 Docker Desktop 仪表板验证身份验证。
打开 Docker Desktop 仪表板,选择 Postgres 容器,然后选择 Exec 进入容器 shell。您可以键入以下命令连接到 Postgres 数据库:
# psql -U postgres
NotePostgreSQL 镜像在本地设置了信任认证,因此您可能会注意到从 localhost(同一容器内)连接时不需要密码。但是,如果从不同的主机/容器连接,则需要密码。
使用 docker run 覆盖默认的 CMD 和 ENTRYPOINT
您也可以直接使用 docker run 命令覆盖默认值,命令如下:
$ docker run -e POSTGRES_PASSWORD=secret postgres docker-entrypoint.sh -h localhost -p 5432
此命令运行一个 Postgres 容器,为密码认证设置一个环境变量,覆盖默认的启动命令,并配置主机名和端口映射。
其他资源
下一步
现在您已经了解了如何覆盖容器默认设置,是时候学习如何持久化容器数据了。
持久化容器数据