Docker 详解:容器化技术的核心概念与实战入门

Docker 是什么?本文系统讲解 Docker 的核心概念:镜像、容器、Dockerfile、仓库、Volume、网络,从安装到运行第一个容器,再到理解容器化与虚拟机的本质区别。

Docker 是开源的应用容器引擎,让开发者把应用及其所有依赖打包到一个标准化的"容器"中,这个容器可以在任何安装了 Docker 的环境中一致运行——从开发者的笔记本到测试服务器,再到生产环境的云主机。Docker 解决了"在我机器上能跑"的经典问题,是现代 DevOps 和云原生应用的基础。


一、Docker 解决了什么问题

1.1 部署环境不一致的噩梦

开发者机器:Node.js 18 + Ubuntu 22.04
测试服务器:Node.js 16 + CentOS 7
生产环境:Node.js 20 + Alpine Linux
结果:同样的代码,三个环境三种表现

Docker 的解法:把应用和它所需的一切(运行时、系统库、配置文件)打包成一个镜像,在任何支持 Docker 的地方运行完全一致的环境。

1.2 Docker 与虚拟机的区别

维度虚拟机(VM)Docker 容器
虚拟化层级硬件级(Hypervisor)操作系统级(Kernel Namespaces/Cgroups)
Guest OS每个 VM 独立完整 OS共享宿主机内核
启动时间分钟级秒级
资源占用数 GB / 每个 VMMB 级 / 每个容器
性能损耗10-20%< 5%
隔离性强(硬件隔离)进程级(够用但弱于 VM)
密度一台物理机 10-100 个 VM一台物理机 1000+ 容器

核心认知:Docker 不是虚拟机,它是运行在宿主机操作系统上的隔离进程,利用 Linux Kernel 的 Namespaces(隔离)、Cgroups(资源限制)、UnionFS(分层文件系统)实现轻量级虚拟化。


二、核心概念

2.1 镜像(Image)

镜像是一个只读模板,包含运行应用所需的一切:代码、运行时、库、环境变量、配置文件。镜像由分层(Layer)结构组成:

镜像分层结构(从底到顶)
├── 基础镜像层:Alpine Linux(5MB)
├── 依赖层:安装 Node.js(50MB)
├── 应用依赖层:npm install(100MB)
└── 应用代码层:COPY . /app(10MB)
    = 总镜像大小 ~165MB

分层的好处:多个镜像可以共享相同的底层。例如 10 个 Node.js 应用镜像都基于 node:18-alpine,基础层只在磁盘存一份。

2.2 容器(Container)

容器是镜像的运行实例。你可以把镜像理解为类(Class),容器理解为对象(Object):

# 从镜像运行一个容器
docker run -d -p 3000:3000 --name my-app my-image

# 查看运行中的容器
docker ps

# 停止容器
docker stop my-app

# 删除容器
docker rm my-app

容器的特性:

  • 隔离性:每个容器有自己的文件系统、网络、进程空间
  • 可写层:容器运行时对文件系统的修改写入一个可写层(Copy-on-Write)
  • 临时性:容器删除后,可写层数据丢失(需要用 Volume 持久化)

2.3 Dockerfile

Dockerfile 是定义镜像构建步骤的文本文件:

# 使用官方 Node.js 轻量镜像作为基础
FROM node:20-alpine

# 设置工作目录
WORKDIR /app

# 先复制依赖文件(利用缓存:只要 package.json 不变,npm install 层就不重建)
COPY package.json package-lock.json ./
RUN npm ci --only=production

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["node", "server.js"]

2.4 仓库(Registry)

Docker Hub 是公共镜像仓库(类似 npm registry):

# 拉取官方镜像
docker pull node:20-alpine

# 推送自己的镜像到 Docker Hub
docker tag my-app username/my-app:v1.0
docker push username/my-app:v1.0

替代方案:自建 Registry、AWS ECR、阿里云容器镜像服务、GitHub Container Registry。


三、安装与第一个容器

3.1 安装 Docker

# macOS
brew install --cask docker

# Ubuntu
sudo apt update
sudo apt install -y docker.io docker-compose
sudo systemctl start docker

