Docker 学习笔记
Docker 学习笔记
Docker 的基本组成
Docker 引入了三个名词:镜像、容器和仓库。
镜像(image):
docker 镜像相当于一个模版,可以通过模版来创建容器,需要的服务就是在容器中运行的。
容器(container):
docker 利用容器技术,独立运行不同的服务。容器包含启动、停止、删除等基本命令。
仓库(repository):
仓库就是存放镜像的地方。
Docker run的运行流程图

Docker 的常用命令
帮助命令
1 | docker version # 显示docker的版本信息 |
官方文档: https://docs.docker.com/reference/cli/docker/
镜像命令
- docker images
1 | docker images # 查看本机上所有镜像 |
- docker search
1 | docker search 镜像 # 搜索镜像 |
- docker pull
1 | docker pull 镜像名[:tag] # 下载镜像 |
- docker rmi
1 | docker rmi 镜像名/镜像id # 删除镜像 |
容器命令
说明:有了镜像才能创建容器,下载一个centos镜像以测试学习
1 | docker pull centos |
新建容器并启动
1 | docker run [可选参数] image |
列出所有运行的容器
1 | docker ps |
退出容器
1 | exit # 容器停止并退出 |
删除容器
1 | docker rm 容器id # 删除指定容器,不能删除正在运行的容器 |
启动和停止容器
1 | docker start 容器id # 启动容器 |
常用其他命令
后台启动容器
1 | docker run -d centos |
查看日志
1 | docker logs 容器id |
查看容器中的进程信息
1 | docker top 容器id |
查看容器的元数据
1 | docker inspect 容器id |
进入当前正在运行的容器
1 | 方式一: 进入容器后开启一个新的终端,可以在里面进行操作 |
从容器内拷贝文件到主机上
1 | docker cp 容器id:容器内路径 目的主机路径 |
Docker 镜像讲解
镜像是什么?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、库、环境变量和配置文件。
所有的应用,直接打包成docker镜像,就可以直接跑起来!
如何得到镜像:
- 从远程仓库下载
- 从网上拷贝
- 自己制作镜像 Dockerfile
Docker 镜像加载原理
UnionFS (联合文件系统)
docker pull 下载镜像时看到的一层层文件就是这个!
Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker 镜像的基础,镜像可以通过分层来进行继承,基于基础镜像可以制作各种具体应用的镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker 镜像加载原理
docker镜像实际由一层一层文件系统组成,这种层级的文件系统就是 UnionFS。
bootfs(boot file system) 就是内核引导器(引导加载内核)和内核。bootfs主要包含bootloader和kernel,bootloader主 要是引导加载kernel,Linux刚启 动时会加载bootfs文件系统。
rootfs 是 docker 容器在启动时内部进程可见的文件系统,即 docker 容器的根目录。当我们运行docker exec命令进入container的时候看到的文件系统就是rootfs。rootfs 通常包含一个操作系统运行所需的文件系统,例如可能包含典型的类 Unix 操作系统中的目录系统,如 /dev、/proc、/bin、/etc、/lib、/usr、/tmp 及运行 docker 容器所需的配置文件、工具等。
为什么docker中centos镜像的镜像那么小?
对于一个精简的操作系统,rootfs可以很小,只需要包含最基本的命令、工具和程序库就行了,底层直接使用主机的内核。对于不同的linux发行版,bootfs基本一致,rootfs会有差别,因此不同的发行版可以共用bootfs。docker中的centos镜像就相当于只下载的centos的rootfs,并公用底层内核。
Docker 分层
在下载镜像的时候,注意观察下载日志,可以看到镜像是一层一层下载的!
docker 为什么采用这种分层的结构呢?
最大的好处莫过于是资源共享!比如有多个镜像都是从相同的base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有容器服务了。
查看镜像分层的方式可以通过 docker image inspect 命令:
1 | docker image inspect redis:latest |
所有的 docker 镜像都起始于一个基础镜像层,当进行修改或添加内容时,就会在当前镜像层之上创建新的镜像层。
例如下图就是一个docker镜像一层一层的构建过程:
特点
Docker 镜像都是只读的,不可以被修改。当容器启动时,一个新的可写层会加载到镜像的顶部:
用户操作的这一层就是常说的容器层,容器层之下都叫镜像层!
commit 镜像
如果想要保存当前容器的状态,就可以通过commit进行提交,获得当前容器状态的一个镜像。
1 | docker commit和git基本一致 |
容器数据卷
什么是容器数据卷
容器数据卷(Docker Volumes) 是一种在 Docker 容器和宿主机(host)之间持久化数据的方法。它用于将数据存储在 Docker 容器之外,以便在容器重启、删除或创建新容器时,数据不会丢失。数据卷可以使容器与数据分离,从而让数据在容器生命周期之外得以持久化、共享和管理。
挂载
挂载(Mount) 是指将一个存储设备(如硬盘、U 盘、网络存储)或文件系统(如 Docker 数据卷)连接到操作系统的目录结构中,使其可以被访问和使用。简单来说,就是把存储设备的某个路径“挂”到系统中的一个目录下,让系统能够像操作本地文件一样操作它。
总结一句话:
挂载就是把一个存储(设备、目录、卷、网络存储)映射到某个目录,让它变得可用。
使用数据卷
1 | 方式一:直接使用命令来挂载 -v |
利用 docker inspect 容器id 查看容器如何进行挂载的:
source 为本机目录,destination 为容器内目录,两个目录是互相绑定的,数据同步。
具名和匿名挂载
1 | 匿名挂载 |
可以看到长长的 abc...
字符串就是匿名挂载。我们在 -v 处只写了容器内的路径,没有写容器外的路径
1 | 具名挂载 |
再次查看卷情况:
查看卷的位置:
1 | docker volume inspect juming-nginx |
所有的docker容器内的卷,在没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data
路径。
我们通过具名挂载可以方便地找到我们的一个卷,大多数情况下都使用具名挂载
1 | 如何确定是具名挂载、匿名挂载还是制定路径挂载 |
拓展:
1 | 通过 -v 容器内路径:ro rw 改变读写权限 |
初识 Dockerfile
Dockerfile 就是用来构建 docker 镜像的构建文件,相当于命令脚本。
通过这个脚本可以生成镜像,镜像是一层层的,脚本就是一个个的命令,每个命令都是一层。
1 | 创建一个dockerfile文件 |
输入docker volume ls,可以看到多了两个匿名挂载的数据卷。
数据卷容器
数据卷容器用于多个容器之间实现数据共享,用 –volumes-from 实现。
以下是一个示例:
1 | docker run -it --name=docker01 kuangshen/centos |
数据卷容器的生命周期一直持续到没有容器使用位置。
DockerFile
dockerfile 是用来构建docker镜像的文件,就是一个命令参数脚本。
构建步骤:
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(到dockerhub、阿里云镜像仓库等)
很多官方的镜像都是基础包,很多功能都没有,我们通常需要自己构建镜像。
DockerFile 构建过程
基础知识:
- 每个保留关键字(指令)都必须是大写字母
- 指令从上到下顺序执行
#
表示注释- 每一个指令都会创建提交一个新的镜像并提交

