Docker 笔记(一)
前言
我对于docker一直有断断续续的使用,但仅限于用 docker hub 寻找漏洞环境,简单的拉取和使用,搭起来博客之后,想来多少应该写点什么,正好在学校“坐牢”的日子里有云计算的大佬玩 k8s 引起一些兴趣,同时有重头系统的学习一些知识的打算,便决定从 docker 的使用开始,顺便搭几个靶场环境,方便学习。
最重要的是做一些简单的摘抄和记录,以供后面翻阅参考,摆脱之前东一榔头西一棒槌的学习模式。接下来记录的内容中有关 Docker 的,主要是 Docker-从入门到实践 的内容,外加其他一些博客等,此外感谢给予指导的大佬们的支持。
Docker 的简单介绍
Docker 是一个开源的应用容器引擎,基于 Go语言开发,使用Linux内核相关技术,对进程进行分装隔离,属于操作系统层面的虚拟化技术,应用了沙箱的机制,相互之间没有任何接口。
Docker 的三个基本概念
镜像(Image)
Docker 镜像是一个特殊的文件系统包含一些为运行准备的配置参数,但不包含任何动态数据,其内容在构建之后也不会被改变。
镜像的多层特性
严格来说,Docker 镜像并不是 ISO 那样的打包文件,而只是一个虚拟的概念,是由一组文件系统在多层上联合组成。Docker 镜像在构建时会一层层构建,前一层是后一层的基础。每一层构建完成后就不会再改变,哪怕是对上一层进行删改,也仅仅只是在当前层进行标记。
也就是说每一层在确定构建完全之前,一定要确认只包含了必要的东西。
镜像的体积
docker 镜像的体积,在仓库中一般显示的是压缩后的大小,而拉取到本地后检视的则是展开的大小。值得注意的是,由于 Docker 镜像是多层存储结构,并可以继承、复用,因此不同镜像可以使用相同的基础镜像,这样一来显示镜像占用的硬盘大小的总和一般比实际要小的多。
要想列出已经下载下来的镜像,可以使用 docker image ls
命令。列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间。
运行命令出现镜像仓库名和标签均为 <none>
的情况,这是虚悬镜像 (dangling image) ,可以使用 docker image ls -f dangling=true
来查看,一般这种镜像是因为,官方对镜像进行了维护,镜像名被转移到新的镜像去了,可以使用命令 docker image prune
删除。
中间层镜像
中间层镜像可以加速构建重复利用资源,命令 docker image ls
默认只会显示顶层镜像,如果希望显示可以加 -a
参数。使用后可以看到许多无标签的镜像,但与虚悬镜像不同,不可以随意删除,因为中间层镜像是别的镜像的依赖,同时相同的层在 Docker 中只会保存一遍,对空间占用影响不大。
删除镜像时的两个行为
删除本地的镜像,使用 docker image rm
命令,Docker 镜像的删除行为分两类:
- Untagged 取消标签
- Deleted 删除镜像
前面我们知道了,镜像是分层的,而且中间层可以被多个镜像使用。所以在进行删除行为时,会先从上层向基础层依次取消每层的标签,并判断取消后没有其他标签后才会执行删除。也就是说并非所有的 docker image rm
都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。
除镜像的依赖之外,还要注意有没有容器对要删除的镜像有依赖,毕竟容器是以镜像为基础,再加一层容器存储层去运行的。
镜像的构成与定制
Dockerfile 文件
Dockerfile 文件中包含一条条指令,文件用来构建镜像,每一条构建一层。
通过 FROM
指定一个基础镜像,并且必须是第一条指令,有一个特殊镜像 scratch
,这个镜像是虚拟的概念,表示空白。
通过 RUN
来执行命令,有 shell 格式 RUN <命令>
和 exec 格式 RUN ["可执行文件", "参数1", "参数2"]
这种更像是函数调用的格式。值得注意的是,执行命令每一条就代表构建一层镜像,构建命令时可可以用 &&
来串联起多条语句,同时最后一定要进行清理无关文件等操作。
|
|
commit 与 build 构建命令
命令 docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
用来生成黑箱镜像,也就是将容器的存储层保存下来成为镜像,但这种方法只适用于入侵后保存现场等特殊情况,因为他不像使用 Dockerfile 文件进行构建,容器内执行过什么命令进行过什么操作没有直观记录,而且容器内的修改调试,有大量重复臃肿的内容,通过 commit 构建之后,不仅大小会大很多,而且因为具体操作不清晰,对后期的维护十分不便。
命令 docker build [选项] <上下文路径/URL/->
可以使用 Dockerfile 文件来构建镜像, 最后的上下文路径要注意,为相对路径,一般来说,把需要构建入镜像的文件放到 Dockerfile 所在目录,用 .
表示为当前目录。docker build
还支持从 URL 构建,比如通过 Git repo、压缩包等。
容器(Container)
在 Docker 中,镜像与容器的关系,镜像是静态的定义,容器是镜像运行时的实体。容器的实质是进程,这里有一个新的名词“命名空间”。在容器进程运行时属于自己的独立的命名空间。
命名空间是Linux内核的一项功能,可以对内核资源进行分区,以便一组进程看到一组资源,而另一组进程看到另一组资源。
同样的,容器也是分层存储的,在运行时,以镜像为基础层,在其上创建容器存储层。容器存储层的生存周期和容器一样,容器消亡时也随之消亡。最好来说,容器存储层要保持无状态化,也就是不写入任何数据。所有的文件操作,都应该使用数据卷或绑定宿主目录,在这些位置操作会跳过容器存储层。
数据卷 (Volume) 的生存周期独立于容器,容器消亡,数据卷不会消亡。
容器的启动-运行-终止
仓库(Repository)
Docker Registry 是一个集中存储、分发镜像的服务。一个 Docker Registry 中可以包含多个仓库 (Repository);每个仓库有多个标签 (Tag);每个标签对应一个镜像。通过格式 <仓库名>:<标签> 来指定具体这个软件的那个版本的镜像。latest 为默认标签。
有官方和第三方提供的免费或者收费相关服务,也可以通过 Docker 官方提供的镜像,在本地搭建私有 Docker Registry。
使用 Docker 镜像