标签:还需 运行环境 moby dev 分类 load width 合成 server
原文:01 . Docker原理部署及常用操作命令
1|0Docker的来源及构造:
容器是一种基础工具:泛指任何用于容纳其他物品的工具,可以部分或完全封闭,被用于容纳,储存,运输物品: 物品可以被放置在容器中,而容器可以保护内容物:
人类使用容器的历史有十万年,甚至可能有数百万年的历史:
但我们重点在LXC这里;
虚拟化和容器的关系:
主机级虚拟化:虚拟化的是整个完整的物理硬件平台,比如VMware,KVM.里面跑的是与宿主机不一样的系统
两种类型:
类型一: 直接在硬件上装一个虚拟机管理器,不装宿主机,在虚拟机管理器上跑需要的操作系统:
类型二: Vmware,kvm
完整意义的操作系统: 我们自己在上面装一个内核,内核上面有一个用户空间,用户空间里面跑进程。但是运行内核并不是我们主要目的,内核核心作用在于资源分配和管理。
就是说真正在应用空间跑的应用程序才是能产生生产力的,就好比我们跑一个web服务,内核其实很少提供服务。
而出于通用目的的而设计的资源管理平台,操作系统管理内核。我们并不太需要:
但是内核也不得不有,原因在于要想在一组硬件平台跑软件程序,而现在的软件都是针对于内核调用和系统调用,库调用研发的,而不安装这些没法运行程序,所以内核看上去没多大用,但是也必不可少;
更何况,我们一旦有了用户空间后,里面运行很多进程,这些进程为了协调也需要内核。
但假设我们创建一个虚拟机,只为了运行一个nginx,tomcat,却不得不去安装内核,用户空间,再去跑tomcat,代价就有点大了。
而在这里如果我们用二级虚拟化来分析的话:
如果为了运行一个进程,就要实现两级调度和资源分派。
第一,自己虚拟机有一个内核,已经实现了一次内存虚拟化,cpu调度以及IO调度和io 管理。
但是真正虚拟机也是被宿主机内核管理一次,这个中间浪费可以想一下。
传统的主机虚拟化技术,确实能让我们一组硬件平台之上实现跨系统传进的隔离和试验,调试,资源高效利用。而带来的资源开销不容忽视的,而很多时候,我们创建虚拟机只是为了运行一个和几个附有生产责任的进程而已,为此;
减少中间层就是一个好的办法,
比如在二级虚拟化我们把虚拟机那一层给抽掉,只保留进程,但是我们加虚拟机就是为了环境隔离,比如说一台机器跑两个或者五个nginx,我们一台机器没有那么多套接字和80端口。
而我们虚拟机就是为了资源隔离,就算把里面的nginx翻江倒海,坏的也是哪一个虚拟机。
所以这里的隔离才是我们的目标,我们虽然想抽掉这一层内核,但是不能让他回到在一个锅里吃饭那个环境,所以要让每一个组进程互相不可干扰的,只不过共享一个底层资源而已。
因此我们想要的环境就是:
创建一个又一个隔离环境,我们要运行隔离的程序就让他跑在隔离环境中,内核提供的是内核空间,进程试运行在用户空间,而这里就能实现将用户空间隔离成多个用户空间,互不干扰,这里一般都有一个空间是有特权的,一般第一个。而这里众多用户空间运行的都是同一个内核,被同一个内核管理的。但是运行时候能看到的边界只能是当前用户空间的边界,虽然没有主机级虚拟化隔离那么彻底。
更重要是,这个用户空间放进程,给进程提供运行环境,并且保护内部进程不被其他进程所干扰.叫做容器.
虚拟的隔离环境管理器
一层硬件平台容器不是什么新概念,最早出现在2000年,当年叫jail,监狱,监禁之意,里面就像一个沙箱,就算里面那个程序bug,有了故障,异常行为,也无法影响这个容器之外的程序运行,这也是jail初衷。
容器并非起源于 Linux,但开源世界的最精彩之处就在于借鉴、修改和改进,容器也不例外.
但这个概念非常有吸引力。
2001 年,通过 Jacques Gélinas 的 [VServer 项目,]隔离环境的实施进入了 Linux 领域。正如 Gélinas 所说,这项工作的目的是“在高度独立且安全的单一环境中运行多个通用 Linux 服务器 [sic]。” 在完成了这项针对 Linux 中多个受控制用户空间的基础性工作后,Linux 容器开始逐渐成形并最终发展成了现在的模样。
一般来讲,就算一个程序被远程劫持在里面搞起破坏,他的边界也仅仅是哪个容器的边界,最初只是为了应用的安全运行。
后来有人把这个技术山寨到Linux平台上,叫Vserver(chroot),在一个子目录定义一个根,让里面的程序以为他就是根。
chroot他能实现的你看上去的那层空间,底层还是同一个内核,进程运行是特权模式还是普通模式,表面很简单,真正实现起来涉及东西至少要有;
在一个单独用户空间当中,它主要目的是隔离使用,要让里面进程以为他就运行在底层内核之上,有六点:
为了容器机制的实现,Linux内核对着六种明成空间原生支持,namespaces。直接通过系统调用对外进行输出,
直到今天,所谓的容器就是靠六个namespaces和chroot来实现的。
听上去容易,这六种名成空间有一个是到内核3.8才实现的,所以要想完美使用容器,要内核版本3.8以上。centos6天然排除在外.
namespace | 系统调用参数 | 隔离内容 | 内核版本 |
---|---|---|---|
UTS | clone_newuts | 主机名和域名 | 2.6.19 |
IPC | clone_newipc | 信号量、消息队列和共享内存 | 2.6.19 |
PID | clone_newpid | 进程编号 | 2.6.24 |
Network | clon_newnet | 网络设备、网络栈、端口等 | 2..29 |
Mount | clone_newns | 挂载点(文件系统) | 2.4.19 |
User | clone_newuser | 用户和用户组 | 3.8 |
容器级虚拟化:
资源限制: 我们可以在整体资源做比例性分配,也可以在单一用户空间做核心绑定,你只能使用几个核;不然的话一个进程内存泄露整个系统都蹦了;或者一个进程占用了绝大部分CPU.
内存是压缩不了的,多一点都不能,一给就收不回来了,因为内存是压缩不了的;
实现这个Control Cgroups
划分成组后,在不同组内进行资源分配,组还可以再分。
即使有了chroot,nameespaces, control cgroups,容器的隔离能力比起主机级别虚拟化依然差很多,因为容器毕竟属于同一个内核,而主机级虚拟化那么好,因为内核本来就是天然的隔离,因此为了加强安全性,防止里面的进程通过漏洞绕过边界伸到别的用户空间,通过selinux各种安全机制加强容器的边界,为了支撑容器做的更加完善。
容器实现就是靠chroot,nameespaces,cgroups核心技术实现,而这些在内核已经实现了。
容器本来是靠jail启发有了vserver,后来为了让这种容器更加易用,
因为创建容器要自己写代码,系统调用,克隆等来实现的,但麻烦程度很大。
所以我们最好把实现容器的这种功能做成一种工具,极大的简化容器的使用,于是就有了LXC的解决方案,
LXCx container,最早一批真正把完整的容器技术用一组简易使用的工具和摸板来极大的简化了容器的使用方案。
lxc-create : 创建一个容器,template,摸板一组脚本,
创建一个明成空间后,这脚本自动执行后,自动实现安装过程,指向了你所打算创建哪一类明成空间的系统发行版所属的仓库,从仓库中镜像下载过来,安装,生成这个新的名成空间,就可以像虚拟机一样使用。
所有的明成空间都这样实现,而lxc就靠这样这一组工具包快速实现创建空间,利用模板完成内部所需要各种文件的安装,同时还有些工具可以通过chroot切换来切换去,于是我们就可以愉快的使用了,跟虚拟机没多大区别;
lxc在容器技术推广绝对功不可没,但依然有很高门槛:
虽然极大的简化了容器使用,但是在复杂程度没有多大降低的,更何况他的隔离性没有虚拟机那么好,
好处是性能资源方面的节约,让每一个进程直接使用宿主机的性能。
于是后来出现了docker:
lxc增强版,也不是容器,容器的一个易用前端工具。
lxc批量创建挺难,docker就在这个上面找突破点,docker早期核心就是lxc,他是lxc的二次封装发行版。
功能上利用lxc做容器管理引擎,创建容器时不再使用模板安装,而是使用一种镜像技术,
我们尝试着把一个操作系统用户空间所需要用到的所需要所有组件事先准备编排好,编排好后整体打包成一个文件,叫做镜像文件,这个镜像文件是放在一个集中统一的仓库中的,我把大家都会用到的最小化centos,ubuntu分别放在仓库内;
而在这里我们在这个最小化系统里面先装好源码nginx,再打包成一个镜像,也放入这个仓库中,当启动创建容器时候,需用镜像,把镜像拖到本地,基于镜像启动容器。所以docker极大的简化了容器使用程度;
比如说你想跑一个tomcat,nginx直接docker run就完成了
为了易于管理,docker还采用另外一种方式,在一个用户空间当中,我们尝试只运行一组进程或一个进程,我们目的就是为了运行一个有生产力的程序,比如我们在主机上要跑tomcat,nginx,nginx运行在nginx容器中,tomcat运行在tomcat容器中,二者用容器间通信逻辑进行通信,所以以后一个容器只运行一个进程,这也是docker的目的;
lxc就是当虚拟机使用,到时候管理极为不便;
而docker这里实现功能:
不用容器,一个内核之上运行各种进程 ,大家属于同一个用户空间,共享同一组主机名,用户,ipc,pid,在同一个可视范围内,如果一个黑客劫持一个进程以他做跳板可以威胁到其他进程
而docker,把他们给圈起来了,彼此间不可见,而且这个容器只为了这一个进程,最小化定义的;
坏处,占用更多空间,如果服务坏了,调试工具只针对一个容器有效,而如果加上调试工具违反了唯一进程目的,所以带来问题:本来调试一个进程极为简单,可能没有工具:
而要想调试得突破他的边界:
好处;删除了不影响别人:
给运维带来极大不便利,给开发带来巨大好处,分发容易了,一次编写到处运行。现在环境都是异构的,
centos5,6,7/Ubuntu/deepin/suse/kali/redhat/AIX
要开发一个软件,要开发每一种平台的软件,各自组织一个团队开发,只需要打包一个镜像,不管你是windows,linux,unix跟内核没关系,跟操作系统没关系,他有自己的明成空间
跟java类似这种效果,但是java有很多版本,6,7,8
以前部署需要发布,变更,故障处理
有了镜像,直接one,就行了,但是还需要接路由器和调度器,如果有一个容器编排工具,之间run结束,甚至连run都不需要你手动执行;
像以前的java容器只能支持java一种语言;
而docker不会管你是什么语言;
随之带来运维的问题,发布操作用编排工具来实现,docker必须要使用编排工具来管理,不用的话手动管理比我们直接管理应用程序更麻烦,增加我们运维环境复杂度;但确实是降低开发压力;
运维工作就是维稳,以往调试很容易,而容器可能没有调试工具,这么一来就意味着,我以后做镜像需要为每一个镜像自带调试工具,这么一来意味着做镜像需要自带一些工具,以前能共享的,现在不能,但他们却是隔离的;
docker还有一个好处: 批量创建,他创建容器采用
分层构建,联合挂载;使得我们以后镜像分发没有那么庞大,比如说我在一个系统上运行三个容器,都是基于底层centos构建,在这里只用一个centos基础镜像,三个上层nginx,tomcat,mariadb,底层镜像是共享的,底层镜像是只读的,要想改,在每一层联合挂载镜像栈最顶层额外附加一个新层,这个层才是能读能写的;
迁移很困难,如果要把容器迁移到其他地方,但这里是有状态的,真正在使用容器时,不会在本地存储有效数据,他会在文件系统上共享存储,而用户存储数据,这个服务不小心宕掉了,再找一个主机重新数据加载就行了,再访问数据还在,所以数据脱离宿主机,脱离容器而持久,容器可以丢到任何主机上;
存储需要一个外置持久性存储,程序是由指令+数据组成,
把容器当进程使用,启动一个容器,就是为了运行一个进程,进程一终止,把容器删了,不要了,下次重新创建,重新挂载
容器不需要持久,容器和进程一样有生命周期,从创建而开始,从停止到结束,跟我们主机都没多大关系,可以运行在任何主机上;
在docker之上建设一个层次,看那个主机更闲,来个调度法则,如果需要持久数据,给个web存储空间,挂载上去存储数据,一旦任务结束直接容器一删,结束,这个组件能帮我们把要启动容器调度于整个底层集群环境中某一个docker主机之上,当要构建lnmp,谁先启动,docker就解决不来这种功能,我们需要一个docker基础之上,能够把这种应用程序依赖关系,从属关系,隶属关系反映在启动关闭时的次序和管理逻辑中,这种功能叫容器编排工具;
google使用容器有十几年历史了,据说每一周销毁和新建容器多达几十亿。
docker因缘巧合摸到了这个门道,并且做成开源软件,谷歌就坐不住了,自己本来做为独门武器,那小子居然找到一种办法还公开所有人使用,本来我最有话语权,秘而不宣藏起来,这样才能称为独门武器,必要时候必杀技;
但是docker已然独霸话语权了,好在docker也不是铁板一块,后来出来出来另一个公司,谷歌就在后面大力扶植反对派,后来发现难以跟docker抗衡,上不来台面;
容器编排工具在谷歌已经跑了十几年了,该踩的坑都踩的差不多了;
docker三两年做不到;
于是kubemetes横空出世,占据了百分八十的市场,成为市场的标准,还成立了CNCF 容器标准组织,docker有一个问题,docker在编排上没有经验,义无建树,技术没走好,没有吸引更多的土豪进来投资,上市做独角兽,虽然互联网上火的不要不要的,但是无法变现,决定,把开源版拆分为企业版和社区版,将社区改名,把docker流量引入企业版,后来改名叫moby,把所有docker引入企业版,
之所以这样 docker是因为一家商业公司,谷歌在做k8s时候向大家表明我是没有任何意图的,于是把k8s源代码捐给了cncf,cncf是由很多组织联合成立的,主导权不再属于谷歌,属于IMB,微软等等,不会被人说想把k8s私有化,一年四个版本发布,go研发的
后来docker研发了一个容器引擎,libcontainer,替换了lxc,docker已经被cncf挟持了,cncf自己玩,把docker排除在外,如果以后容器要走下去肯定要开源,标准化,谁来负责标准化,cncf就可以做,定义标准,但这样太欺负docker了,所以给docker个机会,你来定标准化,同时做一款开源软件。
现在新的docker引擎已经是runC了,
虽然k8s支持很多种容器,但常见的还是docker+k8s;
docker架构形式:只考虑单机之上,整体架构是这样的:
整体是一个dockerhosts: docker server端
dockerhost 就是运行有docker进程(守护进程)的主机,被称为docerhost,dockerserver;
docker接收到创建和启动容器命令后,将在本地创建容器,一个dockerhost上可以启动多个容器,此处我们可能运行的分别不属于各种不同程序的容器,而容器取决于镜像来实现,如果本地没有,dockerdaemon自动链接到registries上,而后从中获得镜像后,先存储到本地一个能够专门存储所谓镜像存储空间中,要求得是特殊并且特殊的文件系统,overlay2,
这里面可能有多个镜像文件,镜像本身是只读的,而且镜像在registries放的时候仓库名就是应用程序名,而后仓库内可以放多个镜像,而且这些镜像通常属于同一个应用程序不同版本,我们用标签来识别;
docker镜像:
含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器:
采用分层构建机制,大体分为两层,最底层为bootfs,其之为rootfs
真正让用户拿来去构建用户空间并运行进程容器的是rootfs;
bootfs: 用于系统引导的文件系统,包括bootloader和kernel ,容器启动完成后会被卸载以节约内存资源
这里的kernel仅仅用于引导并启动一个用户空间,启动完之后就没有了以节约内存资源,毕竟很有可能我们用户空间跟底层内核还是有一点不同之处的,向上就是rootfs了;
传统模式中,系统启动时,内核挂载bootfs时会首先将其挂载为只读模式,完整性自检完成后将其重新挂载为读写模式;
docker中,rootfs由内核挂载为“只读”模式,而后通过“联合挂载技术”额外挂载一个“可写层”;
这里的分层构建
我们做一个apache镜像,运行httpd镜像,我们很有可能在一个底层的非常基础系统镜像之上一个纯净最小化centos版本,在他之上添加一个编辑器,相当于vim,除此之外添加一个httpd,每添加一个软件都是一个独立的层次,这里是三层,底下bootfs那一层在容器启动时,一旦被引导了完了rootfs时候再卸载并移除,不是删除文件,而是从内存中移除;
而这时候底层只有三层,base image 用来构建一个系统基本组成,/bin;如果要用到额外一个工具,需要额外安装;
但是对于我们镜像来讲,底层镜像是不会动的,额外安装一个vim 他会在里面额外生成一个vim 层,再装个nginx,生成个nginx层;叠加在一起挂载的,这三层都是只读的,因此,对于一个容器来讲,仅能在writoble上能写,而且如果删除容器,writable也会被删除;
含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器:
采用分层构建机制,大体分为两层,最底层为bootfs,其之为rootfs
真正让用户拿来去构建用户空间并运行进程容器的是rootfs;
bootfs: 用于系统引导的文件系统,包括bootloader和kernel ,容器启动完成后会被卸载以节约内存资源
这里的kernel仅仅用于引导并启动一个用户空间,启动完之后就没有了以节约内存资源,毕竟很有可能我们用户空间跟底层内核还是有一点不同之处的,向上就是rootfs了;
镜像分层构建和联合挂载依赖于文件系统的支撑
早起用到的是Aufs,高级多层统一文件系统:
最早被docker拿来用于实现联合挂载的Linux文件系统,
aufs是之前的unionfs重新实现,重写后依然很烂,三万行代码,一个ext4才四五千代码,这是要被整合进内核的,因此被申请时,次次被拒绝,一直到不申请,aufs一直都不是内核中自有的文件系统,想用需要向内核打补丁,centos不会干这种事情,因为他们以保守稳定为初衷,ubuntu是很早一批把aufs打包进内核,早些时候想要使用docker需使用ubuntu.
aufs的竞争产品是overlayfs(),后者自从3.18版本才开始被合并到linux内核;
docker的分层镜像,除了aufs,docker还支持btrfs,devicemapper和vsf等;
docker默认是aufs; centos7用的是devicemapper;在试用联合挂载很差,不稳定,因为它使用target driver;
比较成熟的支持的文件系统必须要能够是docker info当中的overlay2,xfs,overlay2是一种抽象的二级文件系统,他需要建立在本地文件系统之上;
构建镜像时,镜像做好之后,应该有一个统一存储的位置,叫做doceker registry
启动容器时,docker daemon会试图从本地获取相关的镜像: 本地镜像不存在时,将其从registry中下载该镜像并保存到本地;
如果我们没有特别指定,那么他就是registry,如果要指向别的registry我们必须在镜像的访问路径当中给明服务器地址;否则访问默认的registry,除非我们修改默认;
OCI
由linux基金会于2015年6月创立
旨在围绕容器格式和运行时制定一个开放的工业化标准
RunC: 无论是客户端还是服务端,都由docker一个程序提供,他有很多子程序,他可以监听在一个套件字之上;
docker有三种类型套接字,
docker启动容器就是基于镜像启动,在镜像基础之上,为一个容器创建一个专用可写层;
containers:容器,
lmages: 镜像 镜像来自于Registry,注册表,可以称为docker的镜像仓库,默认就是docker hub,默认本地是没有的,镜像是分层构建的,所以下载到本地后,可以共享多个上层镜像使用,因为镜像是只读的,所以启动容器就是基于镜像来启动,在镜像基础上为一个容器创建一个专用的可写层,从而来启动这个容器。
所以这里镜像也需要在docker本地存储,因此这有专门的仓库来放镜像,而镜像拥有几十万之多,所以放到一个公共的仓库,需要时候拉取过来加载到本地,这里的协议是http/https,默认是加密的,需要明确定义成不安全才可以使用;
docker的运行过程中尤其是创建容器时可能有一点慢,原因是他要下载一次镜像,取决于他的宽带;
因为服务器在国外, 为了能使加速访问,docker在大陆这边做了一个docker镜像服务器,docker.cn,加速不太好,可以使用阿里,科大,所以要想使用docker,必须要能接入到互联网。
docker镜像是分层构建的
仓库: 一个docker拥有两重功能,第一,他提供镜像提供的仓库,第二,他还提供用户来获取镜像时的认证等功能,还提供了当前服务器所有可用镜像的索引;
所以镜像也会有应用到不同程序版本的镜像,为了让镜像跟应用程序版本有一定的关联,给镜像外面加了一个标签,仓库名+标签才能唯一标识一个镜像。如果只给了仓库名,那就是默认最新版;一个镜像可以有多个标签,在仓库名+标签外面加上 stable最新版,稳定版什么的;
镜像是静态的;
如果我们要是 就使用docker,如果我们要使用在这的仓库就下载docker,区别EE和CE;
Docker 从 1.13 版本之后采用时间线的方式作为版本号,分为社区版 CE 和企业版 EE,社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比如经过官方测试认证过的基础设施、容器、插件等。
社区版按照 stable 和 edge 两种方式发布,每个季度更新 stable 版本,如 17.06,17.09;每个月份更新 edge 版本,如17.09,17.10。
在 Ubuntu/Debian 上有 UnionFS 可以使用,如 aufs 或者 overlay2 ,而 CentOS 和 RHEL 的内核中没有相关驱动。因此对于这类系统,一般使用 devicemapper 驱动利用 LVM 的一些 机制来模拟分层存储。这样的做法除了性能比较差外,稳定性一般也不好,而且配置相对复 杂。Docker 安装在 CentOS/RHEL 上后,会默认选择 devicemapper ,但是为了简化配置, 其 devicemapper 是跑在一个稀疏文件模拟的块设备上,也被称为 loop-lvm 。这样的选择是 因为不需要额外配置就可以运行 Docker,这是自动配置唯一能做到的事情。但是 loop-lvm 的做法非常不好,其稳定性、性能更差,无论是日志还是 docker info 中都会看到警告信 息。官方文档有明确的文章讲解了如何配置块设备给 devicemapper 驱动做存储层的做法,这 类做法也被称为配置 direct-lvm 。
除了前面说到的问题外, devicemapper + loop-lvm 还有一个缺陷,因为它是稀疏文件,所 以它会不断增长。用户在使用过程中会注意到 /var/lib/docker/devicemapper/devicemapper/data 不断增长,而且无法控制。很多人会希望删 除镜像或者可以解决这个问题,结果发现效果并不明显。原因就是这个稀疏文件的空间释放 后基本不进行垃圾回收的问题。因此往往会出现即使删除了文件内容,空间却无法回收,随 着使用这个稀疏文件一直在不断增长。 所以对于 CentOS/RHEL 的用户来说,在没有办法使用 UnionFS 的情况下,一定要配置 direct-lvm 给 devicemapper ,无论是为了性能、稳定性还是空间利用率。 或许有人注意到了 CentOS 7 中存在被 backports 回来的 overlay 驱动,不过 CentOS 里的 这个驱动达不到生产环境使用的稳定程度,所以不推荐使用。
对于大部分企业来说,搭建PaaS既没有那个精力,也没那个必要,用Docker做个人的sandbox用处又小了点。可以用Docker来标准化开发、测试、生产环境。
Docker占用资源小,在一台E5128G内存的服务器上部署100个容器都绰绰有余,可以单独抽一个容器或者直接在宿主物理主机上部署samba,利用samba的home分享方案将每个用户的home目录映射到开发中心和测试部门的Windows机器上。
针对某个项目组,由架构师搭建好一个标准的容器环境供项目组和测试部门使用,每个开发工程师可以拥有自己单独的容器,通过 docker run -v 将用户的home 目录映射到容器中。需要提交测试时,只需要将代码移交给测试部门,然后分配一个容器使用 -v加载测试部门的 home目录启动即可。这样,在公司内部的开发、测试基本就统一了,不会出现开发部门提交的代码,测试部门部署不了的问题。
测试部门发布测试通过的报告后,架构师再次检测容器环境,就可以直接交由部署工程师将代码和容器分别部署到生产环境中了。这种方式的部署横向性能的扩展性也极好。
注意
我们使用docker image ls时候会发现,镜像体积的所占用空间在Docker Hub上看到的镜像大小不同,比如nginx镜像在docker hub官网上是50多兆,而把他pull下来就变成一百多兆了,这是因为docker hub所显示大小是网络传输中更关心的流量大小,而docker image ls显示的是镜像下载到本地展开后的各层所占空间的综合,因为镜像下载到本地后,更关心的是磁盘空间占用的大小.
另一个需要注意问题是,docker image ls列表中的镜像体积综合并非是所有镜像实际硬盘消耗,由于Docker镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能因为使用相同的基础镜像,从而拥有共同的层,由于Docker使用UnionFS,相同的层只需要保存一份即可,因此实际占用硬盘空间很可能比这个列表镜像大小的总和小的多.
启动容器有两种方式,一种基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动.
因为docker的容器太轻量级了,很多时候用户都是随时删除和重建.
当利用docker run来创建容器时,Docker在后台运行的标准操作包括:
使用docker命令需要管理员权限,如果希望每次输入docker相关命令时,不用sudo,可通过以下命令进行设置
官方提供的ubuntu系统镜像,工具命令很少,如希望内部安装ping、ifconfig网卡等工具,可以通过以下命令进行设置[需要联网,而且耗时]
__EOF__
标签:还需 运行环境 moby dev 分类 load width 合成 server
原文地址:https://www.cnblogs.com/lonelyxmas/p/13125953.html