设为首页 收藏本站
查看: 1729|回复: 0

[经验分享] 都9102年了,还不会Docker?10分钟带你从入门操作到实战上手

[复制链接]

尚未签到

发表于 2019-2-20 09:23:36 | 显示全部楼层 |阅读模式
Docker简述
  Docker是一种OS虚拟化技术,是一个开源的应用容器引擎。它可以让开发者将应用打包到一个可移植的容器中,并且该容器可以运行在几乎所有linux系统中(Windows10目前也原生支持,Win10前需要内置虚拟机),正所谓“一次打包,到处运行”。
  Docker容器的运行是完全的沙箱机制,相互之间不会有任何关联(除非自己串联集群)。网络、存储、进程等资源,不仅对于不同的容器是相互隔离,对于宿主机和容器直接也是隔离的,除非你手动映射暴露端口或者挂载存储卷。
  很多人不理解,Docker和虚拟机到底有什么区别。
DSC0000.jpg
DSC0001.jpg
从这两张结构图来看,Docker比虚拟机少了一层虚拟机操作系统,Docker的应用直接Docker引擎上运行。由于虚拟机需要一层操作系统,所以会导致虚拟机的体积非常大,通常在几G到十几G之间。并且通常一个虚拟机上,不只一个应用,因此对于整体的虚拟集群管理并不太友好,比较难做到灵活分配。
  而一个Docker镜像的体积大约在几十M到几百M之间,一般一个镜像只打包一个应用,由多个镜像组成一个完整的项目,并且镜像易于复制,可以跨平台运行,这样可以使项目的部署管理有更好的灵活性。所以Docker无论从资源消耗上、管理上、使用上都在虚拟机之上,因此我们又有何理由不使用这样的容器化技术呢?
  对于容器化技术的学习,可谓是深如海。从基本的镜像、容器操作,到镜像的打包、容器的部署,再到企业生产级的容器集群管理技术(Docker官方的Swarm、Google的Kubernetes),如此多的内容,并不是所有人技术人员都能一朝学会。不过除了生产级别的集群管理技术有难度意外,其他内容从学习使用的角度来说,其实是非常简单的,况且K8s这种东西,对于普通开发来说也是很少能接触到。
  说到这里,可能还有很多人觉得这个是公司层面、运维层面的操作,不是很了解Docker对于普通开发来说,意味着什么,对我们有什么好处?

  • 多办公环境,一键部署。假如你在公司一套开发环境,在家一套开发环境,当你公司的开发环境变更时,在家的环境就要跟着变,如果是使用Docker,将一些依赖型的应用,如Redis、ZK、Mysql等边缘服务都打包在docker里面。无论你在哪里改变了内容,只要在运行时更新下镜像,就可以按照最新的内容去执行了,不需要一个手动去安装,适配。
  • 联调测试,无需依赖他人。当后端完成对外的接口后,将后端应用打包进docker,这样无论是前端、测试,在何地何时都可以自己把容器启动起来进行联调测试,而不需要自己手动一步步地搭建这个后端环境。
  • ...
  下面就来一步步讲解下,普通开发所需要的Docker知识。
概念介绍
  学习Docker首先要了解下几个基础概念:

  • 宿主机,Host,运行Docker所在的物理机,是Docker运行的系统环境。
  • 镜像,Image,相当于一个程序模板,通过这个模板可以生成很多个相似的容器。可以理解为Java中的类,它本身不具备执行运行的能力,是一个对象抽象的模板。每个镜像可以有多个版本,用tag来区分。镜像可以通过Dockerfile来构建。
  • 容器,Container,Docker运行的最小单位对象。它是通过镜像实例化出来的一个可运行对象。容器的修改,可以提交反作用于镜像,更新这个容器的模板。
  • 仓库,Repository,用于存储管理镜像的仓库,类似于git管理代码的仓库一样,可以管理多版本的镜像。
  镜像、容器、仓库的关系如下:
DSC0002.jpg
一句话总结就是,从仓库中拉取镜像,利用镜像生成容器。
基本操作
  了解完Docker的基本概念,我们开始来开始学习下入门操作。此处省略所有的Docker安装过程,自己去官网下载就行了,基本是傻瓜式安装。
