柴少鹏的官方网站 技术在分享中进步,水平在学习中升华

Docker(一)介绍与镜像介绍

一、Docker内容介绍

1.1 云计算平台介绍

       云计算是一种资源的服务模式,该模式可以实现随时随地、便捷按需地从可配置计算资源共享池中获取所需的资源(如网络、服务器、存储、应用及服务),资源能够快速供应并释,大大减少了资源管理工作开销。

       经典云计算架构包括IaaS(Infrastructure as a Service,基础设施即服务)、PaaS(Platform-as-a-Service:平台即服务)、SaaS(Software as a Service,软件即服务)三层服务。下面是对这三种服务的介绍:

  1. IaaS层为基础设施运维人员服务,提供计算、存储、网络及其他基础资源,云平台使用者可以在上面部署和运行包括操作系统和应用程序在内的任意软件,无需再为基础设施的管理而分心。

  2. PaaS层为应用开发人员服务,提供支撑应用运行所需的软件运行时环境、相关工具与服务,如数据库服务、日志服务、监控服务等,让应用开发者可以专注于核心业务的开发。

  3. SasS层为一般用户服务,提供了一套完整可用的软件系统,让一般用户无需关注技术细节,只需通过浏览器、应用客户端等方式就能使用部署在云上的应用服务。

IaaS的发展主要以虚拟机为最小粒度的资源调度单位,出现了资源利用率低、调度分发缓慢、软件堆栈环境不统一等一系列问题。PaaS在IaaS基础上发展而来,众多PaaS已经意识到可以利用容器技术解决资源利用率问题,但是PaaS通常在应用架构选择、支持的软件环境服务方面有较大的限制,这带来了应用与平台无法解耦、应用运行时环境局限性强、运维人员控制力下降的问题。

1.2 什么是Docker?

什么是LXC? 链接地址:https://www.cnblogs.com/cherishui/p/4147240.html   #这篇博客介绍的很详细

       Docker是以Docker容器来资源分割和调度的基本单位,封装整个软件运行时的环境,为开发者和系统管理员设计,用于构建、发布和运行分布式应用的平台。它是一个跨平台、可移植并且简单易用的容器解决方案。Docker的源代码托管在GitHub上,基于Go语言开发并遵从Apache 2.0协议.Docker可在容器内容快速自动化地部署应用,并通过操作系统内核技术(namespaces、cgroups等)为容器提供资源隔离与安全保障。Docker是Docker.inc公司开源的一个基于LXC技术之上构建的Container容器引擎。

1.3 Docker生态系统

image.png

#上图为Docker生态系统。

      围绕Docker的生态系统,自下而上分别覆盖了IaaS层和PaaS层所涉及的各类问题,包括资源调度、编排、部署、配置管理、网络管理、应用开发和部署平台、应用开发工具、应用服务供应以及大数据分析等云计算相关的服务。Docker及其生态系统主要带来了以下几点好处:

  1. 持续部署与测试。 Docker消除了线上线下的环境差异,保证了应用生命周期的环境一致性和标准化。开发人员使用镜像实现标准开发环境的构建,开发完成后通过封装着完整环境和应用的镜像进行迁移,大大简化了持续集成、测试和发布的过程。

  2. 跨云平台支持。 Docker的最大好处之一就是其适配性、越来越多的云平台都支持Docker。目前支持Docker的IaaS云平台包括但不限于亚马逊云平台(AWS)、Google云平台(GCP)、微软云平台(Azure)、OpenStack等,还包括Chef、Puppet、Ansible等配置管理工具。

  3. 环境标准化和版本控制。 可以使用Git等工具对Docker镜像进行版本控制,一旦出现故障可以快速回滚。相比以前的虚拟机镜像、Docker压缩和备份速度更快,镜像启动也像启动一个普通进程一样快速。

  4. 高资源利用率与隔离。 Docker容器没有管理程序的额外开销,与底层共享操作系统,性能更加优良,系统负载更低,在同等条件下可以运行更多的应用实例,可以更充分地利用系统资源。同时,Docker拥有不错的资源隔离与限制能力,可以精确地对应用分配CPU、内存等资源,保证了应用间不会相互影响。

  5. 容器跨平台与镜像。 Linux容器虽然早在Linux 2.6版本内核已经存在,但是缺少容器的跨平台性,难以推广。Docker在原有的Linux容器的基础上进行大胆革新,为容器设定了一整套标准化的配置方法,将应用及其依赖的运行环境打包成镜像,真正实现了“构建一次,到处运行”的理念,大大提高了容器的跨平台性。

  6. 易于理解且易用。 一个开发者可以在15分钟之内入门Docker并进行安装和部署。

  7. 应用镜像仓库。 Docker官方构建了一个镜像仓库,组织和管理形式类似于GitHub,上面已经积累了成千上万的镜像。因为Docker的跨平台的适配性,相当于为用户提供了一个非常有用的应用商店,所有人都可以自由下载微服务组件。

