热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Docker镜像、容器剖析

我们通常所说的docker是什么?在这里英文本意为“搬运工”这里指的的docker搬运点的是集装箱,集装箱装的是够任意类型的APP,开发者通过Docker可以将app变成一种标准化,可移植的、自管

我们通常所说的docker是什么?

在这里英文本意为“搬运工”这里指的的docker搬运点的是集装箱,集装箱装的是够任意类型的APP,开发者通过Docker可以将app变成一种标准化,可移植的、自管理的组件、可以在任意主流的系统开发,调试和运行

  简单的来说,docker是一种用了新颖的方式实现的轻量级的虚拟化,类似于VM,但是在原理和应用上和VM还是有很大的区别,其专业的名称是应用容器;

所谓应用容器,就比如将Nginx,Mysql等软件程序将其封装成一组特定的虚拟机一样,如果我们想用Nginx这些应用的话,我们直接运行这个容器就好了,这就相当于运行起来的虚拟机一样,只要能运行,这些配置都省下来了,如果说系统层面的宿主机出现了异常需要迁移,那么我们将这个容器转移平台就可以的

   Docker基于Go语言开发的,代码托管在Github上,docker容器可以封装任何有效负载,计划可以在任何服务器之间进行一致性运行,也就是说,开发者构建的应用,只需要一次构建即可多平台运行,运营人员只需要配置服务,即可运行所有应用,

    若是利用容器的话,那么开发直接在容器里开发,测试的时候整个同期给测试,测好了把测试后容器再上线就好了,通过容器,整个开发,测试和生产环境保持高度一致;

 此外容器也有和VM一样具有一定的隔离性,各个容器之间的数据和内存之间相互隔离,可以保证一定的安全性

      Hyper-V、KVM和XEN等虚拟机管理程序都是“”基于虚拟化硬件仿真机制”,这就意味着,它们对系统硬件要求很高,然而,容器确实使用共享的操纵系统,它们在使用系统资源方面比虚拟机管理程序要高效很多,容器不是对硬件要求进行的虚拟化的处理,而是驻留在一个linux实例上,Docker可以解决虚拟机能够解决的问题,同时也能解决虚拟机由于资源要求过高而无法解决的问题

为什么使用Docke?或者是docker有哪方面的优势

1)快速的交付应用程序

开发者使用一个标准image来构建开发容器,开发完成之后,系统管理员就可以使用这个容器来部署代码

docker可以快速的创建容器,快速的迭代应用程序,并让整个过程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的

docker容器轻量级,启动很快,启动的时候是次秒级的,节约开发,测试,部署时间

2)更容易部署和扩展

docker容器可以在几乎所有环境中运行,物理机,虚拟机,公有云,私有云,服务器等等

docker容器兼容很多平台,这样就可以把一个应用程序从一个平台上迁移到到另一个

3)效率高

Docker容器不需要hypervisor,他是内核级虚拟化

4)快速的部署也以为这更简单的管理

通常是需要小小的改变就可以替代以往巨型和大量更新工作

【Docker常用的案列】

自动打包和部署应用

创建轻量,私有的Paas环境

自动化测试和持续集成/部署

部署并扩展WEB应用/数据库和后端服务器

【VM的选用】

docker容器相对于VM还是有很多优点的,

1)启动速度快,容器通常在一秒内可以启动,而VM要很久

2)资源利用率小,一台普通服务器可以跑上个容器

3)性能开销小,VM需要额外的CPU和内存来完成OS的功能,这一部分占据了额外的资源

下图所示:对比了docker和传统虚拟化(KVM,XEN等)方式的不同之处,Docker容器是在操作系统层面上实现了虚拟化,直接复用本地主机操作系统,而传统方式则是在硬件基础上,虚拟出自己的系统,再在系统上部署相关的APP应用

传统虚拟化方案:Nginx(图一)

Docker虚拟化解决方案:Nginx镜像-nginx容器-对外访问

Docker虚拟化三个概念解析:镜像,容器,仓库

镜像:Docker的镜像其实就是模板,跟我们常见的ISO镜像类似,是一个样板

容器:使用镜像常见的应用或者系统,称之为一个容器

仓库:仓库是存放镜像的地方,分为公开仓库(Public)和私有仓库(Private)两种形式

