docker基本概念


虚拟机:宿主机 → Hypervisor(虚拟化层) → 每个 VM 都有完整独立 OS
是完整的虚拟电脑,有独立的 CPU、内存、硬盘、操作系统。占用资源多,一个宿主机只能启动少量的虚拟机。

容器:是进程级隔离,共享宿主机内核,只打包应用 + 依赖。占用资源小,所以一个宿主机可以启动很多容器。

Docker是一个用于 构建 运行 传送 应用程序的平台
build run share

Docker是容器的一种实现

镜像是一个模版,容器就是这个模版的实例

docker镜像的内容

Docker 容器的底层规则是:所有容器共享宿主机的 Linux 内核,镜像只提供用户空间。

你这个理解很直观,但其实Docker镜像的实际占用空间常常远超出“仅模板”的预期,核心原因是镜像的“模板”特性和它的存储方式、层级结构密切相关,并非简单的“轻量文本模板”。

一、为什么Docker镜像不一定“小”?

Docker镜像本质是分层的只读文件系统模板,而非单纯的“配置模板”——它包含了运行应用所需的所有依赖、库、系统文件甚至完整的操作系统文件,这才是占用空间的核心:

1. 镜像的分层存储(核心原因)

  • Docker镜像由多个只读层叠加而成,比如:
    • 第一层:基础系统层(如Ubuntu 22.04,约70MB)
    • 第二层:安装Python(约100MB)
    • 第三层:安装项目依赖(如Pandas、Numpy,约50MB)
    • 第四层:添加应用代码(几KB)
  • 最终镜像的大小是所有层的总和(上面例子约220MB),而非仅“代码模板”的几KB。

2. 基础镜像本身就不小

  • 常见基础镜像的默认大小:
    • Ubuntu 22.04:~70MB
    • CentOS 7:~200MB
    • Python 3.11(基于Ubuntu):~900MB
    • 带完整JDK的Java镜像:~1GB+
  • 这些基础镜像包含了操作系统的核心文件,是镜像体积的主要来源。

3. 构建过程中的“冗余层”

如果Dockerfile写得不好,会产生大量冗余层:

# 不好的写法:每一步都新增层,且包含临时文件
FROM ubuntu
RUN apt-get update
RUN apt-get install -y gcc
RUN wget https://xxx.com/tmp.tar.gz
RUN tar -xf tmp.tar.gz
RUN rm tmp.tar.gz

上面的镜像会包含tmp.tar.gz的层(即使最后删除),导致体积变大。

二、如何让Docker镜像“真的变小”?

1. 使用轻量级基础镜像

  • Alpine Linux:专为容器设计,基础镜像仅5MB左右,是主流选择:
    FROM python:3.11-alpine  # Python+Alpine,仅~50MB
    FROM openjdk:17-alpine   # Java+Alpine,仅~200MB
    

2. 合并层 + 清理冗余文件

将多个RUN命令合并,并在同一层清理临时文件:

# 优化写法:合并层,避免冗余
FROM ubuntu
RUN apt-get update && \
    apt-get install -y gcc && \
    wget https://xxx.com/tmp.tar.gz && \
    tar -xf tmp.tar.gz && \
    rm tmp.tar.gz && \
    apt-get clean && \  # 清理apt缓存
    rm -rf /var/lib/apt/lists/*  # 删除无用文件

3. 多阶段构建(核心技巧)

只保留运行时需要的文件,丢弃构建过程中的工具/依赖:

# 阶段1:构建(大体积,包含编译器、源码)
FROM golang:1.21 as builder
WORKDIR /app
COPY . .
RUN go build -o myapp  # 编译出可执行文件

# 阶段2:运行(仅保留可执行文件,体积极小)
FROM alpine:3.19
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["myapp"]

上面的最终镜像仅包含Alpine系统+可执行文件,体积通常只有几MB到几十MB。

4. 清理无用依赖

  • 只安装运行时依赖(--no-install-recommends):
    RUN apt-get install -y --no-install-recommends python3-pip
    
  • 安装完成后删除编译工具、源码等临时文件。

三、查看镜像体积的实用命令

# 查看本地镜像大小
docker images

# 查看镜像的分层详情(找到体积大的层)
docker inspect <镜像ID>

# 清理未使用的镜像/容器/缓存(释放空间)
docker system prune -a

总结

  1. Docker镜像的“模板”是包含完整运行环境的文件系统模板,而非纯文本配置,因此基础镜像和依赖是体积的核心来源;
  2. 镜像体积大的主要原因是基础镜像臃肿、分层冗余、包含构建工具/临时文件;
  3. 优化核心思路:用轻量基础镜像 + 合并层清理冗余 + 多阶段构建剥离构建环境。

简单来说:镜像的“模板”特性决定了它是“运行环境的模板”,而非“代码的模板”,做好分层和清理才能让它真正轻量化。

posted @ 2026-02-25 22:27  向着朝阳  阅读(0)  评论(0)    收藏  举报