1.4 Docker容器与传统虚拟机技术的不同之处

image.png

传统方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层。Docker容器是在操作系统层面上实现虚拟化,直接复用本机本地的操作系统,因此更加轻量级,性能方面也更加高效。Docker 从 0.9 版本开始使用 libcontainer 替代 lxc.

博文来自:www.51niux.com

1.5 Docker三大核心概念

镜像

       Docker镜像(image)类似于虚拟机镜像,可以将它理解为一个面向Docker引擎的只读模板,包含了文件系统。

       例如:一个镜像可以只包含一个完整的Centos操作系统环境,可以把它称为一个Centos镜像,镜像也可以安装了Nginx应用程序(或者用户需要的其他软件),可以把它称为一个Nginx镜像。

       镜像是创建Docker容器的基础,通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制(仓库)创建和更新现有镜像,用户可以从网上下载一个已经做好的应用镜像,并通过命令直接创建Docker容器来使用。

       Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会尝试先从默认镜像仓库下载(默认使用Docker Hub公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库。

容器

       Docker容器(Container)类似于一个箱子,可以把容器看做是一个简易的Linux系统环境(其中包括root用户权限,进程空间,用户空间和网路空间等),以及运行在其中的应用程序打包而成的一个箱子。Docker利用容器这个箱子来隔离和运行应用镜像。

       容器是从镜像创建的应用运行实例,可以对他进行启动,停止,删除等常规操作。这些不同的容器之间都是相互隔离互不可见的。镜像自身是只读的,容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身将保持不变。

仓库

       Docker仓库(Repostory)类似于代码的仓库(与svn、git、maven等概念类似)是Docker用来集中存放镜像文件的场所。

根据所存储的镜像是否公开分享,Docker仓库又分为:公开仓库和私有仓库。

       顾名思义,公开仓库就是公共开放的镜像存储的地方,目前最大的公开仓库是Dokcer Hub (registry.hub.docker.com),存放了大量的镜像可供下载使用,国内的公开仓库有aliyun(acs-public-mirror.oss-cn-hangzhou.aliyuncs.com)。私有仓库是内部使用的私有不对外开放的仓库,用户可以内部自行搭建,内部分享镜像,方便快捷的分享专属环境的镜像文件。

1.6 容器化思维

        如今已迈入互联网+的时代,各行各业更加广泛地与互联网技术结合,软件称为连接人与人、人与企业、企业与企业之间的桥梁,互联网+时代对应用开发迭代速度和质量有了更高的要求,开发者也渐渐由单纯的开发进入到开发、维护、发布的全过程之中(DevOps)。应用开发模式正在朝着微服务模式发展。所谓微服务模式有如下三大特性:

  1. 彼此独立。 微服务模式下的每一个组成部分,都是一个独立的服务。有一整套完整的运行机制以及标准化的对外接口。不依赖于其他部分就能正常运行,同时可以探测其他组成部分的存在。

  2. 原子化。 微服务应该是不可再分的原子化服务。如果一个服务还能继续划分为几个更小的服务,那便不能称为微服务,而更像是由多个微服务组成的“微系统”。

  3. 组合和重构。 微服务的最大特点就在于它能快速的组合和重构,彼此组合成一个系统。系统里所有的实体在逻辑上是等价的,因此它的结构相对简单和松散、具有极强的可扩展性和鲁棒性(健壮和强壮)。

       容器化思维就等同于微服务化思维,每个容器承载一个微服务,容器之间彼此独立正常运行,每个容器中只允许一个进程,容器间可以快速组合重构,形成一个更大的系统。所以使用Docker时需要关注容器本身,时刻提醒自己是在使用容器,享受它带来的种种便利,如快速的应用分发能力、高效的操作及反应能力、弹性灵活的部署能力以及低廉的部署成本;同时我们也要转变思维模式,学习和适应容器化的管理方式。容器的本质是一个系统进程加上一套运行时库的文件系统封装、而针对容器,我们需要监控、资源控制、配置管理、安全等。

二、Docker安装与简单部署

docker官网:https://www.docker.com/

官网文档:https://docs.docker.com/

2.1 Docker的安装

Docker安装的基本要求:

  1. Docker只支持64位CPU架构的计算机,目前不支持32位CPU.

  2. 建议系统的Linux内核版本为3.10及以上。

  3. Linux内核需开启cgroups和namespace功能。

  4. 对于非Linux内核的平台,如Microsoft Windows和OS X,需要安装使用Boot2Docker工具。

cgroups 是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制,可以对 cpu,内存等资源实现精细化的控制,下面是一个博客的介绍链接:http://blog.csdn.net/hzrandd/article/details/52484332

Namespaces(命名空间)机制提供一种资源隔离方案,介绍链接:https://www.cnblogs.com/cherishui/p/4237883.html

Docker的安装:

# cat /etc/redhat-release 

CentOS Linux release 7.2.1511 (Core)

#yum install docker -y   #CentOS7系统,CentOS-Extras源中已内置Docker,安装就是这么一条......

# docker --version  #查看docker版本

Docker version 1.12.6, build 85d7426/1.12.6

# service docker start   #启动docker服务

# docker run hello-world   #测试一下

Unable to find image 'hello-world:latest' locally
Trying to pull repository docker.io/library/hello-world ... 
latest: Pulling from docker.io/library/hello-world
9a0669468bf7: Pull complete 
Digest: sha256:0e06ef5e1945a718b02a8c319e15bae44f47039005530bc617a5d071190ed3fc

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

#上面是执行成功了,说本地没有hello-world:latest的镜像,去下载了一个镜像,说明网络没有问题。

Docker的操作参数:

用户在使用Docker时,需要使用Docker命令行工具docker与Docker daemon建立通信。Docker daemon是Docker守护进程,负责接收并分发执行Docker命令。

# docker --help  #查看操作参数

用法:
docker [OPTIONS] COMMAND [arg...]
docker [ --help | -v | --version ]
选项:
--config=~/.docker       #客户端配置文件的位置
-D, --debug              #启动调试模式
-H, --host=[]            #守护进程套接字(s)连接到
-h, --help               #打印帮助
-l, --log-level=info     #设置日志记录级别
--tls                    #使用TLS;implied by --tlsverify
--tlscacert=~/.docker/ca.pem     #仅由此CA签署的信任证书
--tlscert=~/.docker/cert.pem     #TLS证书文件的路径
--tlskey=~/.docker/key.pem       #TLS密钥文件的路径
--tlsverify                      #使用TLS并验证远程
-v, --version                    #打印版本信息并退出
命令:
attach       #附加到正在运行的容器
build        #从Dockerfile构建一个镜像
commit       #从容器的更改中创建一个新的镜像
cp          #在容器和本地文件系统之间复制文件/文件夹
create      #创建一个新的容器
diff        #检查容器文件系统上的更改
events      #从服务器获取实时事件
exec        #在正在运行的容器中运行命令
export      #将容器的文件系统导出为tar存档
history     #显示镜像的历史
images      #镜像列表
import      #从tarball中导入内容以创建文件系统映像
info        #显示系统环境信息
inspect     #检查返回容器,镜像或任务的低级信息
kill        #杀死一个或多个正在运行的容器
load        #从tar归档或STDIN加载镜像
login       #登录到Docker镜像库。
logout      #从Docker镜像库中注销。
logs        #获取容器的日志
network     #管理Docker网络
node        #管理Docker Swarm节点
pause       #暂停一个或多个容器内的所有进程
port        #列出端口映射或容器的特定映射
ps          #容器列表
pull        #从镜像库中拉出镜像或存储库
push        #推送镜像或存储库到镜像库
rename      #重命名一个容器
restart     #重启一个容器
rm          #删除一个或多个容器
rmi         #rmi删除一个或多个镜像
run         #在新容器中运行命令
save        #将一个或多个镜像保存到tar归档文件(默认流式传输到STDOUT)
search      #在Docker Hub中搜索镜像
service           #管理Docker服务
start       #动一个或多个停止的容器
stats      #信息显示容器资源使用的实时统计信息
stop      #停止一个或多个运行容器
swarm     #管理Docker Swarm
tag       #将镜像标记到存储库中
top       #显示容器的运行过程
unpause   #暂停取消暂停一个或多个容器内的所有进程
update    #更新一个或多个容器的配置
version   #显示Docker版本信息
volume    #管理Docker卷
wait      #阻塞直到容器停止,然后打印其退出代码

#对单个子命令执行help可以查看此子命令的详细用法,如下面对rm执行查看:

# docker rm --help

Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]
Remove one or more containers
Options:
  -f, --force     Force the removal of a running container (uses SIGKILL)
      --help      Print usage
  -l, --link      Remove the specified link
  -v, --volumes   Remove the volumes associated with the container

