无法将环境变量传递给容器

Unable to pass the env variable to container

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine

ENV CORECLR_ENABLE_PROFILING=1 \
    CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8} \
    CORECLR_PROFILER_PATH=/opt/datadog/Datadog.Trace.ClrProfiler.Native.so \
    DD_INTEGRATIONS=/opt/datadog/integrations.json \
    DD_DOTNET_TRACER_HOME=/opt/datadog

WORKDIR /app

RUN apk --no-cache update \
    && apk add bash make curl

ARG TRACER_VERSION=1.19.1

RUN mkdir -p /opt/datadog
RUN curl -L https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm-${TRACER_VERSION}.tar.gz \
    |  tar xzf - -C /opt/datadog
WORKDIR /app
COPY --from=buildcontainer /app/build .

COPY ./Entrypoint.sh /
RUN chmod +x /Entrypoint.sh && /Entrypoint.sh

ENTRYPOINT ["dotnet","testdatadog.dll"]

Entrypoint.sh

#!/bin/bash
set -e
curl http://169.254.169.254/latest/meta-data/local-ipv4 > temp_var
export DD_AGENT_HOST=$(cat temp_var)
exec "$@"

当我通过 ssh 进入我的 ec2 并查看环境变量时,我没有看到 DD_AGENT_HOST 集。当我手动尝试设置 env 时它起作用了。我错过了什么吗?感谢输入。

这个:

RUN chmod +x /Entrypoint.sh && /Entrypoint.sh

实际上 运行 是以下命令:

bash -c "chmod +x /Entrypoint.sh && /Entrypoint.sh"

您的脚本为 运行 所在的 Bash 实例设置环境变量,该实例在脚本完成后立即退出,丢弃其环境。

您需要将 Entrypoint.sh 的执行移动到 ENTRYPOINT 行。

编辑:

所以这是我的测试Dockerfile(请注意,复制和更改脚本的权限是在单独的阶段完成的,以减小最终图像的大小):

FROM alpine:latest AS build

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

FROM alpine:latest

RUN apk add --no-cache bash
COPY --from=build /entrypoint.sh /entrypoint.sh

ENTRYPOINT [ "/entrypoint.sh", "sleep", "10m" ]

entrypoint.sh

#!/bin/bash

set -e
echo "127.0.0.1" > temp_var
export DD_AGENT_HOST=$(cat temp_var)
exec "$@"

我运行以下命令:

docker build -t entrypoint-test .
docker run -itd --rm --name entrypoint entrypoint-test:latest
docker exec -it entrypoint bash

和里面新开的Bashshell:

export

结果:

declare -x HOME="/root"
declare -x HOSTNAME="c951e699bf7b"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/"
declare -x SHLVL="1"
declare -x TERM="xterm"

没有DD_AGENT_HOST!

所以我搜索了容器的主进程(在我的例子中 sleep

ps -a | grep sleep

得到了

 1 root      0:00 sleep 10m
32 root      0:00 grep sleep

最后我运行

strings /proc/1/environ

查看该进程的环境。

结果:

HOSTNAME=3f9760ceb473
PWD=/
HOME=/root
TERM=xterm
SHLVL=0
DD_AGENT_HOST=127.0.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

DD_AGENT_HOST 找到了!

发生了什么事?

很简单。 entrypoint.sh 仅为它执行的进程设置变量 - 在我的例子中 sleepdocker exec 创建一个新的、不相关的进程 运行ning Bash。由于新进程(在 Linux 和 Windows 中)从父进程继承环境,并且由 docker exec 生成的新 Bash 进程不是子进程(而是容器主进程的兄弟),它不知道 DD_AGENT_HOST 变量。

希望对您有所帮助。

编辑 2:

我相信的意思是你可以替换

ENTRYPOINT [ "/entrypoint.sh", "sleep", "10m" ]

ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "sleep", "10m" ]

然后你可以运行

docker run -it --rm --name entrypoint entrypoint-test:latest bash

以便 entrypoint.sh 执行 bash 而不是 sleep 10m,允许您直接检查环境而不是通过 /proc/$pid/environ

你的 Dockerfile 中的等价物是:

ENTRYPOINT [ "/Entrypoint.sh" ]
CMD [ "dotnet" , "testdatadog.dll" ]

问题的要点是您的指令 RUN chmod +x /Entrypoint.sh && /Entrypoint.sh 在构建时执行,并且对您的运行时环境没有影响。

Konrad 正确地更改您的 ENTRYPOINT 以 Entrypoint.sh 改变您的环境。

Konrad 解决方案的问题是,他用来启动容器的 run 命令对 docker [=49= 的 bash shell 没有影响] 当他发出 exec 命令时。

稍微扩展 Konrad 的回答,您实际上可以 entrypoint.sh 为您设置环境。

我复制了 Konrad 的 Dockerfile,但将 ENTRYPOINT 更改如下:

FROM alpine:latest AS build

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

FROM alpine:latest

RUN apk add --no-cache bash
COPY --from=build /entrypoint.sh /entrypoint.sh

ENTRYPOINT [ "/entrypoint.sh", "bash" ]

现在,entrypoint.sh 将设置环境,并执行 bash

我使用 Konrad 的命令 运行 容器:

docker run -itd --rm --name entrypoint entrypoint-test:latest
24a7f3d740c37bb345374a835a465482e3bf49a04361e55205b6d63af48d5c3d

这导致容器被启动。 Entrypoint.sh 将为我们 运行 bash,但它处于守护进程模式,因此我们必须附加到它:

$ docker attach 24a7f3d740c37bb345374a835a465482e3bf49a04361e55205b6d63af48d5c3d
bash-5.0# echo $DD_AGENT_HOST 
127.0.0.1

或者,您可以只 运行 docker 图像而不使用 -d 选项,避免守护进程模式:

$ docker run -it --rm --name entrypoint  entrypoint-test:latest
bash-5.0# echo $DD_AGENT_HOST 
127.0.0.1
bash-5.0# echo Hit Ctrl-P Ctrl-Q to leave this container running

综上所述,这对您的 dotnet 调用有效吗?

ENTRYPOINT [ "/entrypoint.sh", "dotnet" , "testdatadog.dll" ]