全文19974字,耐心观看,原文链接https://ai.feishu.cn/wiki/M3dFwp2Q8ivABfkTFOCcavNVnSg?from=from_copylink

- 了解 Docker 镜像的基础知识
1.1 什么是 Docker 镜像?(image)
简单来说,Docker 镜像就是一个只读的"软件安装包"。
- 生活类比:
- 如果不理解镜像,可以把它想象成 Windows 的 .iso 安装光盘,或者是 手机里的 APP 安装包(.apk/.ipa)。
- 它里面包含了程序运行所需要的一切:代码、依赖库、环境变量、配置文件,甚至是一个微型的 Linux 操作系统(如 Alpine 或 Debian)。
- 不管你把这个"安装包"拿到哪台电脑上(只要装了 Docker),它跑起来的样子都是一模一样的。
1.1.1 核心原理:为什么它叫"镜像"?(分层存储)
Docker 镜像最大的特点是 "分层" (Layered)。它不是一个单一的大文件,而是像"千层饼"一样,由很多层只读文件叠加而成的。
1.1.2 镜像的结构
- Base Image(基础层):最底层通常是一个操作系统引导层(bootfs),上面是操作系统的根文件系统(rootfs),比如 Ubuntu、CentOS 或 Alpine。
- Layer(中间层):在基础层之上,每安装一个软件(比如 install nginx)、每修改一个配置、每复制一个文件,都会生成一个新的"层"。
- Image(最终镜像):所有这些层叠加在一起,对外展示为一个完整的文件系统。
1.1.3 为什么要分层?(知其所以然)
这是 Docker 最天才的设计,主要为了 资源共享 和 节省空间。
- 举个例子:
- 假设你有 10 个不同的镜像(比如 Nginx、Redis、Node.js),它们底层的系统都是 Debian。
- 如果不分层:你需要下载 10 个 Debian 系统,硬盘里存 10 份,既浪费带宽又浪费硬盘。
- 分层后:Docker 只需要下载一次 Debian 基础层。这 10 个镜像会共用这同一份底层文件。当你下载 Redis 时,如果 Docker 发现你本地已经有 Debian 层了,它就只下载 Redis 独有的那几兆文件。
1.1.4 镜像的关键特性
只读(Read-Only)
所有的镜像层都是只读的,不能修改。
- 问题:如果我想改镜像里的代码怎么办?
- 答案:你不能直接改原镜像。你只能基于原镜像启动一个容器,修改后生成一个新的镜像层;或者修改构建脚本(Dockerfile)重新构建一个新的镜像。
- 好处:这保证了环境一致性。测试环境测好的镜像,推送到生产环境时,绝对不会因为"被人误改了"而出现 Bug。
唯一标识(Image ID)
每个镜像都有一个全球唯一的身份证号(Image ID),通常是一串长长的哈希值(SHA256)。为了方便人类记忆,我们通常用 仓库名:标签 来称呼它,例如 nginx:latest 或 mysql:5.7。
1.1.5 小结(复习用)
- 它是啥:一个只读的、包含运行环境的软件包。
- 结构:像千层饼一样的分层结构。
- 优点:分层共享,节省空间;只读不可变,安全稳定。
- 了解 Docker 容器的基础知识
如果说镜像是"静止的模具",那么容器就是"鲜活的生命"。
2.1 什么是 Docker 容器?
简单来说,容器就是镜像运行起来后的一个"实例"。
- 生活类比:
- 类与对象:如果你熟悉编程,镜像就是 Class(类),容器就是 Object(对象/实例)。
- 程序与进程:镜像就像躺在硬盘里的 QQ.exe(可执行文件),容器就像是你双击打开后,正在内存里跑着的 QQ 进程。
- 房子与住户:镜像是一个精装修的样板房(空的),容器就是你拎包入住后的家(有了你的私人物品、生活痕迹)。
- 游戏光盘(镜像) vs 运行中的游戏(容器):镜像就像一张《魔兽世界》的光盘,它是静止的。容器就像是你把它插进电脑、运行起来后的游戏画面,你在里面打怪升级(产生数据和变化),这些都是发生在容器里的。
- 户型图(镜像) vs 样板间(容器):镜像是一张画好的装修图纸(只读)。容器是根据这张图纸盖出来的真实房间,你可以往里面搬家具、住人(可读写)。
2.2 核心原理:容器是怎么"跑"起来的?
初学者容易把容器当成一个"轻量级虚拟机",但它们本质完全不同。
2.2.1 容器 = 进程 + 隔离 (Isolation)
容器本质上只是宿主机上的一个 特殊进程。
- 普通进程:你运行一个 python app.py,它能看到电脑里所有的文件,能看到其他进程,能随便用 CPU。
- 容器进程:Docker 给这个进程戴上了"VR 眼镜"和"手铐脚镣",让它以为自己拥有一台独立的电脑,但实际上它只是被隔离了。
2.2.2 实现隔离的三大黑科技(知其所以然)
Docker 用 Linux 内核的三大技术来实现这种"欺骗":
- Namespaces(命名空间)------实现"欺骗视觉"
|-------------------|
| 作用:让容器看不见外面的世界。 |
- PID Namespace :进程隔离。容器里的进程看自己的 ID 是 1(老大),但其实它在宿主机上可能是一个 ID 为 12345 的普通小弟。
- Mount Namespace :挂载点隔离 。容器只能看到自己目录下的文件(比如 /app),根本看不到宿主机的 C 盘 D 盘。
- Network Namespace :网络隔离。容器有独立的网卡、IP 地址、路由表,感觉自己插着独立的网线。
- 类比:VR 眼镜。戴上它,你虽然身体在客厅,但你眼里只有虚拟世界,完全看不见客厅里的沙发和电视。戴上它,容器以为自己住在一个大别墅里(有独立的 IP、独立的文件系统、独立的进程 ID),其实它只是挤在宿主机的一个小角落里。它看不见外面的宿主机,也看不见别的容器。
- Cgroups(控制组)------ 实现"资源限制"
|---------------------|
| 作用:限制容器"不能抢"太多资源。 |
- 限制 CPU:规定这个容器只能用 0.5 个核,超了就慢下来。
- 限制内存:规定只能用 512MB 内存,超了就杀掉(OOM)。
- 类比:配额水表/电表。虽然大家住同一栋楼,共用一个水管,但给你的房间装了智能水表,超过配额就断水,防止你一个人把整栋楼的水都用光。
- 场景:你可以限制某个容器最多只能用 10% 的 CPU,或最多用 512MB 内存。如果超了,系统会把它杀掉,保证不影响宿主机和其他容器。
- UnionFS(联合文件系统)& chroot------ 实现"写时复制" (Copy-on-Write) "文件"隔离
|---------------------|
| 作用:给容器一个独立的"系统盘"。 |
- 问题:镜像(Image)是只读的,那容器里产生的日志、修改的文件存在哪?
- 机制:Docker 会在只读的镜像层之上,盖一层薄薄的 "读写层" (Writable Layer)。
- 原理:
- 读文件:直接读底层的镜像。
- 写文件:当你在这个"只读"文件上写字时,Docker 会瞬间把这个文件复制一份到顶部的"读写层",你修改的其实是这个副本。
- 结果:底下的镜像永远不会被破坏。容器一删,这层"读写层"就丢了,数据也就没了(所以要用数据卷 Volume 来持久化)。
换句话说
chroot / pivot_root:它可以把某个进程的"根目录"锁定在指定文件夹里(比如 /var/lib/docker/overlay2/xxx)。在这个进程看来,这个文件夹就是它的 /(根目录),它永远走不出这个圈。
UnionFS:它把只读的镜像层和可读写的容器层"联合"挂载在一起,形成一个完整的文件系统给容器看。
- 类比:全息投影的房间。
- chroot 就像把你关进了一个空房间,锁上门,你出不去。
- UnionFS 就像是在这个空房间里,用全息投影投射出了家具、墙纸(镜像层)。你看着很真实,也可以在里面画画(读写层),但其实你并没有真的改变这个房间的结构。
2.2.3 为什么需要"写时复制" (Copy-on-Write)?
- 问题:镜像(图纸)是不能改的,那我在容器(房间)里产生的垃圾(日志)或者新买的家具(新文件)放哪?
- 机制:Docker 会在只读的镜像层上面,盖一层透明的"读写层"。
- 类比:描红纸。
- 底下的字帖(镜像)是不能涂改的。
- Docker 在字帖上蒙了一张透明的纸(读写层)。
- 你想改哪个字,就把它抄到透明纸上再修改。
- 你看上去是改了,其实底下的字帖完好无损。
- 后果:这张透明纸(容器)一扔,你修改的内容就全没了(除非你用了数据卷保存)。
++++总结++++
- Namespaces = 围墙(看不见外面)
- Cgroups = 限额(抢不到资源)
- UnionFS = 幻象(独立的文件环境)
(容器的唯一标识容器ID与镜像ID一样采用UUID形式表示,是由64个十六进制字符组成的字符串。
通过容器名称来代替容器ID引用容器。)
2.3 容器 vs 虚拟机 (VM):为什么 Docker 这么快?
- 比喻:
- 虚拟机:像是一栋大楼里,给每家每户都配了独立的水电站、独立的锅炉房(资源浪费)。
- 容器:像是一栋胶囊公寓,大家共享大楼的水电、地基(内核),但每个人住在自己的独立胶囊房间里(互不干扰)。
容器 vs 虚拟机 (VM)
- 虚拟机 (VM):
- 类比:独栋别墅。每家每户都有独立的地基、供暖系统(独立的操作系统内核)。
- 缺点:太重了,建起来慢(启动慢),占地面积大(占用内存大)。
- 容器 (Container):
- 类比:胶囊公寓。大家共享大楼的地基和供暖(共享宿主机内核)。
- 优点:轻便,拎包入住(秒级启动),省空间(占用内存小)。
2.4 容器的生命周期(Lifecycle)
容器是短暂的(Ephemeral)。设计理念是"用完即焚"。
- Created:刚造出来,还没跑。
- Running:正在干活。
- Paused:暂停(类似电脑睡眠)。
- Exited (Stopped):干完活了,或者报错退出了。注意:停止不等于删除,它的尸体(文件系统)还在。
- Deleted:彻底销毁,渣都不剩。
小结:
容器就是一个被隔离的进程,它利用 Namespace 欺骗视觉,利用 Cgroups 限制资源,利用 写时复制 来保护镜像。
小结
- 容器 = 镜像 + 读写层。
- 容器本质是隔离的进程。
- 容器比虚拟机轻量,是因为共享内核。
- 了解Docker仓库基础知识(Repository)
3.1 什么是 Docker 仓库?
简单来说,仓库是集中存放镜像的地方。
- 生活类比:
- 代码界:如果镜像是代码,仓库就是 GitHub。
- 手机界:如果镜像是 APP,仓库就是 App Store(应用商店)。
- 物流界:如果镜像是货物,仓库就是 亚马逊/京东的大型物流中心。
3.2 核心概念辨析:Registry vs Repository
初学者经常搞混这两个词,它们虽然都叫"仓库",但层级不同。
3.2.1 Registry(注册中心)------ "大商场"
- 定义:存放很多个仓库的服务器。
- 例子:
- Docker Hub:Docker 官方运营的全球最大的 Registry。
- 阿里云容器镜像服务:阿里云搭建的 Registry。
- Google Container Registry:谷歌搭建的 Registry。
- 类比:Registry 就像是一个具体的 "沃尔玛超市" 或 "7-11 便利店"。
3.2.2 Repository(仓库)------ "货架"
- 定义:Registry 里的一个具体的项目,里面存放了同一种软件的不同版本(Tags)。
- 例子:
- nginx:这是一个仓库,里面有 nginx:latest、nginx:1.19、nginx:alpine 等不同版本的镜像。
- mysql:这是一个仓库,里面有 mysql:5.7、mysql:8.0 等。
- 类比:Repository 就像是超市里的 "薯片货架"。这个货架上全都是薯片(同一个软件),但是有原味、番茄味、黄瓜味(不同 Tag 版本)。
3.2.3 完整的镜像地址结构
当我们执行docker pull时,其实我们是再写一个完整的地址:
|------------------------------------------------------------------------------------------|
| Plain Text 【Registry 地址】/【项目组/用户名】/【Repository名】:【Tag】 例如:docker.io/library/nginx:latest |
- docker.io:Registry地址(默认是Docker Hub,通常省略)。
- library:项目组(官方镜像都在library组,通常省略)
- nginx:Repository名字(必须写)
- latest:标签(不写默认是latest)
3.3 仓库的分类
3.3.1 共有仓库(public)
- 代表:Docker Hub(hub.docker.com)
- 特点:任何人都可以拉取
- 场景:你需要下载Nginx、Redis、Python等基础软件时,直接去公有仓库拉取。绝大多数开源软件都托管在这里。
3.3.2 私有仓库(Private)
- 代表:
- 企业自建:使用Docker Registry镜像或Harbor软件自己搭建的Registry
- 云厂商托管:阿里云、腾讯云提供的私有镜像服务(通常要付费或有配额)
- 特点:只有通过认证(Login)的人才能拉取和推送
- 场景:公司开发的业务代码(比如"双11大促支付系统"),里面有商业机密,绝对不能传到公网。只能传到公司内网的私有仓库里,供公司内部服务器部署使用。
- docker三大核心组件(镜像、容器、仓库)之间的关系及工作流程
4.1 三个核心角色(Locations & Objects)
这张图被分为左右两个大框,分别代表了两个物理位置:
- 左边大框:本地(Local Host)
- 这里是你自己的电脑或服务器。
- 角色 A:镜像(Image):
- 位置:左上角。
- 比喻:它是 "模具" 或 "类"。它是静态的、只读的。它是用来创建容器的模板。
- 角色 B:容器(Container):
- 位置:左下角。
- 比喻:它是 "蛋糕" 或 "对象"。它是动态的、正在运行的。它是真正干活的程序实体。
- 右边大框:注册中心(Registry)
- 这里是远程服务器(如 Docker Hub 或 阿里云镜像仓库)。
- 角色 C:仓库(Repository):
- 位置:右侧灰色方块。
- 比喻:它是 "超市货架" 或 "代码仓库"。这里存放着各种打包好的镜像,供大家下载使用。
4.2 四个核心动作(Actions)
图中的箭头代表了数据流向,也对应了Docker最常用的四个命令:
4.2.1 拉取(pull)
- 路径:仓库(Registry)->镜像(image)
- 命令:docker pull nginx
- 含义:"进货"。
- 你从远程的仓库里,把别人做好的镜像下载到你本地的硬盘里
- 场景:场景:你要安装某个软件(如 MySQL),第一步就是去仓库把它拉下来。
4.2.2 推送(push)
- 路径:镜像(image)->仓库(Registry)
- 命令:docker push my-app:v1
- 含义:"发货"。
- 你在本地做好了自己的镜像,想分享给同事,或者存到服务器上备份,就把它上传到远程仓库。
- 场景:开发完代码,打包成镜像后,发布到公司的私有仓库里。
4.2.3 实例化/运行(run)
- 路径:镜像(image)->容器(Container)
- 命令:docker run nginx
- 含义:"做蛋糕"
- 利用本地的镜像(模具),创建一个运行中的容器(蛋糕)
- 关键点:这是一个1对N的关系。一个镜像可以启动无数个容器(就像一个模具可以做无数个一模一样的蛋糕)
- 场景:软件下载(pull)好了,现在要启动它开始服务。
4.2.4 提交(commit)
- 路径:容器(container)->镜像(image)
- 命令:docker commit<容器ID><新镜像名>
- 含义:"定型"
- 你进入容器里修改了配置文件、安装了新软件,现在的容器和原来的镜像不一样了。你想保存这个状态,就把它反向打包成一个新的镜像。
- 场景:你在一个基础 Ubuntu 容器里装好了 Java 和 Tomcat,想把它保存下来,下次直接用这个环境,不用再重装一遍。
- 注:虽然图里画了这个,但实际工作中我们更推荐用 Dockerfile 来构建镜像,而不是用 commit ,因为 Dockerfile 更透明、可维护。
4.3 总结串讲
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| "大家看这张图,它完美解释了 Docker 的工作流: 一切从右边的 仓库(Registry) 开始。我们通过 pull (拉取) 命令,像逛超市一样把需要的软件镜像下载到 本地(Local)。 拿到 镜像(Image) 后,它是静态的,不能直接用。我们需要通过 run (运行) 命令,把它变成一个活生生的 容器(Container),这时候服务才真正跑起来。 如果我们在容器里修修补补,想保存劳动成果,可以用 commit (提交) 命令把它变成一个新的镜像。 最后,为了防止本地硬盘坏了丢失数据,或者为了分发给其他同事,我们通过 push (推送) 命令,把这个新镜像上传回远程 仓库。 这就是 Docker 的生命周期循环。" |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 由于怕初学者绕晕,这里开一个小知识点 * 镜像分类 * 操作系统:ubuntu, centos, alpine(基础底座)。 * 数据库:mysql, redis, mongo, postgres。 * 中间件:nginx, tomcat, rabbitmq。 * 应用软件:wordpress, jenkins, gitlab。 这四类(操作系统、数据库、中间件、应用软件)指的是 镜像的类型(分类),但它们存放在仓库里。 在 Docker 命令里,我们常说"去仓库拉个 Nginx"。 * 这句话严谨的翻译是:去 Docker Hub(注册中心) 的 library/nginx(仓库/货架) 里,拉取 nginx:latest(镜像/商品)。 |
- 命令详解
5.1 镜像基本信息与查看(实战)
5.1.1 镜像基本信息与查看实战
- 查看本地镜像列表
|--------------------------------------------------------|
| Plain Text 操作命令: [root@docker_dev ~]# docker images |
|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| Plain Text 输出示例: REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest a8780b506fa4 4 weeks ago 77.8MB hello-world latest feb5d9fea6a5 14 months ago 13.3kB |
- 输出字段详解
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| * REPOSITORY(仓库源): * 表示这个镜像是什么软件。例如 ubuntu 表示这是一个 Ubuntu 操作系统的镜像,redis 表示这是 Redis 数据库的镜像。 * TAG(标签): * 表示镜像的版本。例如 latest(最新版)、18.04、alpine 等。 * 知识点:REPOSITORY:TAG 共同构成了一个完整的镜像名(如 ubuntu:latest)。如果只写 ubuntu,Docker 默认去找 ubuntu:latest。 * IMAGE ID(镜像 ID): * 核心身份:这是镜像的全球唯一身份证号。 * 格式:它是一个 SHA256 哈希值,全长 64 个十六进制字符(为了方便显示,通常只截取前 12 位,如 a8780b506fa4)。 * 作用:当你对同一个镜像打不同的 Tag 时(比如把 my-app:v1 改名为 my-app:latest),它们的 Image ID 是一样的,说明它们本质上是同一个文件。 * CREATED(创建时间): * 镜像被打包构建的时间(注意:不是你下载的时间,是官方发布这个版本的时间)。 * SIZE(大小): * 镜像占用的逻辑大小。 * 注意:由于镜像有"分层共享"机制,如果你有 10 个镜像,它们加起来的 SIZE 显示是 5GB,但实际占用的硬盘空间可能只有 2GB(因为它们共用了底层的 Debian 系统层)。 |
- 如何引用一个镜像?
在使用 Docker 命令(如运行、删除)时,我们有三种方式来指定一个镜像:
- 使用完整名称:ubuntu:latest(推荐,最清晰)
- 使用镜像 ID:a8780b506fa4(精确,只要输入前几位能区分即可,不用输全)
- 使用摘要值 (Digest):一种更长、更精确的哈希值(通常用于自动化脚本,手动操作很少用)。
5.1.2 镜像描述文件Dockerfile---镜像的图纸
既然镜像是分层的,那这些层是怎么堆叠起来的呢?这就需要提到 Dockerfile。
- 定义:Dockerfile 是一个文本文件,它就像一张施工图纸。
- 作用:它包含了一系列指令,告诉 Docker 引擎:"第一步装系统,第二步考文件,第三步运行程序......",Docker 照着这张图纸,一步步把镜像构建(Build)出来。
- 举例 hello-world 为例
所有的 Docker 教程第一步都是运行 hello-world,我们看看这张图纸里写了什么
|-------------------------------------------------------|
| Plain Text FROM scratch COPY hello / CMD ["/hello"] |
- 行代码深度解析
- 第一行:FROM scratch
- 含义:从零开始。
- 深度解析:
- FROM 指令必须是第一行,它指定了基础镜像(Base Image)。通常我们会写 FROM ubuntu 或 FROM python。
- scratch 是 Docker 中一个特殊的、保留的空镜像。它里面什么都没有,连最基本的 Linux 命令行工具(ls, cd)都没有。
- 为什么要用它? 因为 hello-world 程序是用 C/Go 语言写好的二进制文件,它不需要操作系统环境就能直接在内核上跑。为了让镜像尽可能小(只有 13KB),所以用了这个空底座。
- 第二行:COPY hello /
- 含义:复制文件。
- 深度解析:
- COPY 指令的作用是把宿主机(你的电脑)里的文件拷贝到镜像里。
- 这句话的意思是:把当前目录下的 hello 可执行文件,复制到镜像的根目录 / 下。
- 第三行:CMD ["/hello"]
- 含义:默认启动命令。
- 深度解析:
- CMD 指定了当这个镜像变成容器并启动时,默认要干什么事。
- 这里的意思是:容器一启动,就执行根目录下的 /hello 程序。
- 这个程序执行完打印几行字后就会结束,所以容器也会随之停止(Exited)。
5.1.3 镜像常用操作命令(速查与实战)
在 Docker 中,管理镜像的命令通常以 docker image 开头,但为了方便,Docker 也提供了简写形式(如 docker pull)。建议大家在日常使用中优先记忆简写形式,效率更高。
Docker核心技术详解与简单实战
- 了解 Docker 镜像的基础知识

