原文地址: https://qiita.com/tomoyamachi/items/2397457f5d516a1fbc85
简要
看过Best practices for writing Dockerfiles之后感觉自己写出的Dockerfile已经完美了吗?
别着急,
只需3分钟,用我做的工具检查一下你的Dockerfile。
这不像Hadolint那样只会检测Dockerfilede语法错误,而是把Dockerfile展开(build)之后仔细检查Imagede内部。
还可以检测普通的Linter工具不可能检测到的BaseImage
Dockle底层使用跟Trivy,Vuls相同的工具,想知道更详细的工作原理请看这篇文章(未翻译)
https://qiita.com/tomoyamachi/items/8e042e4269427bb3b326
使用方法
Homebrew (Mac / Linux)
$ export DOCKER_CONTENT_TRUST=1
$ docker build -t test-image:v1 .
$ brew install goodwithtech/dockle/dockle
$ dockle test-image:v1
Linux
$ export DOCKER_CONTENT_TRUST=1
$ docker build -t test-image:v1 .
$ VERSION=$(
curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
grep '"tag_name":' | \
sed -E 's/.*"v([^"]+)".*/\1/' \
) && curl -L -o dockle.tar.gz https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz
$ tar zxvf dockle.tar.gz
$ ./dockle test-image:v1
Windows
$ export DOCKER_CONTENT_TRUST=1
$ docker build -t test-image:v1 .
$ VERSION=$(
curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
grep '"tag_name":' | \
sed -E 's/.*"v([^"]+)".*/\1/' \
) && curl -L -o dockle.zip https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Windows-64bit.zip
$ unzip dockle.zip && rm dockle.zip
$ ./dockle.exe test-image:v1
Docker
$ VERSION=$(
curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
grep '"tag_name":' | \
sed -E 's/.*"v([^"]+)".*/\1/' \
) && docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
goodwithtech/dockle:v${VERSION} test-image:v1
指定Remote的Image时 `/var/run/docker.sock`,不需要`-v`。
# 执行结果
```yaml
PASS - CIS-DI-0001: Create a user for the container
PASS - CIS-DI-0005: Enable Content trust for Docker
PASS - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
PASS - CIS-DI-0007: Do not use update instructions alone in the Dockerfile
PASS - CIS-DI-0008: Remove setuid and setgid permissions in the images
PASS - CIS-DI-0009: Use COPY instead of ADD in Dockerfile
PASS - CIS-DI-0010: Do not store secrets in ENVIRONMENT variables
PASS - CIS-DI-0010: Do not store secret files
PASS - DKL-DI-0001: Avoid sudo command
PASS - DKL-DI-0002: Avoid sensitive directory mounting
PASS - DKL-DI-0003: Avoid apt-get/apk/dist-upgrade
PASS - DKL-DI-0004: Use apk add with --no-cache
PASS - DKL-DI-0005: Clear apt-get caches
PASS - DKL-DI-0006: Avoid latest tag
PASS - DKL-LI-0001: Avoid empty password
PASS - DKL-LI-0002: Be unique UID
PASS - DKL-LI-0002: Be unique GROUP
这里检测的项目包括CIS Benchmarks和Best practices for writing Dockerfiles。
检测出未通过的项目时,会给出如下的一些提示。
WARN - CIS-DI-0001: Create a user for the container
* Last user should not be root
PASS - CIS-DI-0005: Enable Content trust for Docker
WARN - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
* not found HEALTHCHECK statement
PASS - CIS-DI-0007: Do not use update instructions alone in the Dockerfile
INFO - CIS-DI-0008: Remove setuid and setgid permissions in the images
* Found setuid file: usr/lib/openssh/ssh-keysign urwxr-xr-x
FATAL - CIS-DI-0009: Use COPY instead of ADD in Dockerfile
* Use COPY : /bin/sh -c #(nop) ADD file:81c0a803075715d1a6b4f75a29f8a01b21cc170cfc1bff6702317d1be2fe71a3 in /app/credentials.json
FATAL - CIS-DI-0010: Do not store secrets in ENVIRONMENT variables
* Suspicious ENV key found : MYSQL_PASSWD
FATAL - CIS-DI-0010: Do not store secret files
* Suspicious filename found : app/credentials.json
PASS - DKL-DI-0001: Avoid sudo command
FATAL - DKL-DI-0002: Avoid sensitive directory mounting
* Avoid mounting sensitive dirs : /usr
PASS - DKL-DI-0003: Avoid apt-get/apk/dist-upgrade
PASS - DKL-DI-0004: Use apk add with --no-cache
FATAL - DKL-DI-0005: Clear apt-get caches
* Use 'rm -rf /var/lib/apt/lists' after 'apt-get install' : /bin/sh -c apt-get update && apt-get install -y git
PASS - DKL-DI-0006: Avoid latest tag
FATAL - DKL-LI-0001: Avoid empty password
* No password user found! username : nopasswd
PASS - DKL-LI-0002: Be unique UID
PASS - DKL-LI-0002: Be unique GROUP
如果不明白可以去README搜索以下CIS-DI-0001
可能会找到一些提示。
所有检测项目都通过的话时最好的,
不过有一些项目没有通过也没有问题。
这只是一种评价指标。
举个栗子,Best practices中写道不要使用root用户,
然而有些时候不得不使用root用户。
这个工具是想给我们提供一个去思考异于Best practices设计的Dockerfiles是否是我们所期望的契机。
使用-ignore, -i
可以无视检测项
$ dockle -i CIS-DI-0001 -i CIS-DI-0006 [IMAGE_NAME]
或者写.dockleignore
文件无视一些规则。
# root执行
CIS-DI-0001
# 不使用HEALTHCHECK
CIS-DI-0006
# 使用latest tag
DKL-DI-0006
应用了上面的.dockleignore
文件后的运行结果如下。
IGNORE - CIS-DI-0001: Create a user for the container
INFO - CIS-DI-0005: Enable Content trust for Docker
* export DOCKER_CONTENT_TRUST=1 before docker pull/build
IGNORE - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
PASS - CIS-DI-0007: Do not use update instructions alone in the Dockerfile
INFO - CIS-DI-0008: Remove setuid and setgid permissions in the images
* Found setuid file: usr/lib/openssh/ssh-keysign urwxr-xr-x
IGNORE - CIS-DI-0009: Use COPY instead of ADD in Dockerfile
FATAL - CIS-DI-0010: Do not store secrets in ENVIRONMENT variables
* Suspicious ENV key found : MYSQL_PASSWD
FATAL - CIS-DI-0010: Do not store secret files
* Suspicious filename found : app/credentials.json
PASS - DKL-DI-0001: Avoid sudo command
FATAL - DKL-DI-0002: Avoid sensitive directory mounting
* Avoid mounting sensitive dirs : /usr
PASS - DKL-DI-0003: Avoid apt-get/apk/dist-upgrade
PASS - DKL-DI-0004: Use apk add with --no-cache
FATAL - DKL-DI-0005: Clear apt-get caches
* Use 'rm -rf /var/lib/apt/lists' after 'apt-get install' : /bin/sh -c apt-get update && apt-get install -y git
PASS - DKL-DI-0006: Avoid latest tag
FATAL - DKL-LI-0001: Avoid empty password
* No password user found! username : nopasswd
PASS - DKL-LI-0002: Be unique UID
PASS - DKL-LI-0002: Be unique GROUP
结语
Dockle
可以分析Docker的Image。不是检测Dockerfile的语法的工具。
是检测容器内部的工具,包括容器内部的文件权限。
根同类工具相比检测的项目更多。
还支持用stdin制作的Image。
docker build -<<EOF
FROM busybox
RUN echo "hello world"
EOF