拉取镜像
  通过docker pull ${image_uri}:${image_tag}命令,可以从远程仓库(默认是Docker Hub)中拉取所需要的镜像。
  在Docker Hub的网站上可以搜索下自己需要的镜像以及版本。例如Ubuntu,上面提供了几个版本。
DSC0003.jpg
我们拉一下16.04版本的ubuntu镜像。然后通过docker images命令,查看保存在本地镜像,发现多了一个ubuntu的镜像。
DSC0004.jpg
容器创建、启动、停止、登入
  有了镜像以后,就可以通过docker run -it ${image_id}创建启动一个容器了。
  image_id是镜像的id,通过docker images能查看到,也可以是镜像名(REPOSITORY:TAG)。
  -it可以让你在启动后,连上容器的终端。连上终端后,就可以在里面随意操作容器里面的内容了。
DSC0005.jpg
  exit退出容器后,容器就会自动停止了。但是这个容器依然还存在,只是”关机“了。(可以通过ctrl+p,ctrl+q,退出容器登入,而不关闭容器)
  通过docker ps -a可以看到我们的容器已经Exited了。
DSC0006.jpg
  通过docker start ${container_id},我们把这个容器再次启动。通过docker ps(加上-a包含显示未启动的容器),可以看到容器的状态为UP
DSC0007.jpg
  同理,我们可以通过docker stop ${container_id}来停止容器,
  在用docker start命令的时候,如果不加上-a参数,默认不会连接上容器的。不过我们可以在start后,通过docker attach ${container_id}来登入容器。
DSC0008.jpg
  通过以上的基本操作,你基本可以利用docker当作一个虚拟机来使用了。如果想把容器和虚拟机的网络、存储打通,可以网上搜下了解下网络与卷挂载等容器设置。
更新镜像
  在上面的例子中,我们pull下来的仅仅是一个ubuntu的原始镜像,并没有过多的内容。下面我们在这个镜像的容器里面,安装一个jdk。
DSC0009.jpg
这样我们的容器里面就有一个jdk了,但是如果我们再用这个ubuntu原始镜像再创建一个容器,它是不会用这个jdk的。所以我们就需要把这个容器的内容,提交到镜像当中。
  通过docker commit ${container_id} ${repository}:${tag},在本地将容器内容提交到镜像当中。然后就可以拥有一个带jdk的ubuntu镜像了。
DSC00010.jpg
后面我们就可以利用这个镜像,生成带jdk的容器了。
  以上的更新仅限于在本地的镜像,如果想把容器推送到云端就需要用docker push命令。前提是你已经登录了仓库拥有权限。
镜像仓库
  上面提到,默认情况下,仓库是用Docker Hub。我们pull 和push都是在Docker hub上操作,但是如果镜像是内部私有使用的话,没有必要去使用Docker Hub,一个是网络慢,另一个是私有安全性问题。
  针对以上问题,有两种解决方法,一个是自己搭建私有服务,另一个是用云服务的镜像管理平台(如阿里云的“容器镜像服务”)。前者对于一般开发者来说并没有必要,而且还要搞认证的,比较麻烦,这里不细说。下面介绍下如何用阿里云服务作为自己的私有仓库。
  先在阿里云上创建一个镜像仓库,获得一个仓库地址,如registry.cn-shenzhen.aliyuncs.com/zackku/jdk。这里一个仓库地址,对应一种镜像(tag不同)。
  利用docker login,先对阿里云的服务进行登录。
DSC00011.jpg
  然后对上面的jdk镜像打tag(其实也是改仓库源的过程)
DSC00012.jpg
  最后把镜像推送到阿里云就行了。
DSC00013.jpg
  推送后,就能在阿里云的仓库上看到这个镜像。
DSC00014.jpg
  通过搭建私有仓库,我们就可以完全抛开宿主机的环境,构建好一个镜像,就可以到处运行了。
Dockerfile构建镜像
  从上面介绍,我们已经了解到,如何从拉取一个镜像、修改容器内容、提交镜像去构建一个我们所需要的镜像。但通过这些操作去构建一个镜像,一个是太繁琐,另一个问题是不清晰,没办法直观的了解镜像的构成。
  Dockerfile就可以很好的解决该问题。它可以通过编写一个构建过程,来一站式构建镜像。下面同样以ubuntu为基础镜像,安装jdk构建一个新镜像为例,看看Dockerfile是怎么写的。
