docker基本原理

写的很不错的文章,做个存档

什么是容器

容器是 种轻量级、可移植的为应用程序提供了隔离的运行空间 。每一个容器内都包含一个独享的完整用户环境,而且 个容器内的环境变更不会影响其余容器的运行环境,可使应用程序在几乎任何地方以相同的方式运行,好比开发人员在本身的笔记本上建立井测试好的容器,无须任何修改就能在生产环境的虚拟机、物理服务器或公有云 机上运行在技术方面,容器是经过 系列系统级别的机制来实现的,好比经过 Linux Namespace进行空间隔离;经过文件系统的挂载点来决定容器能够访问哪些文件:经过 cgroups 来肯定每一个容器能够利用多少资源:容器之间经过共享同 个系统内核来提高内存的使用率。php

什么是docker

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,听从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。web

Docker 自开源后受到普遍的关注和讨论,以致于 dotCloud 公司后来都更名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中普遍应用。docker

Docker 项目的目标是实现轻量级的操做系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。在 LXC 的基础上 Docker 进行了进一步的封装,让用户不须要去关心容器的管理,使得操做更为简便。用户操做 Docker 的容器就像操做一个快速轻量级的虚拟机同样简单。shell

下面的图片比较了 Docker 和传统虚拟化方式的不一样之处,可见容器是在操做系统层面上实现虚拟化,直接复用本地主机的操做系统,而传统方式则是在硬件层面实现。ubuntu

virtualization

docker

为何用docker

做为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具备众多的优点。centos

Docker 在以下几个方面具备较大的优点:安全

  • 更快速的交付和部署

Docker在整个开发周期均可以完美的辅助你实现快速交付。Docker容许开发者在装有应用和服务本地容器作开发。能够直接集成到可持续开发流程中。bash

例如:开发者可使用一个标准的镜像来构建一套开发容器,开发完成以后,运维人员能够直接使用这个容器来部署代码。 Docker 能够快速建立容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其余成员更容易理解应用程序是如何建立和工做的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。服务器

  • 高效的部署和扩容

Docker 容器几乎能够在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、我的电脑、服务器等。 这种兼容性可让用户把一个应用程序从一个平台直接迁移到另一个。网络

Docker的兼容性和轻量特性能够很轻松的实现负载的动态管理。你能够快速扩容或方便的下线的你的应用和服务,这种速度趋近实时。

  • 更高的资源利用率

Docker 对系统资源的利用率很高,一台主机上能够同时运行数千个 Docker 容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽可能小。传统虚拟机方式运行 10 个不一样的应用就要起 10 个虚拟机,而Docker 只须要启动 10 个隔离的应用便可。

  • 更简单的管理

使用 Docker,只须要小小的修改,就能够替代以往大量的更新工做。全部的修改都以增量的方式被分发和更新,从而实现自动化而且高效的管理。

Docker引擎

docker引擎是一个c/s结构的应用,主要组件见下图:

docker engine components flow

 

 

 

  • Server是一个常驻进程
  • REST API 实现了client和server间的交互协议
  • CLI 实现容器和镜像的管理,为用户提供统一的操做界面

Docker构架

Docker使用C/S架构,Client 经过接口与Server进程通讯实现容器的构建,运行和发布。client和server能够运行在同一台集群,也能够经过跨主机实现远程通讯。即客户端经过与后 台服务交互,来编译、运行和发布容器。 Docker的客户端能够链接到本机的 Docker 服务上,也能够链接到远程的 Docker 服务上Docker 客户端是使用阻ST 接口来与后台服务通讯的,它经过使用 UN Socket 链接或者网络接口实现。

docker architecture

docker_host:docker主机

docker daemon:docker守护进程

containers:容器

images:镜像

registry:仓库

(1)Docker 后台服务监昕 ST 接口的 求,管理 Docker 的对象,好比 Docker 的镜像、容器、网络和磁盘卷。一 Docker 后台服务能够和其余 Docker 后台服务进行通讯,从而对它们进行管理。
(2)Docker 客户端( Docker Client )是咱们和 Docker 后台服务交互的主要工具,在使用 docker run 命令时,客户端把命令发送到 Docker 后台服务,再由后台服务执行该命令。 Docker 客户端能够链接多个后台服务并与它们通讯。
(3)Docker 库( Docker Regis )是用来存 Docker 镜像的, Docker Hub Docker Cloud 是全部人都可以使用的公共的 Docke 仓库 Docker 默认从 Docker Hub 下载镜像,固然咱们也能够本身搭建私有仓库 。当咱们使用 Docker pull docker run 令时,就会从咱们配置的 docker仓库下载镜像, 使用 docker push 命令时,咱们的镜像就会被推送到 Docker 仓库中。
(4)Docker 对象( Docker Object )包括镜像、容器、网络、磁盘卷和插件等 咱们在使用Docker 时,就会建立和使用 Docker 对象

