基本概念
三个基本概念
- 镜像Image
- 容器Container
- 仓库Repository
关于镜像:
- 不包含任何动态数据,其内容在构建后不会改变
- 多层文件
关于容器:
- 和镜像相当于是类和实例的关系
- 容器存储层不写入任何数据,文件写入操作应使用数据卷
- 数据卷的生存周期独立于容器
关于仓库:
- Repository:Tag 的形式,若不给出标签,将以 latest 作为默认标签
安装及配置
安装Docker
brew cask intall docker
配置加速器
由于访问较慢,国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。
Mac 10.10.3以上直接用Docker for Mac配置加速器,用了阿里云的镜像站点
尝试着运行一个Nginx服务器
docker run -d -p 80:80 –name webserver
nginx
由此可以看出分层存储的概念,下载也是一层层的下载,而非单一文件。下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。
访问localhost
没有出错,停止服务器并删除docker stop webserver
docker rm webserver
使用镜像
Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker 会从镜像仓库下载(默认是 Docker Hub 公共注册服务器中的仓库)
获取镜像
从 Docker Hub 上可获取大量高质量镜像
从 Docker Registry 获取镜像命令 docker pull
docker pull –help
查看用法
Docker Registry地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
仓库名:如之前所说,这里的仓库名是两段式名称,既 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。
获取一个最新版本的ubuntu镜像docker pull ubuntu
上面的命令中没有给出 Docker Registry 地址,因此将会从 Docker Hub 获取官方镜像 library/ubuntu 仓库中最新版本的镜像。
使用容器
用刚才下载的ubuntu镜像来启动一个容器docker run -it –rm ubuntu bash
docker run
: 运行容器的命令–it
: 这是两个参数,一个是-i
交互式操作,一个是-t
终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。–rm
:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动docker rm
。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用–rm
可以避免浪费空间ubuntu
:用ubuntu
镜像为基础来启动容器bash
:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是bash
列出镜像
docker images
- 镜像体积:Docker Hub中显示的体积是压缩后的体积,在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 docker images 显示的是镜像下载到本地后,展开的大小
由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。
- 虚悬镜像:由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为
的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image),一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的 - 中间层镜像:为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像,并且相同的层只会存储一遍
- 列出部分镜像:过滤器参数
–filter
,或者简写-f
,用于筛选镜像。–format
格式化筛选镜像
定制镜像
用nginx镜像启动一个容器并命名为webserverdocker run –name webserver -d -p 80:80 nginx
-d:以守护进程方式运行(后台)
-p < HOT_PORT > : < CONTAINER_PORT >:指定端口号
可在localhost访问nginx主页
若想修改主页内容,则docker exec -it webserver bash
我们修改了容器的文件,即修改了容器的存储层
通过docker diff webserver
查看具体的改动
若要用commit方式保存为镜像则docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像。所以,慎用 docker commit
使用 Dockerfile 定制镜像
Dockerfile的实质是一个脚本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
在一个空白目录中,建立一个文本文件,并命名为 Dockerfile
空白目录非常重要,因为上下文所在的整个文件夹(包括子文件夹)是会被打包上传到docker server的。看的时候一直不明白上下文是什么意思,查了官方文档,原话是这样的。
it’s best to start with an empty directory as context and keep your Dockerfile in that directory. Add only the files needed for building the Dockerfile.
这里的上下文也就是context
Dockerfile的内容为
FROM
:指定基础镜像。scratch
表示空白镜像RUN
:执行命令。
RUN执行命令的两种格式:
- shell 格式:
RUN <命令>
- exec 格式:
RUN [“可执行文件”, “参数1”, “参数2”]
每一次 RUN
都会建立一层,所以如果用shell格式,要用 &&
将各个所需命令串联起来,可用 \
命令换行使代码易读。在镜像构建时,一定要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉。
构建镜像
docker build [选项] <上下文路径/URL/->
运行一下容器看一下是否出错
其他 docker build 的用法
- 直接用 Git repo 进行构建
- 用给定的 tar 压缩包构建
- 从标准输入中读取 Dockerfile 进行构建
- 从标准输入中读取上下文压缩包进行构建