Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么
文章目录
- [Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么](#Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么)
-
- [一、为什么要学 Docker](#一、为什么要学 Docker)
- [二、Docker 的核心价值](#二、Docker 的核心价值)
-
- [1. 环境一致](#1. 环境一致)
- [2. 可移植](#2. 可移植)
- [3. 隔离](#3. 隔离)
- [4. 标准化交付](#4. 标准化交付)
- [三、Docker 到底解决的是什么问题](#三、Docker 到底解决的是什么问题)
- [四、用 hello-world 理解 Docker 的最小流程](#四、用 hello-world 理解 Docker 的最小流程)
- 五、什么是镜像
- 六、什么是容器
- 七、镜像和容器的关系
- 八、怎么区分镜像和容器
- 九、三个最基础的观察命令
-
- [1. `docker images`](#1.
docker images) - [2. `docker ps`](#2.
docker ps) - [3. `docker ps -a`](#3.
docker ps -a)
- [1. `docker images`](#1.
- [十、顺手记住 `docker pull`](#十、顺手记住
docker pull) - 十一、这一阶段最容易混淆的点
-
- [1. 镜像不是容器](#1. 镜像不是容器)
- [2. 容器不是"纯环境"](#2. 容器不是“纯环境”)
- [3. `docker run` 不只是"运行"](#3.
docker run不只是“运行”)
- 十二、这一部分学完后应该掌握什么
- 十三、这一部分的个人总结
- 十四、下一步要学什么
本专栏文章导航
- 第 01 篇:Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么
- 第 02 篇:Docker 入门学习笔记 02:基础命令、前后台运行,以及 attach、logs、exec 的区别
- 第 03 篇:Docker 入门学习笔记 03:端口映射到底是什么,为什么容器启动了却访问不到
- 第 04 篇:Docker 入门学习笔记 04:环境变量到底在做什么,为什么很多容器都依赖它
- 第 05 篇:Docker 入门学习笔记 05:卷到底是什么,为什么容器删了数据却还能保留
- 第 06 篇:Docker 入门学习笔记 06:用一个可复现的 Python 项目真正理解 Dockerfile
- 第 07 篇:Docker 入门学习笔记 07:用一个多服务案例真正理解 Docker Compose
这篇笔记对应我在微服务部署学习中的第一阶段前两块内容:
- Docker 到底在解决什么问题
- 镜像和容器到底是什么
这两个问题看起来基础,但它们决定了后面学 Dockerfile、Docker Compose、Kubernetes 时能不能真正理解。
一、为什么要学 Docker
在没有 Docker 的时候,一个项目要运行起来,通常不只是把代码拿到手就行,还需要同时满足很多条件:
- 正确的操作系统环境
- 正确的语言版本
- 正确的依赖包版本
- 正确的配置文件和环境变量
- 正确的端口和运行方式
这就会导致一个经典问题:
代码在我的机器上可以跑,换一台机器就不一定能跑。
所以,项目难迁移并不是表面问题,真正的问题是:
- 运行环境不一致
- 依赖不一致
- 配置不一致
- 启动方式不一致
Docker 解决的核心,就是把这些和应用运行有关的内容尽量标准化。
二、Docker 的核心价值
可以先用一句话概括 Docker:
Docker 是把应用和它运行所需的环境一起打包,然后以容器的方式运行。
它带来的价值主要有四点:
1. 环境一致
开发、测试、部署时尽量使用同一套运行环境,减少"换台机器就出问题"的情况。
2. 可移植
应用不再只是源代码,而是带着运行方式一起被交付,因此更容易迁移到别的机器或平台。
3. 隔离
不同应用可以运行在各自相对独立的容器中,互相影响更小。
4. 标准化交付
别人不需要重新猜这个项目应该怎么配环境,而是直接运行你提供的容器化结果。
三、Docker 到底解决的是什么问题
如果只用一句更准确的话来总结:
Docker 解决的是应用在不同环境中运行不一致的问题,而迁移困难、部署困难、排障困难,都是这个问题的表现。
所以 Docker 的价值不只是"能跑起来",而是:
- 更容易交付
- 更容易迁移
- 更容易部署
- 更容易复现问题
四、用 hello-world 理解 Docker 的最小流程
学习 Docker 时,一个很经典的实验是:
bash
docker version
docker pull hello-world
docker run hello-world
这几个命令分别在验证三件事:
docker version:Docker 客户端和服务端是否正常docker pull hello-world:主动把镜像下载到本地docker run hello-world:Docker 能否完成一次完整的拉取和运行流程
这里可以先顺手认识一个很常用的命令:
bash
docker pull hello-world
它的作用是:
只拉取镜像,不启动容器。
虽然 docker run hello-world 在本地没有镜像时也会自动拉取,但单独使用 docker pull 更有利于理解这两个动作的区别:
docker pull:下载镜像docker run:创建并启动容器
执行 docker run hello-world 时,实际发生的是下面这条链路:
- Docker 先检查本地是否已经有
hello-world镜像 - 如果没有,就从远程仓库拉取镜像
- Docker 基于这个镜像创建一个容器
- 容器运行里面的程序
- 程序输出内容后结束
- 容器也随之结束
这个流程非常重要,因为它已经把 Docker 的最基本工作方式展示出来了。
五、什么是镜像
镜像,英文叫 Image。
可以把它理解成一个静态模板,里面已经包含了应用运行所需的基础内容,比如:
- 基础运行环境
- 应用代码
- 依赖
- 启动命令定义
镜像本身并不是"正在运行的程序",它更像是一个可供启动的模板。
一个简单的理解方式是:
- 镜像像安装包
- 镜像也像模板
但更准确地说,镜像是一个 用来创建容器的静态对象。
六、什么是容器
容器,英文叫 Container。
容器是由镜像启动出来的运行实例。
也就是说:
- 镜像是静态的
- 容器是动态的
如果镜像只是"准备好的一套运行模板",那么容器就是"这套模板真正跑起来之后的实例"。
所以看到容器时,要想到的是:
- 它已经被创建出来了
- 它可能正在运行,也可能运行完退出了
- 它和镜像不是一回事
七、镜像和容器的关系
这是 Docker 入门最关键的一点。
镜像和容器的关系可以这样理解:
- 先有镜像
- 再由镜像创建容器
例如:
bash
docker run hello-world
这条命令并不是简单地"运行镜像",更准确地说,它是在做两件事:
- 找到或拉取镜像
- 基于镜像创建并启动容器
同一个镜像还可以创建多个容器。
这意味着:
- 一个镜像可以被重复使用
- 多个容器可以来自同一个镜像
- 它们是不同的运行实例
八、怎么区分镜像和容器
判断时可以记住一个简单方法:
如果它是 静态模板,那更可能是镜像。
如果它是 已经创建出来的运行实例,那更可能是容器。
再说得更具体一点:
docker images看的通常是镜像docker ps和docker ps -a看的通常是容器
九、三个最基础的观察命令
在理解镜像和容器时,这三个命令最重要:
bash
docker images
docker ps
docker ps -a
1. docker images
查看本地有哪些镜像。
例如执行过 docker run hello-world 之后,通常就能看到:
text
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest e2ac70e7319a 2 weeks ago 10.1kB
这里显示的是镜像信息,不是容器信息。
2. docker ps
查看当前正在运行的容器。
我当前环境里的实际输出是:
text
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
这里没有任何容器记录,说明当前没有容器处于运行状态。
如果某个容器执行完就退出了,那么这里通常看不到它。
3. docker ps -a
查看所有容器,包括:
- 正在运行的
- 已经退出的
我当前环境里的实际输出是:
text
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1aee1d171327 hello-world "/hello" 16 minutes ago Exited (0) 16 minutes ago kind_villani
这也是为什么 hello-world 经常在 docker ps 里看不到,但能在 docker ps -a 里看到。
原因很简单:
它输出完欢迎信息之后就退出了,不再处于运行状态。
十、顺手记住 docker pull
在 Docker 里,pull 是一个非常基础的动作。
例如:
bash
docker pull nginx
它表示把 nginx 镜像拉到本地,但不会启动任何容器。
所以在学习早期,把下面这两个动作分开理解会非常重要:
docker pull:先把镜像下载到本地docker run:再基于镜像创建并启动容器
十一、这一阶段最容易混淆的点
1. 镜像不是容器
镜像只是模板,本身不等于正在运行的实例。
2. 容器不是"纯环境"
很多初学者会把容器理解成"一个环境",这个方向不完全错,但不够准确。
更准确的说法是:
容器是基于镜像创建出来的运行实例,它带着相对隔离的运行环境。
3. docker run 不只是"运行"
docker run 背后往往包含:
- 检查镜像
- 拉取镜像
- 创建容器
- 启动容器
它本质上是一个组合动作。
十二、这一部分学完后应该掌握什么
如果这一部分真正掌握了,你应该能清楚表达下面这些内容:
- Docker 解决的是应用运行环境不一致的问题
- 镜像是静态模板
- 容器是镜像启动后的运行实例
- 同一个镜像可以启动多个容器
docker images看镜像docker ps看运行中的容器docker ps -a看所有容器
十三、这一部分的个人总结
学到这里,我觉得 Docker 最值得先记住的不是命令,而是思路:
过去交付一个项目,往往交付的是代码;
而 Docker 的思路是,把代码、依赖和运行方式一起标准化交付。
理解了这一点,后面再学端口、卷、环境变量、Dockerfile、Docker Compose,就不会只是在背命令,而是在理解一整套容器化运行方式。
十四、下一步要学什么
接下来应该继续学习 Docker 的基础操作,包括:
docker rundocker psdocker logsdocker execdocker stopdocker rm
也就是从"理解概念"进入"真正操作容器"。
本专栏文章导航
- 第 01 篇:Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么
- 第 02 篇:Docker 入门学习笔记 02:基础命令、前后台运行,以及 attach、logs、exec 的区别
- 第 03 篇:Docker 入门学习笔记 03:端口映射到底是什么,为什么容器启动了却访问不到
- 第 04 篇:Docker 入门学习笔记 04:环境变量到底在做什么,为什么很多容器都依赖它
- 第 05 篇:Docker 入门学习笔记 05:卷到底是什么,为什么容器删了数据却还能保留
- 第 06 篇:Docker 入门学习笔记 06:用一个可复现的 Python 项目真正理解 Dockerfile
- 第 07 篇:Docker 入门学习笔记 07:用一个多服务案例真正理解 Docker Compose