核心概念

  • 镜像(image)

Docker 镜像(Image)就是一个只读的模板。例如:一个镜像能够包含一个完整的操做系统环境,里面仅安装了 Apache 或用户须要的其它应用程序。镜像能够用来建立 Docker 容器,一个镜像能够建立不少容器。Docker 提供了一个很简单的机制来建立镜像或者更新现有的镜像,用户甚至能够直接从其余人那里下载一个已经作好的镜像来直接使用。

镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,看看下面这张图:
image ufs

右边咱们看到了多个只读层,它们重叠在一块儿。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker内部的实现细节,而且可以在docker宿主机的文件系统上访问到。统一文件系统(Union File System)技术可以将不一样的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。

  • 仓库(repository)

仓库(Repository)是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上每每存放着多个仓库,每一个仓库中又包含了多个镜像,每一个镜像有不一样的标签(tag)。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括 时速云 、网易云 等,能够提供大陆用户更稳定快速的访问。固然,用户也能够在本地网络内建立一个私有仓库。

当用户建立了本身的镜像以后就可使用 push 命令将它上传到公有或者私有仓库,这样下次在另一台机器上使用这个镜像时候,只须要从仓库上 pull 下来就能够了。

Docker 仓库的概念跟 Git 相似,注册服务器能够理解为 GitHub 这样的托管服务。

  • 容器(container)

Docker 利用容器(Container)来运行应用。容器是从镜像建立的运行实例。它能够被启动、开始、中止、删除。每一个容器都是相互隔离的、保证安全的平台。能够把容器看作是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

容器的定义和镜像几乎如出一辙,也是一堆层的统一视角,惟一区别在于容器的最上面那一层是可读可写的。

container ufs

一个运行态容器被定义为一个可读写的统一文件系统加上隔离的进程空间和包含其中的进程。下面这张图片展现了一个运行中的容器。

container running

正是文件系统隔离技术使得Docker成为了一个很是有潜力的虚拟化技术。一个容器中的进程可能会对文件进行修改、删除、建立,这些改变都将做用于可读写层。

Docker安装部署

docker安装很是简单,支持各类平台,请到官网自行安装下载docker下载

Docker经常使用命令

获取镜像

docker pull

从仓库获取所须要的镜像。

使用示例:

docker pull centos:centos6

实际上至关于 docker pull registry.hub.docker.com/centos:centos6
命令,即从注册服务器 registry.hub.docker.com 中的 centos 仓库来下载标记为 centos6 的镜像。
有时候官方仓库注册服务器下载较慢,能够从其余仓库下载。 从其它仓库下载时须要指定完整的仓库注册服务器地址。

查看镜像列表#

docker images

列出了全部顶层(top-level)镜像。实际上,在这里咱们没有办法区分一个镜像和一个只读层,因此咱们
提出了top-level镜像。只有建立容器时使用的镜像或者是直接pull下来的镜像能被称为顶层(top-level)
镜像,而且每个顶层镜像下面都隐藏了多个镜像层。

使用示例:

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE centos centos6 6a77ab6655b9 8 weeks ago 194.6 MB ubuntu latest 2fa927b5cdd3 9 weeks ago 122 MB

在列出信息中,能够看到几个字段信息

  • 来自于哪一个仓库,好比 ubuntu
  • 镜像的标记,好比 14.04
  • 它的 ID 号(惟一)
  • 建立时间
  • 镜像大小

利用 Dockerfile 来建立镜像

docker build

使用 docker commit 来扩展一个镜像比较简单,可是不方便在一个团队中分享。咱们可使用
docker build 来建立一个新的镜像。为此,首先须要建立一个 Dockerfile,包含一些如何建立镜像的
指令。新建一个目录和一个 Dockerfile。

mkdir hainiu
cd hainiu
touch Dockerfile

Dockerfile 中每一条指令都建立镜像的一层,例如:

FROM centos:centos6 MAINTAINER sandywei <sandy@hainiu.tech> # move all configuration files into container RUN yum install -y httpd EXPOSE 80 CMD ["sh","-c","service httpd start;bash"] 

Dockerfile 基本的语法是

  • 使用#来注释
  • FROM 指令告诉 Docker 使用哪一个镜像做为基础
  • 接着是维护者的信息
  • RUN开头的指令会在建立中运行,好比安装一个软件包,在这里使用yum来安装了一些软件

更详细的语法说明请参考 Dockerfile

编写完成 Dockerfile 后可使用 docker build 来生成镜像。