# Windows
# 下载 Docker Desktop for Windows
# 验证安装
docker --version
# Docker version 27.0.0, build xxx

3.2 运行第一个容器

# 运行 Hello World
docker run hello-world

# 运行一个 Nginx 服务器
docker run -d -p 8080:80 --name my-nginx nginx
# -d: 后台运行
# -p 8080:80: 把容器的 80 端口映射到宿主机的 8080
# --name: 给容器命名

# 浏览器访问 http://localhost:8080

3.3 常用命令速查

# 镜像操作
docker images                    # 列出本地镜像
docker rmi image_id             # 删除镜像
docker build -t my-app .        # 构建镜像
docker pull nginx               # 拉取镜像
docker push username/my-app     # 推送镜像

# 容器操作
docker ps                       # 运行中的容器
docker ps -a                    # 所有容器(包括停止的)
docker start my-container       # 启动容器
docker stop my-container        # 停止容器
docker restart my-container     # 重启
docker rm my-container          # 删除容器
docker logs my-container        # 查看日志
docker exec -it my-container sh # 进入容器内部

# 系统维护
docker system prune             # 清理未使用的镜像/容器/网络/缓存
docker volume ls                # 列出 Volume
docker network ls               # 列出网络

四、Docker 工作流

1. 编写应用代码
   ↓
2. 编写 Dockerfile(定义镜像怎么构建)
   ↓
3. 构建镜像:docker build -t my-app .
   ↓
4. 本地测试运行:docker run -p 3000:3000 my-app
   ↓
5. 推送到 Registry:docker push my-app
   ↓
6. 在服务器上拉取运行:docker pull my-app && docker run my-app

五、数据持久化:Volume

容器是临时的,数据需要持久化存储:

# 创建 Named Volume
docker volume create my-data

# 运行容器时挂载 Volume
docker run -v my-data:/app/data my-app

# 或者挂载宿主机目录
docker run -v /host/path:/container/path my-app

# 查看 Volume
docker volume ls
docker volume inspect my-data
方式适用场景
Named Volume数据库数据、配置文件(Docker 管理)
Bind Mount开发时代码热重载(宿主机目录直接映射)
** tmpfs Mount**敏感数据(不写入磁盘,只在内存)

六、网络通信

Docker 默认创建三种网络:

网络类型说明
bridge默认,容器间通过内部 IP 通信
host容器直接使用宿主机网络
none无网络
# 查看容器 IP
docker inspect my-container | grep IPAddress

# 容器间通信(通过容器名,需要自定义网络)
docker network create my-network
docker run -d --name db --network my-network postgres
docker run -d --name api --network my-network my-api
# 在 api 容器内可以通过 http://db:5432 访问数据库

七、常见问题(FAQ)

Docker 和 Kubernetes 有什么关系?

Docker 是容器运行时( run containers),Kubernetes 是容器编排平台(orchestrate containers at scale)。简单类比:Docker 像单台车的引擎,K8s 像管理整个车队的调度系统。详见 Docker vs Kubernetes 对比与选型

Docker 收费吗?

Docker Engine(核心运行时)完全免费开源。Docker Desktop 对个人和教育免费,企业使用需要 Docker Business 订阅。

容器数据会丢失吗?

容器停止/删除后,容器内的可写层数据会丢失。需要持久化的数据必须使用 Volume 或 Bind Mount

Docker 只能跑 Linux 吗?

Docker Engine 基于 Linux 内核特性(Namespaces/Cgroups),所以:

  • Linux:原生支持
  • macOS/Windows:通过 Docker Desktop(基于轻量 Linux VM)运行
  • 容器内的应用可以是任何语言(Node.js/Python/Go/Java 等)

镜像太大了怎么优化?

  1. 使用轻量基础镜像(Alpine 或 distroless)
  2. 多阶段构建(Multi-stage)
  3. .dockerignore 排除不需要的文件(node_modules/.git)
  4. 合并 RUN 指令减少层数

详见 Dockerfile 最佳实践

相关阅读

← 上一篇

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「saas」更多文章