为什么 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 相同。
我在 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 相同。