DockerFile 指令
1 | FROM # 引入基础镜像,一切从这里开始构建 |
利用 dockerfile 构建自己的个性化ubuntu
1 | 使用官方 Ubuntu 镜像作为基础镜像 |
dockerfile 写好后,利用 docker build -f dockfile文件路径 -t docker镜像名:版本号 .
构建镜像。
docker history
docker history 可以查看镜像是如何构建的,例如:
1 | docker history myubuntu |
CMD 和 ENTRYPOINT 的区别
1. CMD:设置默认的命令和参数
用途:CMD 用于为容器指定默认命令,并且可以提供默认参数。如果在运行容器时没有提供其他命令或参数,Docker 就会执行 CMD 指定的命令。
重写:如果在运行容器时提供了其他命令(如 docker run
),则 CMD 指定的命令会被重写。 常见用法:用来指定容器的默认命令,通常用于启动服务或进程。
1
CMD ["echo", "Hello, World!"]
这个 Dockerfile 中的 CMD 会在容器启动时执行 echo Hello, World!。如果没有指定其他命令,容器会执行 CMD 中的命令。
使用 docker run时:
1 | docker run <image> # 输出 "Hello, World!" |
2. ENTRYPOINT:指定容器的固定执行命令
用途:ENTRYPOINT 用于设置容器启动时执行的固定命令。它始终会被执行,无论你在 docker run 命令中是否指定了其他命令。
重写:ENTRYPOINT 指定的命令不能被重写(除非使用 –entrypoint 选项)。但是,你可以在 docker run 中提供其他参数,来作为 ENTRYPOINT 命令的参数。
常见用法:用来设置容器必须运行的命令,通常用于启动应用或服务。
1
ENTRYPOINT ["echo"]
这个 Dockerfile 中的 ENTRYPOINT 会在容器启动时执行 echo 命令。
使用 docker run 时:
1 | docker run <image> "Hello, World!" # 输出 "Hello, World!" |
3. CMD 与 ENTRYPOINT 结合使用
组合使用:你可以将 ENTRYPOINT 和 CMD 结合使用。在这种情况下,ENTRYPOINT 设置固定的命令,CMD 提供默认的参数。如果在运行容器时指定了其他参数,CMD 中的默认参数会被替换为新的参数。
1 | ENTRYPOINT ["echo"] |
使用docker run时:
1 | docker run <image> # 输出 "Hello, World!" |
Ps:
在 Dockerfile 中,CMD 和 ENTRYPOINT 只能有 一个。如果你在 Dockerfile 中写多个CMD 或 ENTRYPOINT 指令,只有最后一个 CMD 或 ENTRYPOINT 会生效,前面的会被忽略。
发布镜像
- 先登陆dockerhub
1 | docker login -u 用户名 |
输入密码后即可登陆成功。
docker push 镜像即可
注意镜像前必须带有自己的用户名,否则会被拒收。
更改镜像名后,发布成功。
也可以把镜像发布在阿里云镜像仓库中,详见阿里云官方文档。
Docker 小结