Docker最早为LXC+AUFS组合,Docker0.9.0版本开始引入libcontainer,可以视作LXC的替代品,其中LXC负责资源管理,AUFS负责镜像管理;而LXC包括Cgroup,namespace,chroot等组件,并通过cgroup进行资源管理

 从资产管理来看,Docker,LXC,Cgroup三者的关系是:cgroup在最底层落实资源管理,LXC在cgroup上封装了一层,Docker又在LXC封装了一层

    Cgroup是linux内核提供的一种可以限制,记录,隔离进程组所使用的物理资源(如CPU,Memory,IO等)的机制,Cgroups也是LXC为实现虚拟化所使用的资源管理手段,可以说没有Cgroups也就没有LXC,也就没有Docker

   Cgroup最初的目的地为资源管理提供一个统一的框架,即整合现有的Cgroup等子系统,也为未来开发新的子系统提供接口,现在的Cgroup使用与多种应用场景,从单个进程的资源控制,到实现操作系统层次的虚拟化

  LXC容器可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性,容器有效的将单个系统管理的资源划分到独立的组中,以便更好的在独立的组之间平衡有冲突的资源使用需求

【对比传统的虚拟机总结】

【Docker的体系结构】

docker使用C/S架构,docker daemon作为server端接受clinet的请求,并处理(创建,运行,分发容器)他们可以运行在一个机器上,也通过socket或者去RESTful API通信

Docker daemon一般在宿主机后台运行,docker clinet以系统命令形式存在,用户用docker命令与docker daemon交互;

docker守护进程(docker daemon)

如图上所示,docker守护进程运行在一台主机上,用户并不直接和守护进行交互,而通过docker客户端间接和其通信

Docker客户端(Docker client)

Docker客户端实际上是docker的二进制程序,是用户与docker交互方式,它接受用户指令并且与背后的docker守护进程通信;

Docker 内部:

要理解 Docker 内部构建,需要理解以下三种部件:

Docker 镜像 - Docker images 

docker镜像是docker容器运行时的只读模板,镜像可以用来创建docker容器。每个镜像由一系列层的(layers)组成,Docker使用的UFS(联合文件系统)来讲这些层联合到单独的镜像中,

UFS允许独立文件系统中的文件和文件夹被透明覆盖,形成一个单独连贯的文件系统,正因为有了这些镜像层的存在,docker是如此的轻量,当你改变一个docker镜像,比如说升级到某个程序最新版本,这样一个新的层会被创建,不需要替换或者是说重新创建,只需要升级,层使得分发docker镜像变得简单和快速;

每个docker都有很多层次构成,docker使用  union file systems  将这些不同的层结合到一个image 中去。

例如:centos镜像中安装nginx,就成了nginx镜像”,其实在此时Docker镜像的层级概念就体现出来了。底层一个centos操作系统镜像,上面叠加一个ngnx层,就完成了一个nginx镜像的构建。层级概念就不难理解,此时我们一般centos操作系统镜像称为nginx镜像层的父镜像。

Docker 仓库 - Docker registeries

docker仓库用来保存镜像,可以理解为代码控制中的代码仓库,同样的,docker仓库也有共公有和私有的概念,公有Docker仓库名字是docker hub,docker hub提供了庞大的镜像集合供使用,这些镜像可以是自己创建的,或者在比人的镜像基础上创建

仓库是集中存放镜像文件的场所,有时候会把仓库 和仓库注册服务器(Regitry)混为一谈,

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。

最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括 Docker Pool等,可以提供大陆用户更稳定快速的访问。

当然,用户也可以在本地网络内创建一个私有仓库。

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

*注:Docker 仓库的概念跟Git类似,注册服务器可以理解为 GitHub 这样的托管服务。

Docker 容器 - Docker containers

Docker 利用容器来运行应用,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台。

容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

*注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层

[Docker  底层技术]

docker底层的 2 个核心技术分别是 Namespaces 和 Control groups

Namespaces用来隔离各个容器

1)pid namespace

不同用户的进程就是通过pid namespace 隔离开的,且不同  namespace  中可以有相同pid。所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的 namespace 。

 

2) net namespace

有了pid namespace,  每个 namespace 中的pid能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net namespace 实现的,每个 net namespace 有独立的  network devices, IP addresses, IP routing tables, /proc/net  目录。这样每个 container 的网络就能隔离开来。docker默认采用veth的方式将 container 中的虚拟网卡同 host 上的一个docker bridge: docker0 连接在一起。

 

3) ipc namespace

container 中进程交互还是采用linux常见的进程间交互方法 (interprocess communication - IPC),包括常见的信号量、消息队列和共享内存。container  的进程间交互实际上还是host 上具有相同pid namespace 中的进程间交互。

 

4) mnt namespace

类似chroot,将一个进程放到一个特定的目录执行。mnt namespace 允许不同 namespace 的进程看到的文件结构不同,这样每个  namespace  中的进程所看到的文件目录就被隔离开了。在container里头,看到的文件系统,就是一个完整的linux系统,有/etc、/lib 等,通过chroot实现。

 

5) uts namespace

UTS("UNIX Time-sharing System") namespace 允许每个 container 拥有独立的 hostname 和 domain name,  使其在网络上可以被视作一个独立的节点而非 Host 上的一个进程。

 

