Docker 学习笔记(一):基础与核心原理

写在前面

本文是 Docker 系列第一篇。容器化是云原生的基石,K8s、微服务、CI/CD 都建立在它之上。本文讲清楚 Docker 是什么、容器的底层原理(namespace/cgroups)、核心概念和基本用法。

系列定位:本系列已有 K8s 系列,Docker 是它的前置基础。K8s 系列里提到的容器概念,这里能找到根源。


一、Docker 是什么

1.1 定义

1
2
3
4
5
6
Docker = 容器化平台
  把应用 + 依赖(库、环境、配置)打包成一个「容器」
  容器在任何装了 Docker 的机器上都能一致运行

解决的核心问题:
  "在我机器上能跑啊!" → 容器保证了环境一致

1.2 容器 vs 虚拟机

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
虚拟机(VM):
  硬件级虚拟化
  每个 VM 完整操作系统(内核 + 用户空间)
  重、慢、占资源(GB 级)

容器(Container):
  操作系统级虚拟化
  共享宿主机内核,只隔离进程
  轻、快、省资源(MB 级)

        虚拟机                  容器
  ┌──────────────┐       ┌──────────────┐
  │ App │ App     │       │ App │ App     │
  │ 库   │ 库      │       │ 库   │ 库      │
  │ 完整OS │完整OS  │       │  容器运行时    │
  │ Hypervisor   │       │  宿主机OS内核   │
  │  物理硬件    │       │   物理硬件     │
  └──────────────┘       └──────────────┘
  启动分钟级、GB         启动秒级、MB

二、核心概念

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
镜像(Image)
  只读模板,包含应用 + 依赖 + 环境
  分层存储(Layer)
  类比:面向对象的「类」、程序的「安装包」

容器(Container)
  镜像的运行实例
  可读写(在镜像层上加一层)
  类比:「对象」、安装包「运行起来」

仓库(Registry)
  存放镜像的地方
  Docker Hub(公共)、Harbor(私有)、阿里云/腾讯云镜像服务
  类比:代码的 GitHub、npm registry

Dockerfile
  描述如何构建镜像的文本文件
  一系列指令(FROM/RUN/COPY...)

三、容器底层原理

容器不是凭空实现的,它依赖 Linux 内核三个特性:

3.1 Namespace(隔离)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Namespace 让容器"以为"自己独占系统

  PID Namespace    — 进程隔离(容器内 PID 从 1 开始,看不到宿主机进程)
  NET Namespace    — 网络隔离(独立的网卡、IP、端口、路由)
  IPC Namespace    — 进程间通信隔离
  MOUNT Namespace  — 文件系统挂载点隔离
  UTS Namespace    — 主机名隔离
  USER Namespace   — 用户隔离(容器内 root ≠ 宿主机 root)
  Cgroup Namespace — cgroup 视图隔离

  → 容器 = 一个被 namespace 包裹的进程

3.2 Cgroups(资源限制)

1
2
3
4
5
6
7
8
Cgroups(Control Groups)限制容器能用多少资源

  CPU    — 限制 CPU 核数/份额
  内存   — 限制内存上限(超了 OOM Kill)
  磁盘IO — 限制读写速率
  网络   — 限速

  → 防止一个容器吃光宿主机资源

3.3 联合文件系统(UnionFS)

1
2
3
4
5
6
7
镜像分层存储的基础

  镜像由多个只读层叠加
  容器在镜像上加一个可写层(Copy-on-Write)
  多个容器共享相同的镜像层(省空间)

  例:基础镜像层 + 安装依赖层 + 应用代码层 + 容器可写层
1
2
3
一句话总结容器本质:
  容器 = Namespace(隔离)+ Cgroups(限制)+ UnionFS(分层镜像)
  它不是虚拟机,是一个被特殊隔离和限制的进程

四、安装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Linux(Ubuntu/Debian)
curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker

# 将当前用户加入 docker 组(免 sudo)
sudo usermod -aG docker $USER
# 重新登录生效

# 验证
docker version
docker run hello-world
1
2
3
4
5
6
macOS / Windows:
  安装 Docker Desktop(图形化,内置 Docker Engine)
  Windows 用 WSL2 后端性能更好

国内加速(镜像仓库):
  配置 registry-mirrors 指向国内镜像源

五、基本命令

5.1 镜像命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 搜索镜像
docker search nginx

# 拉取镜像(默认 Docker Hub)
docker pull nginx
docker pull nginx:1.25          # 指定版本
docker pull nginx:latest

# 列出本地镜像
docker images

# 删除镜像
docker rmi nginx

# 构建镜像(见 Dockerfile 篇)
docker build -t myapp:1.0 .

5.2 容器命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 运行容器
docker run -d --name web -p 8080:80 nginx
#   -d            后台运行
#   --name web    容器名
#   -p 8080:80    端口映射(宿主机:容器)
#   nginx          镜像名

# 列出运行中的容器
docker ps
docker ps -a                    # 包括已停止的

# 启动/停止/重启
docker start web
docker stop web
docker restart web

# 进入容器
docker exec -it web bash        # 开个终端进去

# 查看日志
docker logs web
docker logs -f web              # 跟踪输出

# 删除容器
docker rm web
docker rm -f web                # 强制删除运行中的

# 查看容器详情/资源占用
docker inspect web
docker stats                    # 实时资源(CPU/内存)

六、第一个容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 跑一个 Nginx
docker run -d --name mynginx -p 8080:80 nginx

# 访问 http://localhost:8080 → 看到 Nginx 欢迎页
# 这个 Nginx 跑在容器里,和宿主机隔离

# 进入容器看
docker exec -it mynginx bash
ls /usr/share/nginx/html        # 网站文件
exit

# 查看日志
docker logs mynginx

# 停止并删除
docker stop mynginx && docker rm mynginx
1
2
3
4
5
发生了什么:
  1. docker pull nginx(拉镜像)
  2. 创建容器(隔离 namespace、限制 cgroups、挂载镜像层)
  3. 端口映射(宿主机 8080 → 容器 80)
  4. Nginx 进程在容器内跑(PID 1)

七、端口、数据、环境

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 端口映射(-p 宿主机:容器)
docker run -p 8080:80 -p 8443:443 nginx

# 数据卷(持久化,容器删了数据还在)
docker run -v /host/data:/container/data nginx
docker run -v mydata:/var/lib/mysql mysql      # 命名卷

# 环境变量
docker run -e MYSQL_ROOT_PASSWORD=123456 mysql

# 工作目录、用户
docker run -w /app -u appuser myimage

# 重启策略
docker run --restart=always nginx              # 总是自动重启

八、小结

  • Docker:容器化平台,解决环境一致性问题
  • 容器 vs 虚拟机:容器共享内核、轻量(MB)、秒启动;VM 完整 OS、重(GB)
  • 核心概念:镜像(模板)、容器(实例)、仓库(存储)、Dockerfile(构建脚本)
  • 底层原理:Namespace(隔离)+ Cgroups(限制)+ UnionFS(分层)
  • 基本命令:pull/run/ps/exec/logs/build

下一篇讲 Dockerfile——如何把你的应用打包成镜像。