简介
基本概念
- 镜像(Image)
- 容器(Container)
- 仓库(Repositroy)
基本概念
镜像
Docker镜像(Image): 相当于一个root
文件系统. 比如个官方镜像ubuntu:14.04
就包含了一套Ubuntu14.04最小系统的root
文件系统.
Docker镜像死一个特殊的文件系统, 除了提供容器运行时所需的程序, 库, 资源, 配置等文件外, 还包含了一些为运行时准备的一些配置参数(如匿名卷, 环境变量, 用户等). 镜像不包含任何动态数据, 其内容在构建之后不会被改变.
分层存储
利用Union FS
技术, 分层存储架构.
镜像构建时, 会分层构建, 前一层是后一层的基础. 每一层构建完毕后就不会发生变化. 比如删除一个前一层的文件操作, 实际不是真的删除前一层的文件, 而是仅在当前层标记为该文件已删除. 在最终容器运行的时候, 虽然不会看到这个文件, 但是实际上该文件会一直跟随镜像.
在构建镜像时, 需要额外小心, 每一层尽量只包含该层需要添加的东西, 任何额外的东西应该在该层构建结束前清理掉.
分层存储的特征还可以使得镜像复用, 定制的更为容易. 甚至可以用之前的构建好的镜像作为基础层, 然后进一步添加新的层.
容器
镜像(Image)和容器(Container)的关系, 就像面向对象的类
和实例
一样. 镜像是静态的定义, 容器是镜像运行时的实体. 容器可以被创建, 启动, 停止, 删除, 暂停等.
容器的实质是进程, 但与直接在宿主执行的进程不同, 容器进程运行于属于自己的独立的命名空间
. 因此容器可以拥有自己的root
文件系统, 自己的网络配置, 自己的进程弓箭, 甚至自己的用户ID控件. 容器内的进程是运行在一个隔离的环境里.
容器存储层的生存周期和容器一样, 容器消亡时, 容器存储层也随之消亡. 因此任何保存于容器存储层的信息都会随容器删除而消亡.
按照 Docker 最佳实践的要求, 容器不应该向其存储层内写入任何数据, 容器存储层要保持无状态化. 所有的文件写入操作, 都应该使用
数据卷(Volume)
. 或者绑定宿主的目录, 在这些位置的读写会跳过容器存储层, 直接对宿主(或网络存储)发生读写, 其性能和稳定性更高.
数据卷(Volume)的生命周期独立于容器, 容器消亡, 数据卷不会消亡.
仓库
镜像完成后很容易在当前宿主上运行, 但是, 如果需要其他服务器上使用这个镜像, 就需要一个集中存储, 分发镜像的服务, 即: Docker Registry
服务
一个 Docker Registry
中可以包含多个仓库 (Repository), 每个仓库可以包含多个标签 (Tag), 每个标签 (Tag) 对应一个镜像.
一般来说, 一个仓库 包含的是同一个软件的不同版本镜像, 而标签则用于对应于软件的不同版本. 可以通过仓库名:标签名
的格式来指定具体的一个镜像. 如果不给出标签值, 则将以latest
作为默认标签.
如,Ubuntu镜像
为例, Ubuntu
是仓库名, 仓库内有不同的版本, 使用标签14.04
, 16.04
作为标签名来表示不同的版本. 我们可以通过: Ubuntu:14.04
, Ubuntu:16.04
来指定具体某一个镜像, 如果忽略了标签, 则视为Ubuntu:latest
仓库名经常已两段式路径形式出现, 如
jwilder/nginx-proxy
, 前者为 Docker Registry 多用户环境下的用户名, 后则为软件名.
常用的 Docker Registry 服务有, Docker Hub
, CoreOS 的Quay.io
, Google 的 Google Container Registry
等.
自己可以搭建私有的 Docker Registry服务区. Docker 官网提供了 Docker Registry 镜像
, 可以直接使用作为私有 Registry服务.