从构建镜像的角度下手
将非root用户添加到Dockerfile
# RUN命令执行创建用户和用户组(命令创建了一个用户newuser设定ID为5000,并指定了用户登录后使用的主目录和shell)
RUN groupadd --gid 5000 newuser \
&& useradd --home-dir /home/newuser --create-home --uid 5000 --gid 5000 --shell /bin/sh --skel /dev/null newuser
# 指定用户,从这一行往下开始的每个命令都是以newuser身份而不是root身份运行(比如后面的CMD、EntryPoint)
USER newuser
在实际项目应用中,并不是所有要运行的镜像都是我们自己构建的。我们还使用了许多第三方镜像,这种情况我们无法像上面那样直接设定用户。
这些第三方Docker镜像默认情况下一般都是以root用户身份运行,除非我们对其进行处理。
如果是你用K8S,则Kubernetes中Pod安全上下文和Pod安全策略,可以帮助我们以非root身份运行镜像。
二、从K8S启动容器的角度下手
可以使用Pod安全上下文,将Pod的执行限制为特定的非root用户。
通过Pod构建文件中添加securityContext来配置Pod的安全设置。
如下示例:
apiVersion: v1 kind: Pod metadata: name: pod-helloworld spec: securityContext: runAsNonRoot: true runAsUser: 5000 runAsGroup: 5000 fsGroup: 5000
runAsUser指定Pod内的任何容器仅以userID为5000的运行,runAsGroup指定的容器内所有进程的组ID(组ID不指定默认为0)。
你可以先进入容器,然后使用 ps 命令查看进程的用户。
关于Pod的更多安全策略可以详见 http://docs.kubernetes.org.cn/690.html#FSGroup
查看容器当前用户的命令可以使用 whoami 或者 ps -aux
之所以出现这个问题,有两个原因:一是docker容器本质是宿主机服务器上的一个进程,不做特殊处理的情况下,容器里的root用户和宿主机上的root用户实际上是同一个用户;二是docker存在一个守护进程,即使用systemctl start docker启动的那个服务进程。因为我们安装docker是root用户安装的,该守护进程也是用root用户启动的,即使容器是非root用户运行的也存在较大的安全问题,是docker安全性问题的重要风险点。
解决这个问题有两个通用方法:就是容器用户与宿主机用户的id段映射;二是使用非root用户搭建docker并启动守护进程。
FROM ubuntu:18.04 COPY . /myappRUN make /myapp... USER newuse CMD python /myapp/hello.py