1.1 什么是 Docker 镜像?(image)
简单来说,Docker 镜像就是一个只读的"软件安装包"。
- 生活类比:
- 如果不理解镜像,可以把它想象成 Windows 的 .iso 安装光盘,或者是 手机里的 APP 安装包(.apk/.ipa)。
- 它里面包含了程序运行所需要的一切:代码、依赖库、环境变量、配置文件,甚至是一个微型的 Linux 操作系统(如 Alpine 或 Debian)。
- 不管你把这个"安装包"拿到哪台电脑上(只要装了 Docker),它跑起来的样子都是一模一样的。
1.1.1 核心原理:为什么它叫"镜像"?(分层存储)
Docker 镜像最大的特点是 "分层" (Layered)。它不是一个单一的大文件,而是像"千层饼"一样,由很多层只读文件叠加而成的。
1.1.2 镜像的结构
- Base Image(基础层):最底层通常是一个操作系统引导层(bootfs),上面是操作系统的根文件系统(rootfs),比如 Ubuntu、CentOS 或 Alpine。
- Layer(中间层):在基础层之上,每安装一个软件(比如 install nginx)、每修改一个配置、每复制一个文件,都会生成一个新的"层"。
- Image(最终镜像):所有这些层叠加在一起,对外展示为一个完整的文件系统。
1.1.3 为什么要分层?(知其所以然)
这是 Docker 最天才的设计,主要为了 资源共享 和 节省空间。
- 举个例子:
- 假设你有 10 个不同的镜像(比如 Nginx、Redis、Node.js),它们底层的系统都是 Debian。
- 如果不分层:你需要下载 10 个 Debian 系统,硬盘里存 10 份,既浪费带宽又浪费硬盘。
- 分层后:Docker 只需要下载一次 Debian 基础层。这 10 个镜像会共用这同一份底层文件。当你下载 Redis 时,如果 Docker 发现你本地已经有 Debian 层了,它就只下载 Redis 独有的那几兆文件。
1.1.4 镜像的关键特性
只读(Read-Only)
所有的镜像层都是只读的,不能修改。
- 问题:如果我想改镜像里的代码怎么办?
- 答案:你不能直接改原镜像。你只能基于原镜像启动一个容器,修改后生成一个新的镜像层;或者修改构建脚本(Dockerfile)重新构建一个新的镜像。
- 好处:这保证了环境一致性。测试环境测好的镜像,推送到生产环境时,绝对不会因为"被人误改了"而出现 Bug。
唯一标识(Image ID)
每个镜像都有一个全球唯一的身份证号(Image ID),通常是一串长长的哈希值(SHA256)。为了方便人类记忆,我们通常用 仓库名:标签 来称呼它,例如 nginx:latest 或 mysql:5.7。
1.1.5 小结(复习用)
- 它是啥:一个只读的、包含运行环境的软件包。
- 结构:像千层饼一样的分层结构。
- 优点:分层共享,节省空间;只读不可变,安全稳定。
- 了解 Docker 容器的基础知识
如果说镜像是"静止的模具",那么容器就是"鲜活的生命"。
2.1 什么是 Docker 容器?
简单来说,容器就是镜像运行起来后的一个"实例"。
- 生活类比:
- 类与对象:如果你熟悉编程,镜像就是 Class(类),容器就是 Object(对象/实例)。
- 程序与进程:镜像就像躺在硬盘里的 QQ.exe(可执行文件),容器就像是你双击打开后,正在内存里跑着的 QQ 进程。
- 房子与住户:镜像是一个精装修的样板房(空的),容器就是你拎包入住后的家(有了你的私人物品、生活痕迹)。
- 游戏光盘(镜像) vs 运行中的游戏(容器):镜像就像一张《魔兽世界》的光盘,它是静止的。容器就像是你把它插进电脑、运行起来后的游戏画面,你在里面打怪升级(产生数据和变化),这些都是发生在容器里的。
- 户型图(镜像) vs 样板间(容器):镜像是一张画好的装修图纸(只读)。容器是根据这张图纸盖出来的真实房间,你可以往里面搬家具、住人(可读写)。
2.2 核心原理:容器是怎么"跑"起来的?
初学者容易把容器当成一个"轻量级虚拟机",但它们本质完全不同。
2.2.1 容器 = 进程 + 隔离 (Isolation)
容器本质上只是宿主机上的一个 特殊进程。
- 普通进程:你运行一个 python app.py,它能看到电脑里所有的文件,能看到其他进程,能随便用 CPU。
- 容器进程:Docker 给这个进程戴上了"VR 眼镜"和"手铐脚镣",让它以为自己拥有一台独立的电脑,但实际上它只是被隔离了。
2.2.2 实现隔离的三大黑科技(知其所以然)
Docker 用 Linux 内核的三大技术来实现这种"欺骗":
- Namespaces(命名空间)------实现"欺骗视觉"
|-------------------|
| 作用:让容器看不见外面的世界。 |
- PID Namespace :进程隔离。容器里的进程看自己的 ID 是 1(老大),但其实它在宿主机上可能是一个 ID 为 12345 的普通小弟。
- Mount Namespace :挂载点隔离 。容器只能看到自己目录下的文件(比如 /app),根本看不到宿主机的 C 盘 D 盘。
- Network Namespace :网络隔离。容器有独立的网卡、IP 地址、路由表,感觉自己插着独立的网线。
- 类比:VR 眼镜。戴上它,你虽然身体在客厅,但你眼里只有虚拟世界,完全看不见客厅里的沙发和电视。戴上它,容器以为自己住在一个大别墅里(有独立的 IP、独立的文件系统、独立的进程 ID),其实它只是挤在宿主机的一个小角落里。它看不见外面的宿主机,也看不见别的容器。
- Cgroups(控制组)------ 实现"资源限制"
|---------------------|
| 作用:限制容器"不能抢"太多资源。 |
- 限制 CPU:规定这个容器只能用 0.5 个核,超了就慢下来。
- 限制内存:规定只能用 512MB 内存,超了就杀掉(OOM)。
- 类比:配额水表/电表。虽然大家住同一栋楼,共用一个水管,但给你的房间装了智能水表,超过配额就断水,防止你一个人把整栋楼的水都用光。
- 场景:你可以限制某个容器最多只能用 10% 的 CPU,或最多用 512MB 内存。如果超了,系统会把它杀掉,保证不影响宿主机和其他容器。
- UnionFS(联合文件系统)& chroot------ 实现"写时复制" (Copy-on-Write) "文件"隔离
|---------------------|
| 作用:给容器一个独立的"系统盘"。 |
- 问题:镜像(Image)是只读的,那容器里产生的日志、修改的文件存在哪?
- 机制:Docker 会在只读的镜像层之上,盖一层薄薄的 "读写层" (Writable Layer)。
- 原理:
- 读文件:直接读底层的镜像。
- 写文件:当你在这个"只读"文件上写字时,Docker 会瞬间把这个文件复制一份到顶部的"读写层",你修改的其实是这个副本。
- 结果:底下的镜像永远不会被破坏。容器一删,这层"读写层"就丢了,数据也就没了(所以要用数据卷 Volume 来持久化)。
换句话说
chroot / pivot_root:它可以把某个进程的"根目录"锁定在指定文件夹里(比如 /var/lib/docker/overlay2/xxx)。在这个进程看来,这个文件夹就是它的 /(根目录),它永远走不出这个圈。
UnionFS:它把只读的镜像层和可读写的容器层"联合"挂载在一起,形成一个完整的文件系统给容器看。
- 类比:全息投影的房间。
- chroot 就像把你关进了一个空房间,锁上门,你出不去。
- UnionFS 就像是在这个空房间里,用全息投影投射出了家具、墙纸(镜像层)。你看着很真实,也可以在里面画画(读写层),但其实你并没有真的改变这个房间的结构。
2.2.3 为什么需要"写时复制" (Copy-on-Write)?
- 问题:镜像(图纸)是不能改的,那我在容器(房间)里产生的垃圾(日志)或者新买的家具(新文件)放哪?
- 机制:Docker 会在只读的镜像层上面,盖一层透明的"读写层"。
- 类比:描红纸。
- 底下的字帖(镜像)是不能涂改的。
- Docker 在字帖上蒙了一张透明的纸(读写层)。
- 你想改哪个字,就把它抄到透明纸上再修改。
- 你看上去是改了,其实底下的字帖完好无损。
- 后果:这张透明纸(容器)一扔,你修改的内容就全没了(除非你用了数据卷保存)。
++++总结++++
- Namespaces = 围墙(看不见外面)
- Cgroups = 限额(抢不到资源)
- UnionFS = 幻象(独立的文件环境)
(容器的唯一标识容器ID与镜像ID一样采用UUID形式表示,是由64个十六进制字符组成的字符串。
通过容器名称来代替容器ID引用容器。)
2.3 容器 vs 虚拟机 (VM):为什么 Docker 这么快?
- 比喻:
- 虚拟机:像是一栋大楼里,给每家每户都配了独立的水电站、独立的锅炉房(资源浪费)。
- 容器:像是一栋胶囊公寓,大家共享大楼的水电、地基(内核),但每个人住在自己的独立胶囊房间里(互不干扰)。
容器 vs 虚拟机 (VM)
- 虚拟机 (VM):
- 类比:独栋别墅。每家每户都有独立的地基、供暖系统(独立的操作系统内核)。
- 缺点:太重了,建起来慢(启动慢),占地面积大(占用内存大)。
- 容器 (Container):
- 类比:胶囊公寓。大家共享大楼的地基和供暖(共享宿主机内核)。
- 优点:轻便,拎包入住(秒级启动),省空间(占用内存小)。
2.4 容器的生命周期(Lifecycle)
容器是短暂的(Ephemeral)。设计理念是"用完即焚"。
- Created:刚造出来,还没跑。
- Running:正在干活。
- Paused:暂停(类似电脑睡眠)。
- Exited (Stopped):干完活了,或者报错退出了。注意:停止不等于删除,它的尸体(文件系统)还在。
- Deleted:彻底销毁,渣都不剩。
小结:
容器就是一个被隔离的进程,它利用 Namespace 欺骗视觉,利用 Cgroups 限制资源,利用 写时复制 来保护镜像。
小结
- 容器 = 镜像 + 读写层。
- 容器本质是隔离的进程。
- 容器比虚拟机轻量,是因为共享内核。
|---|
| |
- 了解Docker仓库基础知识(Repository)
3.1 什么是 Docker 仓库?
简单来说,仓库是集中存放镜像的地方。
- 生活类比:
- 代码界:如果镜像是代码,仓库就是 GitHub。
- 手机界:如果镜像是 APP,仓库就是 App Store(应用商店)。
- 物流界:如果镜像是货物,仓库就是 亚马逊/京东的大型物流中心。
3.2 核心概念辨析:Registry vs Repository
初学者经常搞混这两个词,它们虽然都叫"仓库",但层级不同。
3.2.1 Registry(注册中心)------ "大商场"
- 定义:存放很多个仓库的服务器。
- 例子:
- Docker Hub:Docker 官方运营的全球最大的 Registry。
- 阿里云容器镜像服务:阿里云搭建的 Registry。
- Google Container Registry:谷歌搭建的 Registry。
- 类比:Registry 就像是一个具体的 "沃尔玛超市" 或 "7-11 便利店"。
3.2.2 Repository(仓库)------ "货架"
- 定义:Registry 里的一个具体的项目,里面存放了同一种软件的不同版本(Tags)。
- 例子:
- nginx:这是一个仓库,里面有 nginx:latest、nginx:1.19、nginx:alpine 等不同版本的镜像。
- mysql:这是一个仓库,里面有 mysql:5.7、mysql:8.0 等。
- 类比:Repository 就像是超市里的 "薯片货架"。这个货架上全都是薯片(同一个软件),但是有原味、番茄味、黄瓜味(不同 Tag 版本)。
3.2.3 完整的镜像地址结构
当我们执行docker pull时,其实我们是再写一个完整的地址:
|------------------------------------------------------------------------------------------|
| Plain Text 【Registry 地址】/【项目组/用户名】/【Repository名】:【Tag】 例如:docker.io/library/nginx:latest |
- docker.io:Registry地址(默认是Docker Hub,通常省略)。
- library:项目组(官方镜像都在library组,通常省略)
- nginx:Repository名字(必须写)
- latest:标签(不写默认是latest)
3.3 仓库的分类
3.3.1 共有仓库(public)
- 代表:Docker Hub(hub.docker.com)
- 特点:任何人都可以拉取
- 场景:你需要下载Nginx、Redis、Python等基础软件时,直接去公有仓库拉取。绝大多数开源软件都托管在这里。
3.3.2 私有仓库(Private)
- 代表:
- 企业自建:使用Docker Registry镜像或Harbor软件自己搭建的Registry
- 云厂商托管:阿里云、腾讯云提供的私有镜像服务(通常要付费或有配额)
- 特点:只有通过认证(Login)的人才能拉取和推送
- 场景:公司开发的业务代码(比如"双11大促支付系统"),里面有商业机密,绝对不能传到公网。只能传到公司内网的私有仓库里,供公司内部服务器部署使用。
- docker三大核心组件(镜像、容器、仓库)之间的关系及工作流程