根据命令的用途进行分类:

子命令分类子命令
Docker环境信息info、version
容器生命周期管理create、exec、kill、pause、restart、rm、run、start、stop、unpause
镜像仓库命令login、logout、pull、push、search
镜像管理build、images、import、load、rmi、save、tag、commit
容器运维操作attach、export、inspect、port、ps、rename、stats、top、wait、cp、diff
系统日志信息events、history、logs

Docker命令的结构图,如下图:

image.png

博文来自:www.51niux.com

三、Docker 镜像介绍

3.1 什么是Docker镜像?

详解链接:http://www.infoq.com/cn/articles/analysis-of-docker-file-system-aufs-and-devicemapper/        

        Docker镜像含有启动Docker容器所需的文件系统结构及其内容,因此是启动一个Docker容器的基础。Docker镜像采用分层的结构构件,最底层是bootfs,之上的部分是roofs,其租住结果如下图:

image.png

boofs:

      bootfs是Docker镜像最底层的引导文件系统,包括bootloader和操作系统内核,类似于传统的Linux/Unix引导文件系统。然而,Docker用户很少有机会直接与bootfs打交道,并且在容器启动完毕之后,为了节省内存空间,bootfs将会被卸载。

rootfs

      rootfs位于bootfs之上,是Docker容器在启动时内部进程可见的文件系统,即Docker容器的根目录。rootfs通常包含一个操作系统运行所需的文件系统,例如可能包含典型的类Unix操作系统中的目录系统,如/dev,/tmp等及运行Docker容器所需的配置文件、工具等。

      在Docker的架构中,当Docker daemon为Docker容器挂载rootfs时,沿用了Linux内核启动时的方法,即将rootfs设置为只读模式。在挂载完毕之后,利用联合挂载(union mount)技术在已有的只读rootfs上再挂载一个读写层。这样,可读写层处于Docker容器文件系统的最顶层,其下可能联合挂载多个读写层,并隐藏只读层中的老版本文件,这样的技术被称为写时复制(Copy On Write)。联合挂载技术可以在一个挂载点同时挂载多个文件系统,将挂载点的原目录与被挂载内容进行整合,使得最终可见的文件系统将会包含整合之后的各层的文件和目录。