DSC00015.jpg
  然后执行docker build -t registry.cn-shenzhen.aliyuncs.com/zackku/jdk2:1.0 .就能把镜像构建出来了。
DSC00016.jpg
Dockerfile高级技巧
  上面是Dockerfile的基本使用,但实际情况下我们并不像(或者说不仅是)上面描述那样去构建镜像。下面介绍两个常用的使用原则。
  分层构建。其实Docker的镜像是分层结构的,看回之前推送到远端仓库的例子。
DSC00017.jpg
红框里面就是镜像一层层的提交,如果这层已经本地构建过了,下次不需要构建了,同理如果远端已经有这层了,也不需要推送这层。而且这种分层是可以在不同镜像间共享的,例如不同的Java项目都是依赖于JDK的运行环境,那么它们就可以共用JDK这层镜像内容。
  所以,基于这样的特性,我们就应该要分层去构建镜像,抽象镜像共同点。具体操作的话,我们大致可以去分两次构建镜像,先构建一个base镜像,用于不同镜像的底层,例如Java项目的所有基础运行环境,然后再通过base镜像,构建develop表层的应用镜像。相当于把应用程序打包丢到develop层里面。并且这层要告诉Docker是怎么运行程序的。
  尽量构建小的base层。镜像的体积也是在使用Docker的时候要考虑的一个重要因素,因为如果镜像的体积过大,在更新镜像,拉取镜像的时候效率会低。尤其在刚刚所说的base层里面,如果base层做得太大太臃肿,里面程序过多,不仅仅体积大,还会让CPU、网络等资源消耗过大。其实我们在用Docker的时候,一般是一个容器只包含一个程序项目,关于这个程序的监控、健康等内容,在容器外通过k8s等集群管理去做,所以容器本身只需要保证自己的程序能够运行起来就行了。
  至于上面我用ubuntu作为基础的操作系统是比较多余的,这里推荐只用apline操作系统作为程序的最底层镜像,它是一款轻型的Linux发行版,系统体积与运行时的资源消耗都相当低,十分适合用于Docker容器。基于apline的操作系统,我们在上面添加自己所需要的环境,例如安装一个Tomcat、JDK等,从而构建一个base的镜像。
  上所说的base镜像,其实不太需要自己的写一层Dockfile,docker官方就直接提供了各种语言、环境的基础镜像,在github的docker-library里面。如果再有自己的团队的运行环境的要求,可以在这个Dockerfile基础上去添加修改即可,或者再抽象多一层。
  至于Dockfile怎么写,语法是什么,网上有大把详细的说明,由于篇幅问题,不在这里展开。
docker-compose启动集群
  前面已经介绍完一个单独的容器是如何构建与启动的了,但我们的项目往往不是只有一个容器的,把所有程序打包在一个容器不是正确的做法。所以我们怎么去管理启动这么多的容器,是一个必修的课题。在企业级的层面,有K8S,Swarm这种容器编排的管理工具,但稍微比较复杂,个人使用的话也没有太大必要。
  这里推荐用Docker官方的docker-compose,它可以把所有的容器编排方式写在一个文件里,然后通过docker-compose up命令,就可以把一套的容器按照你的编排全部启动起来。
DSC00018.jpg
  在这个例子的services包含每个容器的配置,其中的redis、mongodb用的是默认的镜像、默认的配置,myproject是我们自己的项目。通过这样的编排,我们就能让我们的项目连上redis和mongodb。最后通过docker-compose up就会自动拉取镜像,按照编排跑起来了。
  具体的语法也不赘述,关键就是容器的卷挂载,网络的配置,端口的暴露,容器的依赖关系。如果把这套东西用起来,慢慢自然就会了解,重要的是动手去做一遍,尝试一下。
  更多技术文章、精彩干货,请关注     
博客:zackku.com     
微信公众号:Zack说码     
DSC00019.png




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-674687-1-1.html 上篇帖子: Docker一些概念和误区总结 下篇帖子: docker 实践(一)安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表