首页 > 解决方案 > 将 gosu 与 kubernetes runAsUser 安全上下文一起使用?

问题描述

我有一个ENTRYPOINT以 root 身份运行的基本容器:

基础容器 Dockerfile:

FROM docker.io/opensuse/leap:latest

# Add scripts to be executed during startup
COPY startup /startup
ADD https://example.com/install-ca-cert.sh /startup/startup.d/install-ca-cert-base.sh
RUN chmod +x /startup/* /startup/startup.d/*

# 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"]

还有一个派生容器,它在启动脚本以 root 身份运行后使用gosu执行 root 步骤:

派生容器 Dockerfile:

ADD ./gosu-entrypoint.sh /usr/local/bin/gosu-entrypoint.sh
RUN chmod +x /usr/local/bin/gosu-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/gosu-entrypoint.sh"]
CMD ["whoami"]

gosu-entrypoint.sh:

#!/bin/bash

set -e

# Call original entrypoint (as root)
/tini -s /startup/startup.sh

# If GOSU_USER environment variable is set, execute the specified command as that user
if [ -n "$GOSU_USER" ]; then
    useradd --shell /bin/bash --system --user-group --create-home @GOSU_USER
    exec /usr/local/bin/gosu $GOSU_USER "$@"
else
    # else GOSU_USER environment variable is not set, execute the specified command as the default (root) user
    exec "$@"
fi

这一切都很好,通过设置GOSU_USERenv var 并运行容器,启动脚本以 root 身份执行,并且CMD执行为GOSU_USER

export GOSU_USER=jim
docker run my-derived-container
# outputs "jim"
...
unset GOSU_USER
docker run my-derived-container
# outputs root

但是,我正在尝试确定上述方法(可能已修改)是否能够与 Kubernetes securityContext runAsUserrunAsGroup指令一起使用?

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000

我认为这些指令被转换为容器的等价物docker run --user=xxx:yyy,因此它们不起作用,因为:

docker run --user $(id -u):$(id -g) my-derived-container

由于启动脚本不再以 root 身份运行,导致权限错误。

我已经看到entrypoint.sh了允许使用--user标志启动容器的脚本示例,但不确定我是否可以使用它,即即使--user提供了标志,我仍然需要启动脚本以 root 身份运行:

https://github.com/docker-library/redis/blob/master/5.0/docker-entrypoint.sh#L11

# allow the container to be started with `--user`
if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then
    find . \! -user redis -exec chown redis '{}' +
    exec gosu redis "$0" "$@"
fi

exec "$@"

更新:再次查看上面的 redis 示例,我不确定这是否允许启动容器,--user正如它所指出的那样,查看 Dockerfile,redis-server是否CMD传递给脚本($1):

https://github.com/docker-library/redis/blob/master/5.0/Dockerfile#L118

CMD ["redis-server"]

并且redis用户只是在上面硬编码docker-entrypoint.sh

标签: dockerkubernetes

解决方案


推荐阅读