强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 11 章:Docker 中使用

第 11 章:Docker 中使用

11.1 为什么在 Docker 中使用 BusyBox

11.1.1 容器镜像体积对比

基础镜像大小包含内容
busybox~1.2MBBusyBox 静态二进制 + Applet
alpine~5.6MBBusyBox + apk 包管理器 + musl
debian:slim~74MBDebian 最小系统
ubuntu~77MBUbuntu 基础系统
centos~237MBCentOS 基础系统
# 拉取并查看镜像大小
$ docker images
REPOSITORY   TAG          SIZE
busybox      latest       1.24MB
alpine       3.19         5.61MB
debian       slim         74.1MB
ubuntu       22.04        77.8MB

11.1.2 适用场景

场景推荐镜像原因
单一静态二进制busybox最小,只需 scratch
需要包管理器alpine兼顾体积和灵活性
Python/Node 应用alpine生态支持好
生产服务器debian:slim稳定性和兼容性
开发调试ubuntu工具齐全

11.2 使用 scratch 构建镜像

11.2.1 最小 BusyBox 镜像

# Dockerfile - 基于 scratch 的最小镜像
FROM scratch

# 复制静态编译的 BusyBox
COPY busybox /busybox

# 创建基本目录
RUN ["/busybox", "mkdir", "-p", "/bin", "/sbin", "/usr/bin", "/usr/sbin", \
     "/tmp", "/proc", "/sys", "/dev", "/etc", "/var", "/root"]

# 创建符号链接
RUN ["/busybox", "--install", "-s"]

# 设置默认 Shell
CMD ["/bin/sh"]
# 编译静态 BusyBox
$ make defconfig
$ sed -i 's/# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config
$ make -j$(nproc)

# 构建镜像
$ docker build -t my-busybox .

# 查看大小
$ docker images my-busybox
REPOSITORY   TAG       SIZE
my-busybox   latest    1.24MB

# 运行
$ docker run -it my-busybox
/ # ls
bin      dev      etc      proc     root     sbin     sys      tmp      usr      var
/ # echo "Hello from BusyBox container!"
Hello from BusyBox container!

11.2.2 多阶段构建

# Dockerfile - 多阶段构建(从源码编译 BusyBox)
# 阶段一:编译
FROM ubuntu:22.04 AS builder