image.png

#如上图,实现这种联合挂载技术的文件系统通常被称为联合文件系统(union filesystem)。由于初始挂载时读写层为空,所以从用户的角度看,改容器的文件系统与底层的rootfs没有差别。当需要修改镜像内的某个文件时,只对处于最上方的读写层进行了变动,不覆盖下层已有文件系统的内容,已有文件在只读层中的原始版本仍然存在,但会被读写层中的新文件所隐藏,当docker commit这个修改过的容器文件系统为一个新的镜像时,保存内容仅为最上层读写文件系统中被更新过的文件。

3.2 镜像的存储组织方式

image.png

#上图是一个完整的、在运行的容器的所有文件系统结构的描述。上图体现了镜像的层级结构,里面有volume、init-layer、可读写层这些概念。可读写层(read-write Layer以及volume)、init-layer、只读层(read-only layer)这3层结构共同组成一个容器所需的下层文件系统,他们通过联合挂载的方式巧妙的表现为一层,使得容器进程对这些层的存在一点都不知道。

#Docker镜像系统实际分成了分多层,任何一层和它直接或间接依赖的所有层构成一个镜像。镜像分层机制提供的复用特性使得存储一个新的镜像时只需要保存修改的内容而不是全部文件。

3.3 镜像关键概念

registry

      每个docker容器都将从Docker镜像生成。registry用以保存Docker镜像,其中还包括镜像层次结构和关于镜像的元数据,可以将registry理解为类似于Git仓库之类的实体。

      除了使用官方的公用registry(即Git Hub),它是由Docker公司维护的一个公共镜像仓库,其中包含了超过45000个公共镜像,供用户下载使用。Docker Hub中有两种类型的仓库,及用户仓库(user repository)与顶层仓库(top-level repository)。用户仓库由普通的Docker Hub用户创建,顶层仓库由Docker公司负责维护,提供官方版本镜像。理论上,顶层仓库中的镜像经过Docker公司验证,被认为是架构良好且安全的。