$ docker build -t hainiu/httpd:1.0 . Sending build context to Docker daemon 2.048 kB Step 1 : FROM centos:centos6 ---> 6a77ab6655b9 Step 2 : MAINTAINER sandywei <sandy@hainiu.tech> ---> Running in 1b26493518a7 ---> 8877ee5f7432 Removing intermediate container 1b26493518a7 Step 3 : RUN yum install -y httpd ---> Running in fe5b6f1ef888 ..... Step 5 : CMD sh -c service httpd start ---> Running in b2b94c1601c2 ---> 5f9aa91b0c9e Removing intermediate container b2b94c1601c2 Successfully built 5f9aa91b0c9e

其中 -t 标记来添加 tag,指定新的镜像的用户信息。 “.” 是 Dockerfile 所在的路径(当前目录),
也能够替换为一个具体的 Dockerfile 的路径。注意一个镜像不能超过 127 层。

用docker images 查看镜像列表

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE hainiu/httpd 1.0 5f9aa91b0c9e 3 minutes ago 292.4 MB centos centos6 6a77ab6655b9 8 weeks ago 194.6 MB ubuntu latest 2fa927b5cdd3 9 weeks ago 122 MB 

细心的朋友能够看到最后一层的ID(5f9aa91b0c9e)和 image id 是同样的

上传镜像

docker push

用户能够经过 docker push 命令,把本身建立的镜像上传到仓库中来共享。例如,用户在 Docker Hub 上完成注册后,能够推送本身的镜像到仓库中。

运行实例:

$ docker push hainiu/httpd:1.0

建立容器

docker create <image-id>

docker create 命令为指定的镜像(image)添加了一个可读写层,构成了一个新的容器。注意,这个容器并无运行。

docker create 命令提供了许多参数选项能够指定名字,硬件资源,网络配置等等。

运行示例:

建立一个centos的容器,可使用仓库+标签的名字肯定image,也可使用image-id指定image。返回容器id

#查看本地images列表
$ docker images

#用仓库+标签
$ docker create -it --name centos6_container centos:centos6 #使用image-id $ docker create -it --name centos6_container 6a77ab6655b9 bash b3cd0b47fe3db0115037c5e9cf776914bd46944d1ac63c0b753a9df6944c7a67 #可使用 docker ps查看一件存在的容器列表,不加参数默认只显示当前运行的容器 $ docker ps -a

可使用 -v 参数将本地目录挂载到容器中。

$ docker create -it --name centos6_container -v /src/webapp:/opt/webapp centos:centos6

这个功能在进行测试的时候十分方便,好比用户能够放置一些程序到本地目录中,来查看容器是否正常工做。本地目录的路径必须是绝对路径,若是目录不存在 Docker 会自动为你建立它。

启动容器

docker start <container-id>

Docker start命令为容器文件系统建立了一个进程隔离空间。注意,每个容器只可以有一个进程隔离空间。

运行实例:

#经过名字启动 $ docker start -i centos6_container #经过容器ID启动 $ docker start -i b3cd0b47fe3d

进入容器

docker exec <container-id>

在当前容器中执行新命令,若是增长 -it参数运行bash 就和登陆到容器效果同样的。

docker exec -it centos6_container bash

中止容器#

docker stop <container-id>

删除容器#

docker rm <container-id>

运行容器

docker run <image-id>

docker run就是docker create和docker start两个命令的组合,支持参数也是一致的,若是指定容器
名字是,容器已经存在会报错,能够增长 --rm 参数实现容器退出时自动删除。

运行示例:

docker create -it --rm --name centos6_container centos:centos6

查看容器列表

docker ps

docker ps 命令会列出全部运行中的容器。这隐藏了非运行态容器的存在,若是想要找出这些容器,增长 -a 参数。

删除镜像

docker rmi <image-id>

删除构成镜像的一个只读层。你只可以使用docker rmi来移除最顶层(top level layer)
(也能够说是镜像),你也可使用-f参数来强制删除中间的只读层。

commit容器#

docker commit <container-id>

将容器的可读写层转换为一个只读层,这样就把一个容器转换成了不可变的镜像。

镜像保存#

docker save <image-id>

建立一个镜像的压缩文件,这个文件可以在另一个主机的Docker上使用。和export命令不一样,这个命令
为每个层都保存了它们的元数据。这个命令只能对镜像生效。

使用示例:

#保存centos镜像到centos_images.tar 文件 $ docker save -o centos_images.tar centos:centos6 #或者直接重定向 $ docker save -o centos_images.tar centos:centos6 > centos_images.tar

容器导出

docker export <container-id>

建立一个tar文件,而且移除了元数据和没必要要的层,将多个层整合成了一个层,只保存了当前统一视角看到
的内容。expoxt后的容器再import到Docker中,只有一个容器当前状态的镜像;而save后的镜像则不一样,
它可以看到这个镜像的历史镜像。

inspect

docker inspect <container-id> or <image-id>

docker inspect命令会提取出容器或者镜像最顶层的元数据

快照地址:地址

做者地址:青牛

相关文章
相关标签/搜索