Docker学习
Docker是什么
Docker 是一套把应用连同运行环境一起打包、并在任何机器上几乎一致运行的容器技术。

主要解决三类问题:
- 环境一致:利用容器技术,减少本地和真实机器运行环境不一致的问题
- 交付标准化:发布物从「一堆文件 + 安装步骤」变成「一个镜像 + 一条启动命令」
- 隔离与密度:多个docker容器能跑在同一台物理机上,彼此进程级隔离,相比虚拟机更轻量级
Docker容器与虚拟机的区别
Docker容器
Docker容器之间共用同一个系统内核

虚拟机
每个虚拟机包含完整的操作系统内核

Docker是如何实现容器化的
Docker利用了Linux内核的两大原生功能 实现容器化:
- Cgroups:限制和隔离进程的资源使用,为每个容器设置内存、cpu等资源使用上限,确保一个容器的资源消耗不会影响其他容器和宿主机
- Namespaces:隔离进程的资源视图,使得容器只能看到自己的文件目录、网络资源而看不到宿主机的,让容器看起来还是一个进程
镜像(Image)
镜像是一份用来创造容器的配置文件,通过一个镜像可以创建多个容器,里面通常包括:
- 应用程序(编译产物或脚本)
- 依赖(系统库、运行时如 Node、JRE)
- 元数据(启动命令、环境变量默认值、暴露端口说明等)
Docker Hub
Docker的官方镜像仓库是Docker Hub,存储官方和其他开发者分享的镜像
镜像相关的常用命令
- docker build:根据 Dockerfile 构建镜像
- docker pull:从仓库 拉取镜像
- docker images:列出本地镜像
利用Dive分析镜像
我们可以通过Dive分析镜像组成,以一个node镜像(koa)为例,整个镜像组成包括:
- 基础系统层(用户态文件系统、基础系统库):FROM blobs、apt-get
- 业务代码相关(COPY):业务文件被打进镜像的层
- 应用依赖层:RUN npm install # buildkit,也就是node_modules里的依赖

通过这里也可以看到,Docker 镜像不是一个单文件,而是由多层(layer)叠加出来的,详细见:layer概念
容器(Container)
容器可以理解成最小型的一个操作系统环境,可以对各种服务以及应用容器化,是镜像的运行实例
容器相关常用命令
- docker run
- docker ps
- docker container
- docker rm
后台运行
让容器在后台运行,不影响当前命令行
1 | docker run -d |
端口映射
容器的网络和宿主机的网络是隔离的,默认情况下并不能从宿主机直接访问到docker的内部网络,所以要把容器内的端口和宿主机的端口做一个映射
1 | docker run -p xxxx:xxxx |

挂载卷
绑定挂载
-v:把宿主机和容器的文件目录进行绑定,常用于数据的持久化缓存
因为删除容器时,容器内的数据会被永久删除掉, 如果使用挂载卷,容器对应的数据也会被保存到宿主机对应的文件目录里
1 | docker run -v /Users/you/data:/app/data my-image |

命名卷
1 | docker volume create |
(第一次创建时会把容器里的文件复制过来)
设置环境变量
1 | docker run -e |
容器改名
1 | docker run --name |
控制台进入容器进行交互
1 | docker run -it |
容器停止时自动删除容器
1 | docker run --rm |
容器停止后的重启策略
–restart always:停止就立马重启
1 | docker run --restart always nginx:alpine |
unless-stop:手动停止不会强制重启
1 | docker run --restart unless-stopped nginx:alpine |
测试容器
1 | docker exec |
Dockerfile
在使用 docker 部署自己应用时,往往需要独立构建镜像。
docker 使用 Dockerfile 作为配置文件构建镜像,简单看一个 nginx静态资源服务器的 dockerfile:
1 | # ====== build stage ====== |
FROM
声明这一 stage 的基础镜像,后面的 RUN、COPY 等都基于它的文件系统和环境。
ADD
把构建上下文里的文件/目录(或一个 URL)放进镜像指定路径。
RUN
在构建镜像时执行一条或多条 shell 命令(安装依赖、编译、npm run build 等)。
CMD
指定容器启动时默认执行的命令(主进程)。镜像可以没有 ENTRYPOINT 时,CMD 就是容器入口。
Layer(分层)的概念
Docker 镜像不是一个单文件,而是由多层(layer)叠加出来的
- 每条
RUN/COPY/ADD指令通常会产生一层(FROM是基础层)。 - 层是只读的,容器启动后会在最上面再加一层可写层(容器层)。
- 在构建时可以利用缓存,详细可见:Docker构建缓存
对应上面的 Dockerfile,大致可以理解为:
FROM node:20-alpine AS builder:构建阶段基础层(Node 运行时 + Alpine 用户态)。COPY package.json yarn.lock ./+RUN yarn install --frozen-lockfile:依赖清单层 + 依赖安装层COPY . .+RUN yarn build:业务代码层 + 构建产物层(生成前端静态文件)。FROM nginx:1.27-alpine:运行阶段基础层(仅保留 nginx 运行环境)。COPY nginx.conf ...+COPY --from=builder /app/build ...:运行时配置层 + 静态产物层EXPOSE 80、CMD ["nginx", "-g", "daemon off;"]:镜像元数据(端口声明与启动命令)
利用dive验证:
Docker Network
bridge模式
宿主机网络和容器网络隔离,通过bridge去做端口映射
host模式
直接使用宿主机网络的模式
none模式
不联网
Docker Compose
容器编排技术
compose up
compose down
K8s
大规模的容器编排