repository

       repository即由具有某个功能的Docker镜像的所有迭代版本构成的镜像库。registry由一系列经过命名的repository组成,可以通过命名规范对用户仓库和顶层仓库进行区分。用户仓库的命名由用户名和库名两部分组成,中间以"/"隔开,即username/repository_name的形式,库名通常表示镜像所具有的功能,如:centos7-ansible ;而顶层仓库则只包含库名的部分,如:centos(可以通过#docker search centos来查看)。

      registry是repository的集合,repository是镜像的集合。

index

       registry负责存储和提供真正的镜像,而index则类似于registry的索引,负责管理用户账号、访问权限认证、搜索镜像以及为镜像打标签等事务。

      当用户执行docker search时,真正搜索的是index,而非registry。当执行docker push或docker pull时,将由index判断使用者是否有拉取或推送相应镜像及访问registry的权限,而registry则是将需要存储或拉取镜像存储的实际位置。 

graph

        从registry中下载的Docker镜像需要保存在本地,这一功能由Docker graph完成。

         在本graph的本地目录/var/lib/docker/devicemapper/devicemapper中,保存了每一个下载到本地的Docker镜像的主体文件,在/var/lib/docker/image目录下面保存了每一个下载到本地的Docker镜像的元数据,包括有json与layersize。其中json文件记录了相应Docker镜像的ID、依赖关系、创建时间和配置信息等,layersize为Docker镜像的大小。

Dockerfile

       Dockerfile是在通过docker build命令构建自己的Docker镜像时需要使用到的定义文件。它允许用户使用基本的DSL语法来定义Docker镜像,每一条指令描述了构建镜像的步骤。

四、 Docker镜像的操作

        Docker registry是存储器镜像的仓库,用户可以通过Docker client与Docker registry进行通信,以此来完成镜像的搜索、下载和上传等相关操作。Docker HUb是由Docker公司在互联网上提供的一个镜像仓库,提供镜像的公有与私有存储服务,它是用户最主要的镜像来源。除了Docker Hub外,用户还可以自行搭建私有服务器来实现镜像仓库的功能。

4.1 获取镜像

镜像是docker运行容器的前提。docker pull命令从网络上下载镜像。

该命令的格式为:

用法:docker pull [OPTIONS] NAME[:TAG|@DIGEST]
选项:
-a, --all-tags   #下载存储库中的所有标记的镜像
--disable-content-trust  #跳过镜像验证(默认为true)
--help         #打印帮助

对Docker镜像来说,如果不显示地指定TAG,则默认会选择latest标签,即下载仓库中最新版本的镜像。

获取默认最新的镜像:

# docker pull ubuntu   #下载最新版的ubuntu镜像

image.png

#上图为从默认的注册服务器的ubuntu仓库下载标记为latest的镜像。

#Downloading行首的子串代表各个层的ID。下载过程中会获取并输出镜像的各层信息。层(Layer)其实是AUFS(一种联合文件系统)中的重要概念,是实现增量保存与更新的基础。

指定仓库下载镜像:

# docker pull dl.dockerpool.com:5000/ubuntu   

#可以从其他注册服务器的仓库下载,但是需要在仓库的名称前指定完整的仓库注册服务器地址。例如这个dockerpool社区的镜像源。

4.2 镜像的管理

查看镜像信息:

使用docker images命令可以列出本地主机上已有的镜像。

# docker images --help

用法:docker images [OPTIONS] [REPOSITORY[:TAG]]
选项:
-a, --all   #显示所有的镜像,默认只列出最顶层的镜像
    --digests  #显示摘要
-f, --filter value   #根据提供的条件过滤输出(默认[])
    --format string  #漂亮的打印镜像使用Go模板
    --help           #打印帮助
    --no-trunc      #不要截断输出
-q, --quiet        #只显示数字ID

# docker images  #列出主机上面已有的镜像

REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
docker.io/ubuntu        latest              dd6f76d9cc90        8 days ago          122 MB
docker.io/hello-world   latest              725dcfab7d63        8 days ago          1.84 kB

#第一列字段:REPOSITORY。 是来自于哪个仓库,这里可以看出都是来自于官方镜像库。

#第二列字段:TAG。 用来标记来自于同一个仓库的不同镜像。通过TAG信息来区分发行版本。也就是镜像的标签信息。

#第三列字段:IMAGE ID。这是一个唯一值,也就是镜像的唯一ID号。

#第四列字段:CREATED。 这是镜像的创建时间。

#第五列字段:SIZE。  这是镜像的大小。

给镜像打标签:

# docker tag docker.io/ubuntu testubuntu:16.04  #指定镜像然后给打个新的标签是testubuntu:16.04

# docker images

image.png

#注意也就第一列和第二列不一样,后面全是一样的(如ID是一个),这说明镜像还是原来的镜像,只是多了一个标签而已。也就是它们实际上指向了同一个镜像文件,只是别名不同而已。标签在这里起到了引用或快捷方式的作用。

获取镜像的详细信息:

 docker inspect 命令可以查看镜像和容器的详细信息,默认会列出全部信息

# docker inspect --help

用法:docker inspect [OPTIONS] CONTAINER|IMAGE|TASK [CONTAINER|IMAGE|TASK...]
-f, --format  #可以通过此参数指定输出的模板格式,以便输出特定信息。
-s, --size   #如果类型是容器,则显示总文件大小
--type       #回指定类型的JSON(例如镜像,容器或任务)

# docker inspect dd6f76d9cc90  #获取ID号镜像的详细信息

[
    {
        "Id": "sha256:dd6f76d9cc90f3ec2bded9e1c970bb6a8c5259e05401b52df42c997dec1e79be",
        "RepoTags": [
            "docker.io/ubuntu:latest",
            "testubuntu:16.04"
        ],
        "RepoDigests": [
            "docker.io/ubuntu@sha256:6eb24585b1b2e7402600450d289ea0fd195cfb76893032bbbb3943e041ec8a65"
        ],

#上面是JSON输出信息,内容比较多,只粘贴了部分内容。

# docker inspect -f {{".Architecture"}}  dd6f76d9cc90  #可以指定{{".key"}}的形式只显示指定的值

# docker inspect -f {{".Architecture"}}  dd6f    #当然也可以只截取ID的前一部分。

amd64

搜索镜像:

使用docker search命令可以搜索远端仓库中共享的镜像,默认搜索Docker Hub官方仓库中的镜像。

# docker search --help

用法:docker search [OPTIONS] TERM
选项:
-f, --filter value    #根据提供的条件过滤输出(默认[])
--limit int          #搜索结果的最大数目(默认为25)
--no-index         #不要截断输出
--no-trunc         #不要截断输出

# docker search mysql  #搜索带mysql关键字的镜像

image.png

# docker search mysql --filter=stars=5  #仅显示评价为5星以上的镜像

删除镜像:

使用镜像的标签删除镜像,使用docker rmi命令可以删除镜像.

# docker rmi testubuntu:16.04  #删除掉testubuntu:16.04的镜像

Untagged: testubuntu:16.04
Untagged: docker.io/ubuntu@sha256:6eb24585b1b2e7402600450d289ea0fd195cfb76893032bbbb3943e041ec8a65

#同一个镜像拥有多个标签的时候,这个操作对本地的镜像不会有影响,docker rmi命令只是删除那个标签而已,但是当剩余一个标签的时候,再执行就是删除该镜像了。

#docker rmi  镜像ID   #会尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。

#需要注意的是,使用rmi命令删除镜像时,如果已有基于该镜像启动的容器存在,则无法直接删除,需要首先删除容器。当然,如果再加上-f, --force参数的话,就强制删除存在容器的镜像。

4.3 创建镜像:

创建镜像的方法有三种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建。

基于已有镜像的容器创建(这篇就先记录这种方式):

commit命令可以将一个容器固化为一个新的镜像。当需要制作特定的镜像时,会进行修改容器的配置,如在容器中安装特定工具等。通过commit命令可以将这些修改保存起来,使其不会因为容器的停止而丢失。

# docker commit --help  #使用方法如下

用法:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
选项:
-a, --author string   #作者的信息,(例如“John Hannibal Smith <hannibal@a-team.com>”)
-c, --change value    #将Dockerfile指令应用于创建的映像(默认[])
-m, --message string  #提交信息
-p, --pause           #在提交期间暂停容器(默认为true)

#提交保存时,只能选用正在运行的容器(即可以通过docker ps查看到的容器)来制作新的镜像。在指定特定镜像时,直接使用commit命令只是一个临时性的辅助命令,不推荐使用。官网建议通过docker build命令结合Dockerfile创建和管理镜像。

# docker run ubuntu echo 'hello!I am here!'  #先利用ubuntu镜像创建一个新的容器

# docker ps -a

image.png

#可以看到我们新启动的容器已经在运行了,ID为:faa5835a39ff

# docker commit -m "Added a new file" -a "51niux docktest1" faa5835a39ff   test #根据容器的ID提交一个新的镜像,镜像名称为test

sha256:24afcdfb76f10198c73e7b50f713587472fd8b5ccc6a41122e07987cec159941

#上面的信息是提交成功之后的显示内容

# docker images   #查看一下现在有点镜像

image.png

#从上面的截图可以看出新的镜像已经产生了。

build构建镜像:

一般用户主要使用docker build命令和Dockerfile来完成一个新镜像的构建,这里先介绍docker build命令。

# docker build --help

用法:Usage:  docker build [OPTIONS] PATH | URL | -
选项:
    --build-arg value   #设置构建时间变量(默认[])
    --cgroup-parent string   #容器的可选父cgroup
    --cpu-period int       #限制CPU CFS(完全公平调度程序)周期
    --cpu-quota int      #限制CPU CFS(完全公平调度程序)配额
-c, --cpu-shares int      #CPU份额(相对权重)
    --cpuset-cpus string  #在其中允许执行的CPU(0-3,0,1)
    --cpuset-mems string  #允许执行的MEM(0-3,0,1)
    --disable-content-trust   #跳过镜像验证(默认为true)
 -f, --file string     #Dockerfile的名称(默认是'PATH/Dockerfile') 
     --force-rm       #始终删除中间容器
     --help     #打印用法
     --isolation string   #容器隔离技术
     --label value   #设置镜像的元数据(默认[])
 -m, --memory string      #内存限制
     --memory-swap string  #交换限制等于内存加交换:'-1'以启用无限交换
     --network string     #将容器连接到网络(默认“默认”)
     --no-cache     #构建镜像时不要使用缓存
     --pull  #始终尝试拉取图像的较新版本
 -q, --quiet     #取消构建输出并成功打印镜像ID
     --rm     #成功构建后移除中间容器(默认为true)
     --shm-size string   #/dev/shm的大小,默认值是64MB
 -t, --tag value     #以“名称:标记”格式命名(可选)标记(默认为[])
     --ulimit value   #Ulimit选项(默认[])
 -v, --volume value     #设置构建时绑定挂载(默认[])

先把命令介绍记录到这里,下来还得单开一篇记录镜像的构建。

4.4 存储和导入镜像

可以使用docker save和docker load命令来存储和载入镜像。

# docker save -o /opt/ubuntu_latest.tar docker.io/ubuntu:latest  #将镜像存储到本地的/opt目录下名称为ubuntu_latest.tar

# ls -lh /opt/ubuntu_latest.tar 

-rw------- 1 root root 121M 11月 12 22:36 /opt/ubuntu_latest.tar

# docker load -i /opt/ubuntu_latest.tar   #载入镜像,-i, --input后面跟要载入的镜像tar包

## docker load  </opt/ubuntu_latest.tar   #当然这种方式也是可以的

另外简单先提一下上传镜像:

可以使用docker push命令上传镜像到仓库,默认上传到DockerHub官方仓库(需要登录),命令格式为docker push NAME[:TAG].用户在DockerHub网站注册后,即可上传自制的镜像。

#docker tag test:latest user/test:latest #先添加新的标签

#docker push user/test:latest

博文来自:www.51niux.com      

4.5 Docker Hub

        目前Docker官方维护了一个公有仓库https://hub.docker.com,其中已经有上万个镜像。大部分需求都可以通过在Docker Hub中直接下载镜像来实现。

       仓库是集中存放镜像的地方。一个容易与之混淆的概念是注册服务器(Registry).实际上注册服务器是存放仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说仓库可以被认为是一个具体的项目或目录。

      仓库又分共有仓库和私有仓库。

登录 DockerHub账户:

      用户通过拥有一个Docker Hub账户,用以提交和推送自己的镜像。当用户在未登录状态下输入docker login命令后,Docker client端将提示用户依次输入Username、 Password和Email,并存放到用户希望登录的registry对应的配置文件中。若用户处于已登录状态且没有尝试以新用户身份重新登录,则根据配置文件中的既有信息来获取用户信息。其后,Docker client向Docker server发送“post/auth”的HTTP请求,进行权限认证。Docker server接受到相应的HTTP请求后,根据URL以及请求方法来确定需要执行的方法,认证的方法为postAuth。

      在postAuth这个方法执行的过程中,根据HTTP请求中的配置信息,由daemon实例调用Auth函数来进行认证工作,并将函数返回状态(即认证是否通过)写入HTTP应答。

      Auth函数代码实现包括如下几个关键步骤:

  1. 根据config中的registry address,得到有效的index配置信息

  2. 由返回的Index配置信息解析获得一个registry endpoint.

  3. 重置config中的registry address为上一步返回的endpoint.

  4. 执行Login函数登入该registry endpoint。

     上述Login函数真正负责进行用户登录的实现过程。它会根据Docker registry的版本分别执行Login V2和Login V1.

基本操作:

       无需登录就可以进行:docker search 和docker pull操作

       根据是否为官方提供,可将这些镜像资源分为两类。一种是类似于centos这样的基础镜像,称为基础或根镜像。这些镜像是由docker公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。还有一种类型,比如tianon/centos镜像,它是由DockerHub的用户tianon创建并维护的,带有用户名称为前缀,表明是某用户的某仓库。可以通过用户名称前缀user_name/来指定使用某个用户提供的镜像.

# docker search centos --filter=stars=50    #显示评价为50星以上的镜像

image.png

#用户可以再登录的情况下通过docker push命令将本地的镜像推送到Docker Hub。

自动创建:

       自动创建功能对于需要经常升级镜像内程序来说十分方便,自动创建功能使得用户通过Docker Hub指定跟踪一个目标网站(目前支持GitHub或BitBucket)上的项目,一旦项目发现新的提交,则会自动执行创建。要配置自动创建,包括如下的步骤:

1). 创建并登录Docker Hub,以及目标网站;*在目标网站中连接账户到Docker Hub。
2). 在Docker Hub中配置一个自动创建。
3).选取一个目标网站中的项目(需要含Dockerfile)和分支
4).指定Dockerfile的位置,并提交创建。
之后可以再Docker Hub的“自动创建”页面跟踪每次创建的状态。

