Distroless image 使用经验
最近开始使用 GoogleContainerTools 的 distroless image, 但是遇到了一些问题, 这里记录一下.
distoless image 是啥?
https://github.com/GoogleContainerTools/distroless
GoogleContainer Distroless镜像是一种用于容器化应用程序的轻量级基础镜像,它旨在最小化容器的攻击面和大小。它由Google开发并维护,专为在Kubernetes等容器编排平台上部署的应用程序而设计。
Distroless镜像的一些优点包括:
- 最小化攻击面:Distroless镜像只包含应用程序运行所需的最小运行时组件和依赖项,因此减少了潜在的安全风险。它不包含操作系统工具或其他不必要的软件包,使得容器更加安全。
- 减小镜像大小:由于Distroless镜像只包含应用程序运行所需的最小组件,因此它们的大小相比包含完整操作系统的基础镜像更小。这可以减少容器的下载时间和存储空间。
- 简化部署和维护:Distroless镜像提供了一个简化的部署流程,因为它们不需要管理操作系统的配置或更新。这使得容器化应用程序的部署和维护更加简单和高效。
- 与容器编排平台集成:Distroless镜像与Kubernetes等容器编排平台无缝集成,可以轻松地部署和管理大规模的容器化应用程序。
总的来说,Distroless镜像提供了一种安全、高效和简化的方式来容器化应用程序,使开发人员能够更专注于应用程序的开发和部署,而无需担心底层基础设施的细节。
注意: 它默认连shell 都没有, 只有后缀加上 :debug
才有 busybox 的shell. 也没有包管理器, 所以不能安装任何东西.
Dockerfile RUN, CMD, and ENTRYPOINT 指令的 shell 和 exec 形式
https://docs.docker.com/reference/dockerfile/#shell-and-exec-form
RUN, CMD, and ENTRYPOINT 有2种形式: shell 和 exec 形式.
shell 形式: 用字符串形式, 会被shell解释, 例如: RUN echo $HOME
exec 形式: 用数组形式, 不会被shell解释, 例如: RUN ["echo", "$HOME"]
Shell形式依赖于容器内的shell解释器,会增加一定的额外开销,因为每个命令都需要被shell解释器处理。
Exec形式直接将命令传递给Docker守护进程,避免了额外的shell解释器,因此更加高效。
遇到的问题
- 由于distroless没有shell, 所以不能用shell形式, 只能用exec形式. 若要使用shell, 要么使用
:debug
版本, 要么自己 copy busybox 到镜像里. - 由于 python 命令和 pip 命令要使用
PYTHONPATH
环境变量, 所以要用shell形式, 但是distroless没有shell, 所以只能用exec形式, 所以只能用python -m
和pip install
的形式. 但是这样找不到安装的模块, 要么使用 busybox shell, 要么在 python 代码一开始使用 sys.path 设置需要依赖的文件. - python 版本差异. 由于不能安装东西, 所以只能通过build 环境container安装, 比如安装的东西和最后使用的 distroless image 里面的系统是不是兼容, 要考虑.