docker使用进阶与实用技巧
1.runlike工具
在维护一些非Compose管理的遗留容器时,手动还原复杂的启动参数往往费时费力。通常情况对于复杂的容器服务,还原启动参数时,需要通过inspect子命令导出并分析JSON配置文件,才能逆向推导出原始的创建命令。runlike工具简化相关过程,直接使用runlike+容器名可以方便的导出容器构建命令。
pip install runlike
runlike posteio
docker run --name=posteio --hostname=mail.diyao.me --volume /data --env=TZ=Asia/Shanghai --env=DISABLE_CLAMAV=TRUE --network=host --restart=always --runtime=runc --detach=true analogic/poste.io
2.下一代构建引擎buildkit
BuildKit是Docker的下一代镜像构建引擎,用于替代传统docker build所依赖的legacy builder。作为构建后端,它通过buildx插件进行调用与配置,提供现代化的镜像构建能力,包括多平台构建、分布式执行以及安全可复现机制,从而满足容器构建在可追溯、可验证和可审计方面的需求。
sudo apt-get install docker-buildx-plugin
多平台方面,buildx支持构建以下类型镜像:
linux/arm64
linux/amd64
linux/amd64/v2
linux/riscv64
linux/ppc64le
linux/s390x
linux/386
linux/mips64le
linux/mips64
linux/arm/v7
linux/arm/v6
2.1简单案例
使用buildx构建docker镜像,构建工作都在moby/buildkit镜像实例中进行,在容器中执行构建任务,包括拉取基础镜像、执行指令(如 RUN、COPY)、构建缓存、输出镜像等
# 创建buildx构建实例
# buildx-create命令的bootstrap参数,立即运行buildx实例,否则在构建时惰性运行实例
# buildx-create命令的driver参数,可以生产不同引擎的buildx实例
# 在后续的构建流程中,使用test实例
docker buildx create --name test --bootstrap
docker buildx use test
docker buildx build --sbom=true --provenance=true --output=type=local,dest=build --platform=linux/amd64 -f Dockerfile .
# 多节点分布式构建
docker buildx create --name test --node test0 --driver docker-container ssh://root@192.168.5.46
docker buildx create --name test --node test1 --append --driver docker-container ssh://root@192.168.5.47
buildx支持多种构建引擎,下表列出引擎的相应使用场景
| 引擎 | 说明 |
|---|---|
| docker | 使用本地docker守护进程(默认,功能受限) |
| docker-container | 使用moby/buildkit容器,更完整的buildKit支持 |
| kubernetes | 在k8s中运行构建节点 |
| remote | 使用远程buildKit节点 |
2.2注意事项
使用buildx构建多平台镜像时,出现基础镜像拉取不下来,即使是修改docker的配置文件,修改docker源为国内源,还是会出现这个问题。 因为buildx的原理是先创建一个buildx的多平台镜像,在这个多平台镜像中构建所需的镜像,所以配置文件无法继承主机的docker配置。
针对此问题可以使用以下几种方式规避:
- 配置驱动参数,使用代理访问docker镜像仓库
export PROXY=http://192.168.5.9:2080
export NOPROXY=127.0.0.1,localhost,/run/buildkit/buildkitd.sock
docker buildx create --name test --driver-opt env.http_proxy=${PROXY} --driver-opt env.https_proxy=${PROXY} --driver-opt '"env.no_proxy='${NOPROXY}'"'
docker buildx use test
docker buildx build .
- 配置remote驱动,使用远程实例
# 远程主机运行buildkit实例,本地主机使用remote引擎连接实例
docker run -d -v 1234:1234 --name buildkitd --privileged moby/buildkit:latest --addr tcp://0.0.0.0:1235
export BUILDKIT_NO_CLIENT_TOKEN=1
docker buildx create --name test --driver remote tcp://103.79.76.198:1235 --use
docker buildx build .
- 使用docker-container的ssh方式
export BUILDKIT_NO_CLIENT_TOKEN=1
docker buildx create --name test --driver docker-container ssh://root@103.79.76.198 --use
docker buildx build .
2.3安全构建
buildkit除了实现基础构建的功能,还引入了对软件供应链安全的原生支持。
SBOM软件物料清单
通过在构建命令中使能sbom参数,BuildKit会在镜像中嵌入一份详细的软件物料清单。该清单记录了构建过程中安装的软件包信息、引入文件的来源、版本及哈希Hash值。这些元数据不仅能辅助进行镜像内容的依赖合规检查,还能为已知漏洞CVE的扫描与分析提供核心数据支持。
构建溯源
通过启用–provenance参数,BuildKit会生成一份详尽的构建溯源信息。该元数据记录了构建工具版本、源代码输入、构建参数、构建者身份、时间戳以及输入文件的摘要Digest。这些关键信息为镜像提供了完整的可追溯性,能够辅助安全团队验证镜像是否来自可信源、是否在传输中被篡改,并确保构建过程在不同环境下具备可重现性。
审计与分析
Syft工具可读入镜像文件,导出多种格式的SBOM信息,配套Grype开源工具读取SBOM文件进行漏洞分析,并与全球漏洞数据库比对,精准识别镜像中的已知漏洞CVE。
syft ubuntu:latest
分发可信验证
为了确保镜像在传输过程中未被篡改,开发者可以利用Cosign对构建后的镜像进行数字签名或验证。此外,Docker也内置了简单易用的Docker Content Trust(DCT)机制:通过设置export DOCKER_CONTENT_TRUST=1,在执行docker push时即可自动完成镜像签名。
cosign generate-key-pair
docker inspect --format '{{index .RepoDigests 0}}' ubuntu:latest
cosign sign --key ./cosign.key ubuntu@sha256:1e622c5f073b4f6bfad6632f2616c7f59ef256e96fe78bf6a595d1dc4376ac02
3.docker容器的异构运行
Docker本身并不直接模拟异构指令集,而是通过集成QEMU用户态模拟器(结合内核的binfmt_misc机制)和多平台镜像(Multi-arch Images)支持来实现跨架构运行。QEMU负责将目标CPU指令如ARM动态翻译为宿主机指令如x86_64,而多平台镜像则确保容器能够拉取到匹配目标架构的指令集分层。
sudo apt-get install qemu binfmt-support qemu-user-static
docker pull --platform linux/arm64 arm64v8/ubuntu
docker run --rm -it --platform linux/arm64 arm64v8/ubuntu:latest uname -m
4.Whaler导出镜像Dockerfile
Whaler(捕鲸船)是一个用Go编写的镜像逆向工具,其旨在逆向Docker镜像,恢复创建该镜像的Dockerfile文件,并自动扫描镜像层中的文件名以识别潜在的敏感泄露。此外,它还具备直观地展示镜像的端口配置、运行用户及环境变量等核心元数据的功能。
whaler -v -sV=1.36 klakegg/hugo:latest
Analyzing klakegg/hugo:latest
Docker Version:
GraphDriver: overlay2
Environment Variables
|PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|HUGO_VERSION=0.111.3
|HUGO_BIND=0.0.0.0
|HUGO_DESTINATION=public
|HUGO_ENV=DEV
|HUGO_EDITION=standard
|HOME=/tmp
Open Ports
|1313
Image user
|User is root
Potential secrets:
unable to parse history from json file