Pull镜像:

     Docker的server端收到用户发起的pull请求后,需要做的主要工作如下:

  1. 根据用户命令行参数解析出其希望拉取的repository信息

  2. 通过TagStore设置锁,保证Docker daemon在一个时刻对一个repository只能进行一个拉取操作;拉取镜像完毕之后该锁释放。

  3. 获取endpoint信息,并向该endpoint指定的registry发起会话

  4. 如果待拉取repository为official版本或者endpoint的API版本为V2,同时用户没有配置Docker-Mirrors,Docker就直接向V2 registry拉取镜像。(如果向V2 registry拉取镜像失败,则尝试从V1 registry拉取。)

  5. 获取V2 registry的endpoint。

  6. 由endpoint和待拉取镜像名称获取拉取指定镜像的认证信息。

  7. 如果tag值为空,即没有指定标签,则获取V2 registry中repository的tag list,然后对于tag list中的每一个标签,都执行一次pullV2Tag方法。该方法的功能分为两大部分,一是验证用户请求,二是当且仅当某一层不在本地时进行拉取这一层文件到本地。如果tag值不为空,则只对指定标签的镜像进行上述工作。

Commit镜像:

       docker commit命令只提交容器镜像发生变更了的部分,即修改后的容器镜像与当前仓库中对应镜像之间的差异部分,这使得该操作实际需要提交的文件往往并不多。Docker server接收到对应的HTTP请求后,需要执行下面的步骤:

  1. 根据用户输入pause函数的设置确定是否暂停该Docker容器的运行。

  2. 寻找该容器文件系统再graphdriver上的路径。

  3. 返回该容器与其父镜像的差异并将这部分文件和目录打成压缩包,即待commit容器的可读写层的差异(diff)。

  4. graphdriver根据返回的差异创建一个新的镜像,记录其元数据。

  5. 将上述镜像文件及目录上传至repository。

