使用 Envoy Docker 镜像

注意

Envoy OCI 镜像是使用 Docker 构建的,并在运行 Docker 的大规模部署中经过了广泛测试。使用其他容器技术(如 Podman)可能正常运行,但尚未经过广泛测试,也不明确支持。

以下示例使用 官方 Envoy OCI 镜像

这些说明已知适用于 x86_64arm64 架构。

使用 docker compose 运行 Envoy

如果你想使用 Envoy 和 docker compose,你可以使用卷覆盖提供的配置文件。

version: '3'
services:
  envoy:
    image: envoyproxy/envoy:dev-fcdc9d6d5a9da98fe30ad749201034770ff6b30e
    ports:
      - "10000:10000"
    volumes:
      - ./envoy.yaml:/etc/envoy/envoy.yaml

如果你使用此方法,则需要确保 envoy 用户可以读取已挂载的文件,方法是确保文件具有正确的权限,或者使其可供所有人读取,如下所述。

使用 Docker 构建和运行 Envoy 镜像

创建一个简单的 Dockerfile 来执行 Envoy。

如果你创建了一个自定义的 envoy.yaml,可以使用以下 Dockerfile 配方,使用它创建自己的 Docker 镜像

FROM envoyproxy/envoy:dev-fcdc9d6d5a9da98fe30ad749201034770ff6b30e
COPY envoy.yaml /etc/envoy/envoy.yaml
RUN chmod go+r /etc/envoy/envoy.yaml

使用以下命令构建 Docker 镜像

$ docker build -t envoy:v1 .

假设 Envoy 配置为监听端口 990110000,现在可以使用 Docker 在 Docker 中启动它

$ docker run -d --name envoy -p 9901:9901 -p 10000:10000 envoy:v1

或者在 Podman(不支持)中使用

$ podman run -d --name envoy -p 9901:9901 -p 10000:10000 envoy:v1

在容器中运行 Envoy 的根文件系统权限

Envoy 容器镜像可以与容器的根文件系统挂载为只读状态一起运行。例如,使用 Docker 和 Podman,可以使用 run 命令的 --read-only 选项。

使用 Kubernetes,这意味着将 podSpec.containers.securityContext.readOnlyFilesystem 设置为 true

使用 Nomad,这意味着在使用 dockerpodman 驱动程序时,在任务的 config 块中设置 readonly_rootfs = true

以非 root 用户身份在容器中运行 Envoy 的权限

默认情况下,Envoy OCI 镜像将以 root 用户身份启动,但在 Docker ENTRYPOINT 中,它将切换到构建时创建的 envoy 用户。

或者,你可以启动指定 Docker user 的容器。

在这种情况下,容器不会尝试降低特权,但你仍然需要确保在容器内运行的用户具有任何必需的权限,如下所述。

更改容器内 envoy 用户的 uid 和/或 gid

envoy 用户的默认 uidgid101

可以使用 ENVOY_UIDENVOY_GID 环境变量在运行时设置此用户的 uidgid

例如,可以在 Docker 命令行上执行此操作

$ docker run -d --name envoy -e ENVOY_UID=777 -e ENVOY_GID=777 envoyproxy/envoy:dev-fcdc9d6d5a9da98fe30ad749201034770ff6b30e

如果你希望限制或提供对容器内的 unix 套接字的访问,或者用于控制从容器外部对 Envoy 套接字的访问,这将非常有用。

要将容器内的进程作为 root 用户运行,可以将 ENVOY_UID 设置为 0,但这样做可能会降低正在运行的容器的安全性。

Envoy 容器内的日志记录权限

envoy 镜像默认将应用程序日志发送到 /dev/stdout/dev/stderr,这些日志可以在容器日志中查看。

如果你将应用程序、管理或访问日志发送到文件输出,则 envoy 用户将需要写入此文件的必要权限。这可以通过设置 ENVOY_UID 和/或使文件可供 envoy 用户写入来实现。

例如,要从主机挂载日志文件夹并使其可写,可以使用

$ mkdir logs
$ chown 777 logs
$ docker run -d --name envoy -v $(pwd)/logs:/var/log -e ENVOY_UID=777 envoyproxy/envoy:dev-fcdc9d6d5a9da98fe30ad749201034770ff6b30e

然后,你可以配置 envoy 将日志记录到 /var/log 中的文件

Envoy 容器内的配置和二进制文件权限

envoy 用户还需要有权访问挂载到容器中的任何必需配置文件。

配置中指定的任何二进制文件也应该可供 envoy 用户执行。

如果你在具有严格 umask 设置的环境中运行,则可能需要通过设置文件的拥有权和/或权限来为 envoy 提供访问权限。

一种无需更改任何文件权限即可执行此操作的方法是使用主机用户的 uid 启动容器,例如

$ docker run -d --name envoy -v $(pwd)/envoy.yaml:/etc/envoy/envoy.yaml -e ENVOY_UID=$(id -u) envoyproxy/envoy:dev-fcdc9d6d5a9da98fe30ad749201034770ff6b30e

仅在 Envoy 容器内的端口 > 1024 上监听

基于 Unix 的系统将限制打开 well-known 端口(即端口号 < 1024)的权限,仅限于 root 用户。

如果你需要监听 well-known 端口,可以使用 Docker 来实现。

例如,要创建一个在端口 8000 上监听的 Envoy 服务器,并从端口 80 进行转发

$ docker run -d --name envoy -p 80:8000 envoyproxy/envoy:dev-fcdc9d6d5a9da98fe30ad749201034770ff6b30e