为什么 Docker CMD 运行 在 GKE 中是 chronos?

Why is Docker CMD running as chronos in GKE?

我在 GKE 上有一个 pod 和 NodePort 服务 运行ning。

在我 pod 中容器的 Dockerfile 中,我使用 gosu 到 运行 作为特定用户的命令:

startup.sh

exec /usr/local/bin/gosu mytestuser "$@"

Docker 文件

FROM ${DOCKER_HUB_PUBLIC}/opensuse/leap:latest

# Download and verify gosu
RUN gpg --batch --keyserver-options http-proxy=${env.HTTP_PROXY} --keyserver hkps://keys.openpgp.org \
      --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \
    curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.12/gosu-amd64" && \
    curl -o /usr/local/bin/gosu.asc -SL "https://github.com/tianon/gosu/releases/download/1.12/gosu-amd64.asc" && \
    gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \
    chmod +x /usr/local/bin/gosu

# Add tini
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--", "/startup/startup.sh"]

# Add mytestuser
RUN useradd mytestuser

# Run startup.sh which will use gosu to execute following `CMD` as `mytestuser`
RUN /startup/startup.sh
CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/helloworld.jar"]

我刚刚注意到,当我登录到 GKE 上的容器并查看进程 运行ning 时,我期望的 java 进程是 运行ning因为 mytestuser 实际上是 运行ning 作为 chronos:

me@gke-cluster-1-default-ool-1234 ~ $ ps aux | grep java
root        9551  0.0  0.0   4296   780 ?        Ss   09:43   0:00 /tini -- /startup/startup.sh java -Djava.security.egd=file:/dev/./urandom -jar /helloworld.jar
chronos     9566  0.6  3.5 3308988 144636 ?      Sl   09:43   0:12 java -Djava.security.egd=file:/dev/./urandom -jar /helloworld.jar

任何人都可以解释发生了什么,即谁是 chronos 用户,以及为什么我的进程不像 mytestuser 那样 运行ning?

当您 RUN adduser 时,它会在 图像的 /etc/passwd 文件中分配一个用户 ID。您的脚本使用该数字用户 ID 启动进程。但是,当您随后从主机 运行 ps 时,它会在 主机的 /etc/passwd 文件中查找该用户 ID,并得到一些不同的东西。

这种差异通常无关紧要。如果您要从主机绑定挂载目录,则只有数字用户 ID 对文件系统权限等事项很重要。出于安全目的,重要的是数字用户 ID 不为 0,但它被普遍命名为 root.

当您 运行 在容器内添加用户(或作为映像构建的一部分)时,它会向容器内的 /etc/passwd 添加条目 . uid/gid 将与主机共享命名空间,除非您启用用户命名空间。但是,这些 ID 到名称的映射将特定于进程所在的文件系统命名空间 运行ning。因此在这种情况下,容器内的 mytestuser 的 uid 恰好与主机上的 chronos 的 uid 相同。