RUN apt-get update && \
    apt-get install -y build-essential gcc make wget bzip2 && \
    rm -rf /var/lib/apt/lists/*

ARG BUSYBOX_VERSION=1.36.1

RUN wget https://busybox.net/downloads/busybox-${BUSYBOX_VERSION}.tar.bz2 && \
    tar xjf busybox-${BUSYBOX_VERSION}.tar.bz2 && \
    cd busybox-${BUSYBOX_VERSION} && \
    make defconfig && \
    sed -i 's/# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config && \
    make -j$(nproc) && \
    make CONFIG_PREFIX=/output install

# 阶段二:运行时
FROM scratch

COPY --from=builder /output /

CMD ["/bin/sh"]

11.3 BusyBox 镜像进阶

11.3.1 包含应用的镜像

# Dockerfile - 运行 Go 应用的最小镜像
FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /myapp .

# 运行时镜像
FROM busybox

COPY --from=builder /myapp /usr/local/bin/myapp

# 使用 mdev 设备管理
RUN mkdir -p /etc/init.d && \
    echo '#!/bin/sh' > /etc/init.d/rcS && \
    chmod +x /etc/init.d/rcS

EXPOSE 8080
USER nobody
CMD ["/usr/local/bin/myapp"]

11.3.2 包含 CA 证书的镜像

FROM scratch

# 从 builder 阶段复制 CA 证书
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY busybox /busybox
RUN ["/busybox", "--install", "-s"]

# 现在可以使用 HTTPS
RUN ["/bin/wget", "https://example.com"]

11.3.3 带配置文件的镜像

FROM busybox

# 复制应用和配置
COPY myapp /usr/local/bin/
COPY config.yml /etc/myapp/
COPY entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh /usr/local/bin/myapp

EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"]
CMD ["--config", "/etc/myapp/config.yml"]

11.4 Alpine Linux 对比

11.4.1 Alpine 简介

Alpine Linux 是一个基于 musl libc 和 BusyBox 的安全导向轻量级 Linux 发行版。

Alpine Linux = musl libc + BusyBox + apk 包管理器 + OpenRC init

11.4.2 详细对比

特性busyboxalpine
大小~1.2MB~5.6MB
包管理器apk
libc无(静态编译)musl
Shellashash
包数量14000+
init 系统BusyBox initOpenRC
适用场景单一二进制完整运行环境
安全更新定期更新

11.4.3 Alpine 使用

# Alpine 基础镜像
FROM alpine:3.19

# 安装软件包
RUN apk add --no-cache \
    curl \
    wget \
    bash \
    python3 \
    nodejs

# 使用 apk 搜索包
# docker run -it alpine:3.19
/ # apk search python3
python3-3.11.6-r0
python3-dev-3.11.6-r0
...

11.4.4 选择建议

# 仅需要单一静态二进制 → busybox
FROM busybox
COPY myapp /myapp
CMD ["/myapp"]

# 需要运行时环境 → alpine
FROM alpine
RUN apk add --no-cache python3 py3-pip
COPY app.py /app.py
CMD ["python3", "/app.py"]

# 需要完整生态 → debian
FROM debian:slim
RUN apt-get update && apt-get install -y python3 python3-pip

11.5 Dockerfile 最佳实践

11.5.1 减小镜像体积

# 1. 使用多阶段构建
FROM golang:1.21 AS builder
RUN go build -ldflags="-s -w" -o /app .

FROM busybox
COPY --from=builder /app /app

# 2. 合并 RUN 指令
RUN mkdir -p /app && \
    cp file1 /app/ && \
    cp file2 /app/ && \
    rm -rf /tmp/*

# 3. 使用 .dockerignore
# .dockerignore
.git
*.md
test/
vendor/

# 4. 清理包管理器缓存
RUN apk add --no-cache package  # Alpine
RUN apt-get clean && rm -rf /var/lib/apt/lists/*  # Debian

11.5.2 安全加固

FROM busybox

# 不以 root 运行
RUN adduser -D -u 1000 appuser
USER appuser

# 只读文件系统(运行时)
# docker run --read-only ...

# 限制资源
# docker run --memory=100m --cpus=0.5 ...

# 丢弃能力
# docker run --cap-drop=ALL ...

11.6 嵌入式容器方案

11.6.1 Docker on Embedded Linux

# 在 ARM 设备上运行 Docker
# 1. 安装 Docker
$ curl -fsSL https://get.docker.com | sh

# 2. 拉取 ARM 镜像
$ docker pull busybox:latest  # 自动选择架构

# 3. 运行
$ docker run -it busybox

11.6.2 容器化嵌入式应用

# Dockerfile.arm32v7
FROM arm32v7/busybox:latest

COPY qemu-arm-static /usr/bin/
COPY myapp /usr/local/bin/

CMD ["/usr/local/bin/myapp"]
# 交叉构建镜像
$ docker buildx build --platform linux/arm/v7 -t myapp:arm32 .

11.6.3 Kubernetes 与 BusyBox

# debug-pod.yaml - 调试 Pod
apiVersion: v1
kind: Pod
metadata:
  name: debug
spec:
  containers:
  - name: debug
    image: busybox
    command: ['sleep', '3600']
    resources:
      limits:
        memory: "64Mi"
        cpu: "100m"
  restartPolicy: Never
# 创建调试 Pod
$ kubectl apply -f debug-pod.yaml

# 进入调试容器
$ kubectl exec -it debug -- /bin/sh

# 网络诊断
$ kubectl exec debug -- nslookup kubernetes.default
$ kubectl exec debug -- wget -qO- http://service:8080/health

11.7 实用 Docker 命令

# 交互式运行
$ docker run -it busybox /bin/sh

# 后台运行
$ docker run -d --name myapp busybox sleep 3600

# 进入运行中的容器
$ docker exec -it myapp /bin/sh

# 查看容器日志
$ docker logs myapp

# 复制文件
$ docker cp myapp:/etc/hosts ./hosts

# 容器导出为 tar
$ docker export myapp > myapp.tar

# 从 tar 导入镜像
$ docker import myapp.tar myapp:latest

# 查看容器资源使用
$ docker stats myapp

11.8 本章小结

概念说明
scratch空白基础镜像,适合静态二进制
busybox~1.2MB,最小容器基础
alpine~5.6MB,带包管理器
多阶段构建编译和运行分离,减小镜像体积
安全非 root 运行、只读文件系统、能力限制

扩展阅读


上一章: 第 10 章 — Buildroot 集成
下一章: 第 12 章 — 最佳实践