4.1 三个核心角色(Locations & Objects)
这张图被分为左右两个大框,分别代表了两个物理位置:
- 左边大框:本地(Local Host)
- 这里是你自己的电脑或服务器。
- 角色 A:镜像(Image):
- 位置:左上角。
- 比喻:它是 "模具" 或 "类"。它是静态的、只读的。它是用来创建容器的模板。
- 角色 B:容器(Container):
- 位置:左下角。
- 比喻:它是 "蛋糕" 或 "对象"。它是动态的、正在运行的。它是真正干活的程序实体。
- 右边大框:注册中心(Registry)
- 这里是远程服务器(如 Docker Hub 或 阿里云镜像仓库)。
- 角色 C:仓库(Repository):
- 位置:右侧灰色方块。
- 比喻:它是 "超市货架" 或 "代码仓库"。这里存放着各种打包好的镜像,供大家下载使用。
4.2 四个核心动作(Actions)
图中的箭头代表了数据流向,也对应了Docker最常用的四个命令:
4.2.1 拉取(pull)
- 路径:仓库(Registry)->镜像(image)
- 命令:docker pull nginx
- 含义:"进货"。
- 你从远程的仓库里,把别人做好的镜像下载到你本地的硬盘里
- 场景:场景:你要安装某个软件(如 MySQL),第一步就是去仓库把它拉下来。
4.2.2 推送(push)
- 路径:镜像(image)->仓库(Registry)
- 命令:docker push my-app:v1
- 含义:"发货"。
- 你在本地做好了自己的镜像,想分享给同事,或者存到服务器上备份,就把它上传到远程仓库。
- 场景:开发完代码,打包成镜像后,发布到公司的私有仓库里。
4.2.3 实例化/运行(run)
- 路径:镜像(image)->容器(Container)
- 命令:docker run nginx
- 含义:"做蛋糕"
- 利用本地的镜像(模具),创建一个运行中的容器(蛋糕)
- 关键点:这是一个1对N的关系。一个镜像可以启动无数个容器(就像一个模具可以做无数个一模一样的蛋糕)
- 场景:软件下载(pull)好了,现在要启动它开始服务。
4.2.4 提交(commit)
- 路径:容器(container)->镜像(image)
- 命令:docker commit<容器ID><新镜像名>
- 含义:"定型"
- 你进入容器里修改了配置文件、安装了新软件,现在的容器和原来的镜像不一样了。你想保存这个状态,就把它反向打包成一个新的镜像。
- 场景:你在一个基础 Ubuntu 容器里装好了 Java 和 Tomcat,想把它保存下来,下次直接用这个环境,不用再重装一遍。
- 注:虽然图里画了这个,但实际工作中我们更推荐用 Dockerfile 来构建镜像,而不是用 commit ,因为 Dockerfile 更透明、可维护。
4.3 总结串讲
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| "大家看这张图,它完美解释了 Docker 的工作流: 一切从右边的 仓库(Registry) 开始。我们通过 pull (拉取) 命令,像逛超市一样把需要的软件镜像下载到 本地(Local)。 拿到 镜像(Image) 后,它是静态的,不能直接用。我们需要通过 run (运行) 命令,把它变成一个活生生的 容器(Container),这时候服务才真正跑起来。 如果我们在容器里修修补补,想保存劳动成果,可以用 commit (提交) 命令把它变成一个新的镜像。 最后,为了防止本地硬盘坏了丢失数据,或者为了分发给其他同事,我们通过 push (推送) 命令,把这个新镜像上传回远程 仓库。 这就是 Docker 的生命周期循环。" |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 由于怕初学者绕晕,这里开一个小知识点 * 镜像分类 * 操作系统:ubuntu, centos, alpine(基础底座)。 * 数据库:mysql, redis, mongo, postgres。 * 中间件:nginx, tomcat, rabbitmq。 * 应用软件:wordpress, jenkins, gitlab。 这四类(操作系统、数据库、中间件、应用软件)指的是 镜像的类型(分类),但它们存放在仓库里。 在 Docker 命令里,我们常说"去仓库拉个 Nginx"。 * 这句话严谨的翻译是:去 Docker Hub(注册中心) 的 library/nginx(仓库/货架) 里,拉取 nginx:latest(镜像/商品)。 |
- 命令详解
5.1 镜像基本信息与查看(实战)
5.1.1 镜像基本信息与查看实战
- 查看本地镜像列表
|--------------------------------------------------------|
| Plain Text 操作命令: [root@docker_dev ~]# docker images |
|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| Plain Text 输出示例: REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest a8780b506fa4 4 weeks ago 77.8MB hello-world latest feb5d9fea6a5 14 months ago 13.3kB |
- 输出字段详解
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| * REPOSITORY(仓库源): * 表示这个镜像是什么软件。例如 ubuntu 表示这是一个 Ubuntu 操作系统的镜像,redis 表示这是 Redis 数据库的镜像。 * TAG(标签): * 表示镜像的版本。例如 latest(最新版)、18.04、alpine 等。 * 知识点:REPOSITORY:TAG 共同构成了一个完整的镜像名(如 ubuntu:latest)。如果只写 ubuntu,Docker 默认去找 ubuntu:latest。 * IMAGE ID(镜像 ID): * 核心身份:这是镜像的全球唯一身份证号。 * 格式:它是一个 SHA256 哈希值,全长 64 个十六进制字符(为了方便显示,通常只截取前 12 位,如 a8780b506fa4)。 * 作用:当你对同一个镜像打不同的 Tag 时(比如把 my-app:v1 改名为 my-app:latest),它们的 Image ID 是一样的,说明它们本质上是同一个文件。 * CREATED(创建时间): * 镜像被打包构建的时间(注意:不是你下载的时间,是官方发布这个版本的时间)。 * SIZE(大小): * 镜像占用的逻辑大小。 * 注意:由于镜像有"分层共享"机制,如果你有 10 个镜像,它们加起来的 SIZE 显示是 5GB,但实际占用的硬盘空间可能只有 2GB(因为它们共用了底层的 Debian 系统层)。 |
- 如何引用一个镜像?
在使用 Docker 命令(如运行、删除)时,我们有三种方式来指定一个镜像:
- 使用完整名称:ubuntu:latest(推荐,最清晰)
- 使用镜像 ID:a8780b506fa4(精确,只要输入前几位能区分即可,不用输全)
- 使用摘要值 (Digest):一种更长、更精确的哈希值(通常用于自动化脚本,手动操作很少用)。
5.1.2 镜像描述文件Dockerfile---镜像的图纸
既然镜像是分层的,那这些层是怎么堆叠起来的呢?这就需要提到 Dockerfile。
- 定义:Dockerfile 是一个文本文件,它就像一张施工图纸。
- 作用:它包含了一系列指令,告诉 Docker 引擎:"第一步装系统,第二步考文件,第三步运行程序......",Docker 照着这张图纸,一步步把镜像构建(Build)出来。
- 举例 hello-world 为例
所有的 Docker 教程第一步都是运行 hello-world,我们看看这张图纸里写了什么
|-------------------------------------------------------|
| Plain Text FROM scratch COPY hello / CMD ["/hello"] |
- 行代码深度解析
- 第一行:FROM scratch
- 含义:从零开始。
- 深度解析:
- FROM 指令必须是第一行,它指定了基础镜像(Base Image)。通常我们会写 FROM ubuntu 或 FROM python。
- scratch 是 Docker 中一个特殊的、保留的空镜像。它里面什么都没有,连最基本的 Linux 命令行工具(ls, cd)都没有。
- 为什么要用它? 因为 hello-world 程序是用 C/Go 语言写好的二进制文件,它不需要操作系统环境就能直接在内核上跑。为了让镜像尽可能小(只有 13KB),所以用了这个空底座。
- 第二行:COPY hello /
- 含义:复制文件。
- 深度解析:
- COPY 指令的作用是把宿主机(你的电脑)里的文件拷贝到镜像里。
- 这句话的意思是:把当前目录下的 hello 可执行文件,复制到镜像的根目录 / 下。
- 第三行:CMD ["/hello"]
- 含义:默认启动命令。
- 深度解析:
- CMD 指定了当这个镜像变成容器并启动时,默认要干什么事。
- 这里的意思是:容器一启动,就执行根目录下的 /hello 程序。
- 这个程序执行完打印几行字后就会结束,所以容器也会随之停止(Exited)。
5.1.3 镜像常用操作命令(速查与实战)
在 Docker 中,管理镜像的命令通常以 docker image 开头,但为了方便,Docker 也提供了简写形式(如 docker pull)。建议大家在日常使用中优先记忆简写形式,效率更高。