6) user namespace

每个 container 可以有不同的  user  和  group id,  也就是说可以在 container 内部用 container 内部的用户执行程序而非 Host 上的用户。

 

有了以上 6 种 namespace 从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个 container 就可以对外展现出一个独立计算机的能力,并且不同 container 从 OS 层面实现了隔离。然而不同 namespace 之间资源还是相互竞争的,仍然需要类似ulimit来管理每个 container 所能使用的资源 - -cgroup。

cgroups(Control groups)实现了对资源的配额和度量。

 【创建自己的镜像】

一:使用docker commit  来扩展一个 image

1.1:先下载一个容器

docker pull training/sinatra

1.2用容器启动这个镜像

docker run -t -i training/sinatra /bin/bash 

1.3:接下来给使用中的容器,添加自己需要的工具,组装自己的运行环境

1.4:结束后,我们使用exit来退出,现在我们的容器已经改变了,我们使用docker commint命令来提交相应的副本

docker commit -m “Added json gem” -a “xiaoyu”   0b2616b0e5a8  ouruser/sinatra:v2 

其中, -m  来指定提交的说明信息,跟我们使用的版本控制工具一样; -a  可以指定更新的用户信息;之后是用来创建镜像的容器的 ID;最后指定目标镜像的仓库名和 tag 信息。创建成功后会返回这个镜像的 ID信息。

 二:从dockerfile来创建image

使用docker commit  来扩展一个 image 比较简单,但它不容易在一个团队中分享它。我们使用docker build  来创建一个新的 image 。为此,我们需要创建一个dockerfile,包含一些如何创建我们的image 的指令。现在,我们来创建一个目录和一个dockerfile

 

Dockerfile基本的语法是

使用#来注释

FROM指令告诉 Docker 使用哪个镜像作为基础(docker使用哪个 image 源)

MAINTAINER是维护者的信息

RUN开头的指令会在创建中运行,比如安装一个软件包,在这里使用 yum来安装了一些软件

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

 

2.1、创建镜像所在的文件夹和Dockerfile文件 
命令: 
1、mkdir sinatra 
2、cd sinatra 
3、touch Dockerfile 
2.2、在Dockerfile文件中写入指令,没一条指令都会更新镜像的信息例如: 
# This is a comment 
FROM ubuntu:14.04 
MAINTAINER Kate Smith ksmith@example.com 
RUN apt-get update && apt-get install -y ruby ruby-dev 
RUN gem install sinatra 
格式说明: 
每行命令都是以 INSTRUCTION statement 形式,就是命令+ 清单的模式。命令要大写,“#”是注解。 
FROM 命令是告诉docker 我们的镜像什么。 
MAINTAINER 是描述 镜像的创建人。 
RUN 命令是在镜像内部执行。就是说他后面的命令应该是针对镜像可以运行的命令。 
2.3、创建镜像 
命令:docker build -t ouruser/sinatra:v2 . 
docker build 是docker创建镜像的命令 
-t 是标识新建的镜像属于 ouruser的 
sinatra是仓库的名称 
:v2 是tag 
“.”是用来指明 我们的使用的Dockerfile文件当前目录的 
2.4、创建完成后,从镜像创建容器 
docker run -t -i ouruser/sinatra:v2 /bin/bash

 

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

可以看到 build 进程在执行操作。它要做的第一件事情就是上传这个Dockerfile内容,因为所有的操作都要依据Dockerfile来进行。然后,Dockfile中的指令被一条一条的执行。每一步都创建了一个新的容器,在容器中执行指令并提交修改(就跟之前介绍过的docker commit  一样)。当所有的指令都执行完毕之后,返回了最终的镜像 id。所有的中间步骤所产生的容器都被删除和清理了。

*注意一个镜像不能超过 127 层

 拓展:

进入容器

在使用 -d 参数时,容器启动后会进入后台。某些时候需要进入容器进行操作,有很多种方法,包括使用docker attach 命令或nsenter命令。

使用docker attach进入容器

 

1.docker attach 允许我们进入后台进程.

2.--sig-proxy=false 不使用容器转发信号,允许我们使用 ctrl -c 来退出,执行dockerps查看在后台运行

但是使用  attach  命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。

 

也可以执行docker exec进入运行的容器

docker  exec  -it  容器ID/名称 /bin/bash

以上命令返回一个命令界面,exec代表直接在容器中运行命令

 

容器导入和导出

导出容器

docker export [容器 id] > [导出文件]

如果要导出本地某个容器,可以使用docker export  命令。

导入容器

可以使用docker import  从容器快照文件中再导入为镜像

# cat centos6.tar | docker import – centos6:test

#docker images

 


推荐阅读
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
author-avatar
吕小布
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有