一文带你认识Kubernetes中的非根容器:non-root containers

前言

k8s本身并不负责容器的定义与实现,Kubernetes 通过使用容器运行时接口来实现容器的管理,而容器的实现通过容器运行时(如 Docker、CRI-O 等)来实现。

非根容器和默认容器的区别

容器内部默认是以root用户来执行指令的,这意味着应用程序在它所在的容器内部都拥有最高的执行权限,程序都可以修改容器内部的系统文件,访问机密信息,可以在运行时安装系统包,还可以绑定1024以下的任意端口。

而非根容器的出现就是为了阻止这些不安全行为。非根容器启动之后是无法再转变成根容器的,应用程序只能以特定的用户角色运行,可以防止恶意代码获取最高运行权限。

非根容器的优/缺点

优点:1. 安全 ,某些k8s发行版如Openshift要求必须使用非根容器。

缺点:应用程序可能会因为权限不足,无法访问或创建某些文件、目录。例如mysql,git等应用。

如何解决非根容器的局限性

假如应用程序必须使用root权限做一些事情,但是又希望使用非根容器运行,那么可以考虑以下几种方案:

  1. 使用initContainers。initContainers是一种特殊的容器,它可以在Pod的其他容器启动之前运行,用于初始化容器所需的环境。
  2.  修改Dockerfile,在Dockerfile中以root用户完成要做的事情之后,再切换回指定用户。
  3.  在Dockerfile中修改运行时需要访问的文件权限(不推荐)
  4.  在使用挂载卷时,修改UID等参数将挂载卷的所有者设置为非根容器使用的用户或组。这样非根容器才可以以自己的用户身份来访问挂载卷。

如何创建非根容器

非根容器的创建需要分为两部分:

Dockerfile

在Dockerfile中可以通过命令 USER 将默认root用户切换为指定用户。

如下所示,USER 1001之后的命令将以UID为1001的用户权限来执行,如果该用户不存在,docker会尝试使用该UID创建一个用户。

需要注意的是红帽公司推出的Pass平台 Openshift 会忽略掉dockerfile中指定的user,而是使用一个随机的UID,这也意味着在Openshift 上所有容器都是默认以非根方式运行的。

FROM bitnami/minideb-extras:jessie-r22
LABEL maintainer "Bitnami "

ENV BITNAMI_PKG_CHMOD="-R g+rwX"
...
RUN bitnami-pkg unpack nginx-1.12.2-0 --checksum cb54ea083954cddbd3d9a93eeae0b81247176235c966a7b5e70abc3c944d4339
...
USER 1001
ENTRYPOINT ["/app-entrypoint.sh"]
CMD ["nginx","-g","daemon off;"]

Kubernetes

在Kubernetes中,创建非根容器需要在Pod的容器定义中设置securityContext。即通过设置runAsUser和runAsGroup字段来指定容器中进程的用户和组,以此创建非根容器。

同时,还需要在Dockerfile中使用USER指令将文件和目录的权限设置为非root用户和组,否则可能会在以非root用户身份运行容器时出现权限问题。

apiVersion: v1
kind: Pod
metadata:
  name: non-root-container-pod
spec:
  containers:
  - name: non-root-container
    image: my-non-root-image
    securityContext:
      runAsUser: 1000 # 指定非root用户
      runAsGroup: 3000 # 指定非root组

参考

Why non-root containers are important for security (bitnami.com)

ChatGPT

你可能感兴趣的:(Kubernetes,kubernetes,非根容器,docker)