5.2 容器操作常用命令(速查与实战)
容器是动态的,所以它的命令比镜像更多,涵盖了从"出生"到"死亡"的全过程。同样,我们推荐使用简写命令。
5.2.1 生命周期管理(生与死)

5.2.2 状态查询与交互(看与管)

点击图片可查看完整电子表格
5.2.3 文件与备份(存与取)

5.2.4 进阶操作(老司机必备)


这里需要补充辨析一下:
docker exec vs docker attach(面试常问)
- docker exec (推荐):
- 像是给房间新开了一扇后门进去。
- 你进去做了什么,不会影响房间里原本正在干活的人。
- 你退出(exit)时,房间里的人继续干活,容器不会停。
- docker attach (不推荐):
- 像是直接夺舍了房间里正在干活的那个人。
- 你和它是同一个视线。
- 你按 Ctrl+C 结束,那个人也就死了,容器会挂掉。
5.3 学会Docker注册中心的建立和使用
5.3.1 基于容器快速搭建本地Registry
|-----------------------------------------------------------------------------------------------------------------------------------------------------|
| Plain Text 1启动Registry容器 docker run -d -p 5000:5000 \ --restart=always \ --name myregistry \ -v /opt/data/registry:/var/lib/registry \ registry |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| * registry:这是Docker官方提供的"仓库服务"镜像,虚拟一个迷你版Docker Hub。 * -p 5000:5000:把一台机器的5000端口映射到容器内部的5000端口,以后的访问http://宿主机IP:5000就是在访问这个仓库。 * --restart=always:开机自动重启,避免服务器重启后仓库忘记启动。 * -v /opt/data/registry:/var/lib/registry:把镜像数据持久化到下一机/opt/data/registry,防止容器掉掉后仓库数据丢失。 |
|----------------------------------------------------------------|
| Plain Text 2验证注册表是否工作正常 curl http://127.0.0.1:5000/v2/_catalog |
|-----------------------------------------------------------------------------------------------------------------|
| * 如果是新建的仓库,返回:{"repositories":[]}表示当前还没有任何仓库。 * 稍后上传镜像后,这里会推出类似{"repositories":["hello-world"]}的内容 |
|-------------------------------------------------------------------------------------------------------------------------------------------|
| 127.0.0.1 什么? * 127.0.0.1是标准的Loopback地址,又叫localhost,永远指向"本机"。 * 无论你的主机真实IP是192.168.1.100还是10.0.0.5,访问127.0.0.1都表示"访问自己"。 |
5.3.2 向自建注册中心主动镜像
|------------------------------------------------------------------------------|
| Plain Text 1给镜像打标签(tag) docker tag hello-world 127.0.0.1:5000/hello-world:v1 |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 为什么要改名字? * Docker通过镜像中的另一项判断要推到哪一个仓库。 * hello-world→ 默认指向 Docker Hub。 * 127.0.0.1:5000/hello-world:v1→ 明确告诉 Docker:目标是本机 5000 端口上的Registry。 |
|-------------------------------------------------------------------|
| Plain Text 2自适应镜像(push) docker push 127.0.0.1:5000/hello-world:v1 |
|----------------------------------------|
| 第一个动作时,终端会显示分层上传的日志,最后出现的Pushed字样表示成功。 |
|------------------------------------------------------------|
| Plain Text 再次验证仓库内容 curl http://127.0.0.1:5000/v2/_catalog |
|------------------------------------------------------------------------------|
| * 现在应该看到:{"repositories":["hello-world"]},说明你的仓库仓库里已经有一个名为hello-world的仓库了。 |
5.3.3 从自建注册中心拉取镜像
在同一台机器上测试拉取(或者在交换机内的其他主机上,只需把IP换成本机IP):
|------------------------------------------------------|
| Plain Text docker pull 127.0.0.1:5000/hello-world:v1 |
|------------------------------------------------------------------------------------------------------|
| * 终端会显示Pulling from hello-world,并拉取成功。 * 说明您的本地Registry→push/pull整个仓库已经打通,可以作为后续企业仓库章节的基础示例 |
5.4 综合实战演练:从拉取到运行的全流程
这一节我们将通过一个真实的任务,把前面学到的命令全部串联起来。请打开你的终端,跟随以下 8 个步骤操作。
5.4.1 拉取镜像------进货
我们要运行一个Nginx网页服务器。首先,去Docker Hub进货。
狂欢
docker pull nginx:latest
- 现象:屏幕会出现下载资料条,显示Pulling fs layer,最终显示Status: Downloaded newer image for nginx:latest。
5.4.2 显示本地的镜像列表------盘点库存
确认货还没到。
docker images
- 预期结果:你应该能在列表中看到nginx,标签为latest。
5.4.3 查看镜像的建设历史 ------ 查验说明书
看看这个 Nginx 镜像是怎么做出来的。
docker history nginx:latest
- 预期结果:你会看到很多行记录,每一行代表 Dockerfile 中的一个指令(如 CMD、EXPOSE、COPY),展示了分层构建的过程。
5.4.4 启动容器并让其以守护进程的形式在后台运行后台运行 ------ 开工生产
这是最关键的一步。我们要启动Nginx,让在后台匿名工作( -d),并将其80端口暴露出来。
docker run -d --name my-nginx -p 8080:80 nginx:latest
- 命令解析:
- -d:后台运行。
- --name my-nginx:给容器起名叫my-nginx。
- -p 8080:80:把电脑的8080端口映射到容器的80端口。
- 验证:打开浏览器访问http://localhost:8080,你应该能看到"Welcome to nginx!" 的页面。
5.4.5 显示容器列表------查岗
看看刚才启动的容器状态不正常。
docker ps
- 预期结果:看到一条记录,状态显示Up X seconds,说明它活得好好的。
5.4.6 获取容器的日志信息------听它说话
如果网页打不开,我们需要看日志排错。
docker logs my-nginx
- 预期结果:你会看到 Nginx 的启动日志,或者刚才浏览器访问时留下的访问记录(Access Log)。
5.4.7 进入容器------进厂维修
假设我们修改 Nginx 的首页文字,需要钻容器进里。
狂欢
docker exec -it my-nginx /bin/bash
- 现象:你的命令行提示符会变(通常变成root@容器ID:/#容器),说明你已经进入内部了。输入ls可以看到容器里的文件。输入exit退出。
5.4.8 删除集装箱------清理现场
任务结束,装载。
# 1. 先停止
docker stop my-nginx
# 2. 再删除
docker rm my-nginx
- 注意:如果不先停止,直接rm会报错(否则-f加强制删除)。删除后,用docker ps -a确认集装箱已经消失。
恭喜!做完这8步,你已经掌握了Docker最核心的操作闭环。