白话容器基础四重新认识_第1页
白话容器基础四重新认识_第2页
白话容器基础四重新认识_第3页
白话容器基础四重新认识_第4页
白话容器基础四重新认识_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

123456789fromflaskimportimportsocketimportosapp=Flask(namehtml=o{name}!</h3>""<b>Hostname:</b>returnhtml.format(name=os.getenv("NAME","world"), =="mainapp.run(host='',在这段代码中,我使用Flask框架启动了一个Web服务器,而它唯一的功能是:如果当前环境中有“NAME”这个环境变量,就把它打印在“o”后,否则就打印“oworld”,最后再打印出当前环境的hostname。这个应用的依赖,则被定义在了同下的requirements.txt代码$cat代码代码123456789#使提供的Python开发镜像作为基FROMpython:2.7-#将工切换为WORKDIR#将当 下的所有内ADD./app#使用pip命令安装这个应用所需要RUNpipinstall--trusted-host-r#允许外EXPOSE80端设置环境变17ENVNAME#设置容器进程为:pythonapp.pyPythonCMD["python",亮的词语),描述我们所要构建的Docker镜像。并且这些原语,都是按顺序处理的。Python代码代码FROMRUNapt-getupdate-yRUNapt-getinstall-ypython-pippython-devbuild-其中,RUNs命令的意思。而WORKDIR,意思是在这一句之后,Dockerfile后面的操作都以这一句指定的/app CMD,Dockerfilepythonapp.pyapp.pyapp/app.py。所以,CMDpython”,“app.pydocker另外,在使用Dockerfile时,你可能还会看到一个叫作ENTRYPOINTCMDDockerENTRYPOINTCMD不指定ENTRYPOINT时,比如在我们这个例子里,实际上运行在容器里的完整进程是:/bin/shc“pythonapp.pyCMDENTRYPOINTENTRYPOINTCMD当前(即Dockerfile所在的)里的文件,到指定容器内的当中。读懂这个Dockerfile之后,我再把上述内容,保存到当前 代码代码$ Docker制作这个镜像了,在当前执行:代码代码1$dockerbuild-oworld其中,-tTag,即:起一个好听的名字。dockerbuild当前下的Dockerfile文件,然后按照顺序,执行文件中的原语。而这个过程,实际上可以DockerDockerfile并没有明显地修改文件的操作(比如,ENV原语),它对应的层也会存在。只不过在外界看代码代码1234$dockerimageIMAGE法,查看这些新增的层在AuFS路径下对应的文件和了。dockerrun代码代码1$dockerrun-p 代码代码1$dockerrun-poworldpythondockerps代码代码123$dockerCONTAINERd"python10secondsp4000:80Docker804000代码代码$ oWorld!</h3><b>Hostname:</b>否则,我就得先用dockerinspect命令查看容器的IP地址,然后“http://<容器IP地DockerHub上给的人,我要怎么做呢为了能够上传镜像,我首先需要一个DockerHub账号,然后使用dockerlogin命令登dockertag代码代码1$dockeroworld 注意:你自己做实验时,请将"geektime"替换成你自己的DockerHub账户名称,比如zhangsan/ docker代码1$dockerpushgeektime/DockerHub此外,我还可以使用dockercommit指令,把一个正在运行的容器,直接提交为一个镜像。一代码代码$dockerexec-itd3 d:/app#touch445d:/app#$dockercommit d 这里,我使用了dockerexec命令进入到了容器当中。在了解了LinuxNamespace的机制后,你应该会很自然地想到一个问题:dockerexec是怎么做到进入容器里的呢?比如,通过如下指令,你可以看到当前正在运行的Docker容器的进程号(PID)是代码代码$dockerinspect--format'{{.State.Piddproc25686Namespace410-]510-]610-]710-]lrwxrwxrwx1rootroot0Aug1314:05pid_for_children-> lrwxrwxrwx1rootroot0Aug1314:05user-> lrwxrwxrwx1rootroot0Aug1314:05uts-> LinuxNamespaceproc/[进程号]/ns应的虚拟文件,并且到一个真实的Namespace文件上。有了这样一个可以“holdLinuxNamespaceNamespace一些很有意义事情了,比如:加入到一个已经存在的Namespace当中。入”这个进程所在容器的目的,这正是dockerexec的实现原理。代码代码1#definemain(intargc,char*argv[])intfd=open(argv[1],if(setns(fd,0)==-1)}execvp(argv[2],}Namespace文件的路径,比如/proc/25686/ns/net;而第二个参数,则是你要在这个Namespace里运行的进程,比如/bin/bash。文件的描述符fd交给setns()使用。在setns()执行后,当前进程就加入了这个文件对应的LinuxNamespace当中了。Namespace中:1gcc-oset_ns2./set_ns/proc/25686/ns/net34 Link HWaddr inet inet6addr:fe80::42:acff:fe11:2/64UPBROADCASTRUNNING RXpackets:12errors:0dropped:0overruns:0TXpackets:10errors:0dropped:0overruns:0collisions:0 RXbytes:976(976.0 TXbytes:796(796.013 Linkencap:Local inet inet6addr:::1/128UPLOOPBACK RXpackets:0errors:0dropped:0overruns:0collisions:0RXbytes:0(0.0TXbytes:0(0.0实际上,在setns()之后我看到的这两个网卡,正是我面启动的Docker容器里的网卡。也bin/bash(PID=25686)NetworkNamepace,它看到的网络设备与这个容器里是一样的,即:/bin/bash在宿主机上,你可以用ps指令找到这个set_nsbin/bash进程,其真实的PID代码代码#在宿主机psaux|grep 284990.00.0199443612S 0:00PID=28499Namespace,你就会代码代码12345$ls-llrwxrwxrwx1rootroot0Aug1314:18/proc/28499/ns/net->]$ls-llrwxrwxrwx1rootroot0Aug1314:05/proc/25686/ns/net->]在 (PID=25686)指向的NetworkNamespace文件完全一样。这说明这两个进程,共享了这个名叫net:[ ]的NetworkNamespace。NetworkNamespacenet代码代码1$dockerrun-it--netdbusybox这样,我们新启动的这个容器,就会直接加入到ID=4ddf d的容器,也就是我们前面的创建的Python应用容器(PID=25686)的NetworkNamespace中。所以,这里ifconfig而如果我指定–net=host,就意味着这个容器不会为进程启用NetworkNamespace。这就意味着,这个容器拆除了NetworkNamespace的“墙”,所以,它会和宿主机上的其他普dockerexecLinuxNamespacedockercommitdockercommit,实际上就是在容器运行起来后,把最上层的“可读写层”,加上原先容器镜而正如前所说,InitdockercommitDockerDockerHub代码1$dockerpushgeektime/当然可以,这个统一存放镜像的系统,就叫作DockerRegistry。感的话,你可以查Docker的文档,以及VMware的Harbor项目Docker:Volume(数据卷)rootfsMountNamespace,构建出了一个同宿主 这正是DockerVolume要解决的问题:Volume机制,允许你将宿主机上指定的 在Docker项目里,它支持两种Volume方式,可以把宿主机 挂载进容器的/test目代码$dockerrun-v/test$dockerrun-v/home:/test 挂载进了容器的/test目 ,那么Docker就会默认在宿主机上创建一个临 MountNamespaceMountNamespacechroot(pivot_root)之前,容器进 rootfschrootVolume(比如 ),挂载到指定的容 (比如 )在宿主机上对应 (/[可读写层上,这个更重要的是,由于执行这个挂载操作时,“容器进程”已经创建了,也就意味着此时Mount容器内部的这个挂载点的。这就保证了容器的性不会被Volume打破。注意:这里提到的"容器进程",是Docker创建的一个容器初始化进程(dockerinit),而不是应用进程(ENTRYPOINT+CMD)。dockerinit会负责完成 、配置hostname等一系列需要在容器内进行的的PID=1的进程。而这里要使用到的挂载技术,就是Linux的绑定挂载(bindmount)机制。它的主要作用就 其实,如果你了解Linux内核的话,就会明白,绑定挂载实际上是一个inodeLinux操作系统中,inode可以理解为存放文件内容的“对象”,而dentry,也 是这个inode所使用的“指针”正如上图所示,mountbindhometesthometest/test的dentry,重定向到了/home的inode。这样当我们修改 的inode。这也就是为何,一旦执行umount命令,/test 复:因为修改真正发生在的,是/home 所以,在一个正确的时机,进行一次绑定挂载,Docker就可以成功地将一个宿主机上的 这样,进程在容器里对这个/test 那么,这个/test commit提交掉呢?这个原因其实我们前面已经提到过。容器的镜像操作,比如dockercommit机空间的。而由于MountNamespace的作用,宿主机并不知道这个绑定挂载的存在。以,在宿主机看来,容器中可读写层的 不过,由于Docker一开始还是要创建/test这个 作为挂载点,所以执行了dockercommit之后,你会发现新产生的镜像里,会多出来一个空的/test 作,又不是挂载操作,MountNamespace对它可起不到“障眼法”的作用。 oworld容器,给它一个Volume,挂载在容器里的 上代码代码$dockerrun-d-v容器启动之后,我们来查看一下这个Volume代码代码$dockervolume VOLUME 然后,使用这个ID,可以找到它在Docker工 下的volumes路径代码1$ls这个_data文件夹,就是这个容器的Volume在宿主机上对应的临时 接下来,我们在容器的Volume里,添加一个文件text.txt:代码$dockerexec-itcf53b766fa6fcdtouch这时,我们再回到宿主机,就会发现text.txt已经出现在了宿主机上对应的临 里代码$ls可是,如果你在宿主机上查看该容器的可读写层,虽然可以看到这个/test 的(关于如何找到这个AuFS文件系统的路径,请参考我上一次的内容):11$lsVolumedockercommit以上内容,就是DockerVolume的原理了总的主要场景。熟悉了这些操作,你也就基本上摸清了Docker容器的功能。LinuxNamespace、Cgroupsrootfs这个容器进程“pythonapp.py”,运行在由LinuxNamespace和Cgroups构成的环境合挂载在一起的rootfsrootfsDockerDockerInit/etc/hosts容器的Volume的挂载点,也出现在这一层。思考DockerNamespacecgroupNamespace?它是Linux4.6之后新增加的一个Namespace,你知道它的作用吗?如果你执行dockerrun-v/home:/test的时候,容器镜像里的/test下本来就有内容的话,你会发现,在宿主机的/home下,也会出现这些内容。这是怎么回事?为什么它们没有被绑定挂载隐呢?(提示:Docker的“copyData”功能)PythonCPUMemory限制,然后启动它。根据我们前面介绍CgroupsCgroups归科技所有 精选留言

一步 这样把原理刨根究底的讲解出来,很好,理解的很透彻黄文 收货很大,感谢!请教一个问题,请问在容器内部如何获取宿主机的 谢谢作者回复单靠容器,在开的情况下是拿不到的。但是有了kbenetes之后这些系统信息都可以从环境变量里拿到。这个功能叫donardpi 这节干货满满啊与路同 有预感专栏会破2假装 听来清晰易懂,省去不少学习时间蔡鹏 dockerrun时指定-v挂载宿主机 到容器 ,即使容器原有 内有数据,也会被我宿主 作者回复这个行为其实是可配置的陶希 想知道云服务器等技术是不是也是通过namespace+cgroup作者回复当然多 一切从问题出发,根据问题理解答案,总结问题如下:一、docker镜像如何制作的两种方式是什么?二、容器既然是一个封闭的进程,那么外接程序是如何进入容器这个进程的呢?三、dockercot对挂载点oume内容修改的影响是什么?四、容器与宿主机如何进行文件读写?或volume五、Docker的copyData六、bindmount机制是什么?七、cgroupNamespace的作用是什么? 非常感谢老师的讲解,咱们这个有群可以互相交流吗? 作者回复如果你用的是k ontners这种基于虚拟化的容器,才可以实现。但原生其实也不提供这个功能。择 在等更新,沙发!Leon 谢谢老师!前4节高屋建瓴地介绍了ocker和K8S的演进历史,接着4节ocker基础深入浅出地介绍了重要的基础知识,受益匪浅,这4节ocker基础再次让我体会到了醍醐灌顶的感觉。多 课程干货满满,一堂课下来不听上几遍根本无法掌握课中的知识点,一切从问题出发,能明白课中解决了什么问题或提出了什么问题,从这个角度出发,更正理清课中讲的知识点,总结内容如下:一、docker镜像如何制作的两种方式是什么?二、容器既然是一个封闭的进程,那么外接程序是如何进入容器这个进程的呢?三、dockercot对挂载点oume内容修改的影响是什么?四、容器与宿主机如何进行文件读写?或oue是为了解决什么题?五、ocker的copyata功能是什么?解决了什么问题?六、bindmount机制是什么?七、cgroupNamespace的作用是什么?兽 讲得非常不错,曾经翻遍了几乎所有Docker文档,都没中来得深刻,谢谢。 话,这些CMD执行的yum命令修改的内容还属于只读层?作者回复任何镜像里的内容,都属于只读层。commit之后的东西当然也属于只读层。一 你好,磊哥,谢谢你讲得这么详细,我有一点不是很清楚:容器中的主进程在系统调用或调用一些lib时,调用到的和容器只读层提供的lib吗作者回复 !有些地方自己折腾狠难理解到!多谢老师高维指点。 请问docker挂载有何限制没,是否随便一个 都可以挂载?在容器里应该是root用户,岂是可以对 无节制地操作,哪怕原本主机 中有些文件并不允许当前用户?是否可以相应限制作者回复。至于用户权限,是有 namespace可以做一定的限制 如果在docker容器中部署oracle,实际生产环境有没有人这么干?作者回复好像oracle自己就有个方案? 所以说dockerexec每次都会创建一个和容器共享namespace的新进程?作者回复可以这么理解,i.e.spawnanewprocessinexisting蓝色天 Linux基础薄弱,理解起来有点吃力作者回复不太理解的地方,可以提出来微 很清 确实清晰了很多了不过还是有不清楚的点作者回复可以提出来讨论 老师您好!请问,搭建的Harbor服务器,在项目管理页面的右上角会显示我有作者回复不了解 老师好,又来问您问题了。生产中有没有什么好的工具管理本地的dockerregistry,比如磁盘作者回复harbor孙 4.6内核之前,查看/proc/$PID/cgroup,或者挂载cgroup时,在容器中会看到整个系统的这个问题感觉像陷阱,挂载后改变的是home的inode值(/test的inode),有数据就作者回复2.docker 挂载文件夹能理解,但是如果挂载宿主机的某一文件到容器,为什么需要容器事先存在同名的这个文件呢?作者回复不需要啊,文件 都不需要事先存在韩懿 豆沙 你好我用dockerrun起了app这个容器之后,查看aufs里层的信息,读写层为什么会和init层是同一个层呢?不是一个会被打包一个不会被打包么?#cat/sys/fs/aufs/si_cc04a4d4a9a38631/br[0- 作者回复你没分清楚 和 的区别 干货很多,要反复琢磨一下了!追寻云的痕 docker-ee的实现不是基于Hyper-V作者回复在windows上一共就两种方案hyperv和wincontainer,它必然得支持 只会最后这个。dockerrun-p8000:80--cpuset-cpus="1"-m500M 木 张老师,能把搭建dockerk8s的环境简要说一下吗,比如使用ubuntu还是centos、rhel,什么作者回复看部署那篇 ;老师,有个地方还是不太明白,以下是你些的原文:ENTRYPOINTCMDdockerinit会负责完成根的准备、挂载设备和、配hostnameexecv让应用进程取代自己,成为容器里的PID=1的进程。我有以下疑问:2、这里的dockerinit和应用进程在宿主机中是两个不同的进程id么4、一个容器内部是否只有一个进程?,或者说容器只是一个房间(由aepce和cgrop组成),而其他的进程都是走进了这个房间,让大家以为这个房间就是一个系统,里面包含了这么多进程,其实在宿主机的角度他们都是一个个进程,只是共享了amepace和cgrop而已,这样理解对么?作者回复是。替换当然就是为了保证pd不变。注意,容器里的其他进程都是1号进程的子进程,不存在独立的说法。甄心 为什作者回复因为被到单独的netns里了 赞 请教一个问题,为啥子镜像的entrypoint会覆盖母镜像的entrypoint的作者回复因为dockerfile顺序buildShJin、 那么老师,请问有没有办法通过 -it的方式进入容器作者回复权限控制的办法很多,但这也啥意义呢?我手写一个 行的语言代码就可以加入容器的amespace啊。所以不随便给人root权限比较重要吧。 抱歉:再次进入image还是dockerrunimage,但没有指定volumn作者回复因为volume除非删除掉它还是在那台主机上,你在别的机器上拉镜像试试江宇 写的不错点 作者回复再次进入image是什 请问老师,镜像只提供文件系统,系统调用使用的宿主机的内核?这个感觉很模糊,不是很理解作者回复默念三遍内核共享侯强亮 公司研发环境用的oracle的12c容 cetos7都是版本3的内核,针对k8s,到目前为止有遇到过因为内核bg的问题必须从3切换到版本4的内核的场景吗,比如切换到btu?篇幅问题具体问题不方便在这里描述。主要是想了解下,是否有遇到过cetos有些比较棘手的问题,而不得不试图切换到其它os的场景呢 docket里面的用户和真实系统的会 docker启动用户用root好不 如果查看alpine:latest的挂 ,应该如何查找换句话说就是如何通过dockerimage的唯一id来查找出内部id(si_xxx)?作者回复遗憾的是,这个ID没有对应关系,最方便的做法是查看mnt 变化小鱼 老师的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论