Build构建镜像:

      Docker client端通过Dockerfile完成相关信息的设置之后,Docker client向Docker server发送“POST/build”的HTTP请求,包含了所需的context信息(文件或目录)。

Docker server端接受到相应的HTTP请求后,需要做的工作如下:

  1. 创建一个临时目录。并将context制定的文件系统解压到该目录下。

  2. 读取并解析Dockerfile

  3. 根据解析出的DOckerfile遍历其中的所有指令,并分发到不同的模块去执行。Dockerfile每条指令的格式均为INSTRUCION arguments,INSTRUCION是一些特定的关键词,包括FROM、RUN、USER等,都会映射到不同的parser进行处理。

  4. parser为上述每一个指令创建一个对应的临时容器,然后通过commit使用此容器生成一层镜像。

  5. Dockerfile中偶的指令对应的层的集合,就是此次build后的结果。其中最后一次commit生成的层镜像ID就会作为最终的镜像ID返回。

Push镜像:

       当用户制作了自己的镜像后,希望将它上传至仓库,此时可以通过docker push命令完成该操作。而在Docker server接收到用户的push请求后的关键步骤如下:

  1. 解析出repository信息,通过TagStore设置锁。

  2. 通过ping操作检查指定的registry是否可用,返回一个registry endpoint,然后发起同registry的会话.

  3. 如果推送的镜像为Official镜像或者endpoint对应版本为V2 registry,则调用pushV2 Repository方法。这个方法会首先验证用户指定标签的镜像在本地是否存在,以及被推repository的访问权限。接下来,对于不同标签的待推送镜像,该方法会从顶向下逐个检验layer其checksum,标记被推送repository中不存在的layer和更改过的读写层内容。将这些标记后的镜像内容上传完毕后,再讲一份描述文件manifest上传到repository。

  4. 如果镜像不属于上述情况,则Docker会调用push Repository方法来推送镜像到V1 registry,并根据待推送的repository和tag信息保证当且仅当某layer在endpoint上不存在时,才上传该layer。


作者:忙碌的柴少 分类:Docker 浏览:3234 评论:0
留言列表
发表评论
来宾的头像