【编者按】Docker自开源以来就受到各大公司的广泛关注。可能互联网公司的运维系统都没有承载在Docker(或者Pouch等)互联网公司身上。本文将简要介绍Docker的基本概念、入门级的使用方法以及使用Docker可以大大提高效率的一些场景。原理对于Docker最简单也是错误的认知就是“Docker是一个性能非常好的虚拟机”。如上所述,这是一个有点错误的说法。与传统的虚拟机技术相比,Docker要先进得多。具体来说,Docker并不是在宿主机上虚拟出一套硬件,然后再虚拟出一个操作系统,而是让Docker容器中的进程直接在宿主机上运行。在宿主机上(Docker会隔离文件、网络等),这样Docker会“体积更轻,运行速度更快,可以在同一宿主机下创建更多”。Docker中有3个核心概念:Image、Container、Repository。Image:广大容易收到“好人卡”的程序员一定对“镜像”这个概念不陌生。但与Windows的ISO镜像相比,Docker中的镜像是分层的、可复用的,而不是简单的一堆文件堆叠在一起(类似于压缩包源码和Git仓库的区别)。容器:容器的存在离不开镜像的支持,镜像是镜像运行时的??载体(类似于实例和类的关系)。依托Docker的虚拟化技术,为容器创建独立的端口、进程、文件等“空间”。Container是一个与宿主机隔离开来的“容器”。容器和主机之间可以通过端口、卷、网络等方式相互通信。Repository:Docker的仓库类似于Git的仓库,有仓库名和tag。在本地构建镜像后,可以通过仓库分发镜像。常用的Dockerhub包括https://hub.docker.com/、https://cr.console.aliyun.com/等。相关命令1.安装Docker安装非常方便。macOS、ubuntu等下都有一键安装工具或脚本,更多信息请参考Docker官方教程。安装后,在终端中输入docker。如果有使用说明,说明大部分情况下已经安装成功。2.找到基础镜像DockerHub等网站提供了很多镜像。一般我们会从中找出一张图片作为基础图片,然后进行我们的后续操作。这里我们以Ubuntu基础镜像为例,配置一个node环境。由于“链接太长”,国内访问DockerHub可能会比较慢,可以使用国内很多厂商提供的镜像加速器。3、拉取基础镜像,使用dockerpull命令将镜像从相关hub网站拉取到本地。同时,在拉取的过程中,可以看到镜像是按照多个“层”拉取的。>dockerpullubuntu:18.0418.04:Pullingfromlibrary/ubuntuc448d9b1e62f:Pullcomplete0277fe36251d:Pullcomplete6591defe1cd9:Pullcomplete2c321da2a3ae:Pullcomplete08d8a7c0ac3c:PullcompleteDigest:sha256:2152a8e6c0d13634c14aef08b6cc74cbc0ad10e4293e53d2118550a52f3064d1Status:Downloadednewerimageforubuntu:18.04执行dockerimages即可看到本地所有的镜像。>dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZEubuntu18.0458c12a55082a44hoursago4.创建Docker容器dockercreate命令通过镜像创建容器,同时吐出容器ID。>dockercreate--nameubuntuContainerubuntu:18.040da83bc6515ea1df100c32cccaddc070199b72263663437b8fe424aadccf4778使用dockerstart运行容器。>dockerstartubuntuContainer可以使用dockerps查看正在运行的容器。>dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES9298a27262daubuntu:18.04"/bin/bash"4minutesagoUpAbou使用dockerexec进入容器。>dockerexec-it9298root@9298a27262da:/#lsbinbootdevetchomeliblib64mediamntoptprocrootrunsbinsrvsystmpusrvarroot@9298a27262da:/#exit使用dockerrun一步创建运行容器,然后进入容器。>dockerrun-it--namerunUbuntuContainerubuntu:18.04/bin/bashroot@57cdd61d4383:/#lsbinbootdevetchomeliblib64mediamntoptprocrootrunsbinsrvsystmpusrvarroot@57cdd61d4383:/#dockerps可以查到已经成功运行了runUbuntuContainer>dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES57cdd61d4383ubuntu:18.04"/bin/bash"9secondsagoUp8secondsrunUbuntuContainer9298a27262daubuntu:18.04"/bin/bash》9分钟前Up65.在容器中安装Node环境。进入容器后,所有操作都与正常环境一致。让我们安装一个简单的节点环境。>apt-getupdate>apt-getinstallwget>wget-qO-https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh|安装bash后,当前会话可能无法读取nvm命令,可以退出然后进入中间终端环境>nvminstall8.0.0>node-v6.commit容器,新建镜像和Ghost安装Windows,很多时候我们希望自定义自己的镜像,在里面安装一些基础环境(比如上面的节点),然后制作自己想要的基础镜像。这时候dockercommit就派上用场了。>dockercommit--author"rccoder"--message"curl+node"9298rccoder/myworkspace:v1sha256:68e83119eefa0bfdc8e523ab4d16c8cf76770dbb08bad1e32af1c872735e6f71通过dockerimages就能看到新制作的rccoder/myworkspace就躺在这里了>dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZErccoder/myworkspacev1e0d73563fae820secondsago196MB接着,试一下我们新Thecreatedimage?>dockerrun-it--namenewWorkSpacerccoder/myworkspace:v1/bin/bashroot@9109f6985735:/#node-v8.0.0looksok.7.PushtheimagetodockerhubAftertheimageismade,howtoshareitforotherstouse?Herewetakepushtodockerhubasanexample.Thefirststepistogotothedockerhubtoregisteranaccount,thenlogintotheaccountontheterminalandpush.>dockerlogin>dockerpushrccoder/myworkspace:v1Thepushreferstorepository[docker.io/rccoder/myworkspace]c0913fec0e19:Pushing[=>]2.783MB/116.7MBbb1eed35aacf:Mountedfromlibrary/ubuntu5fc1dce434ba:Mountedfromlibrary/ubuntuc4f90a44515b:Mountedfromlibrary/ubuntua792400561d8:Mountedfromlibrary/ubuntu6a4e481d02df:Waiting8.是时候使用Dockerfile与Docker持续集成?比起知道Docker,你肯定听说过这个,也就是说你需要从某处复制代码并执行(是的,听起来有点像travis-ci)。是时候让Dockerfile上场了!Dockerfile是由一堆命令+参数组成的脚本。使用dockerbuild执行构建镜像的脚本,自动做一些事情(类似于travis-ci中的.travis.yml)。Dockerfile的格式是all:#CommentINSTRUCTIONarguments必须以FROMBASE_IMAGE开头来指定基础镜像。有关更详细的规范和说明,请参阅Dockerfile参考。这里我们以上面的rccoder/myworkspace:v1为基础镜像,然后在根目录下创建目录为例。Dockerfile如下:FROMrccoder/myworkspace:v1RUNmkdira然后执行:>dockerbuild-tnewfiledocker:v1.SendingbuildcontexttoDockerdaemon3.584kBStep1/2:FROMrccoder/myworkspace:v1--->68e83119eefaStep2/2:RUNmkdira--->Runningin1127aff5fbd3Removingintermediatecontainer1127aff5fbd3--->25a8a5418af0Successfullybuilt25a8a5418af0Successfullytaggednewfiledocker:v1新建一个基于filedocker的容器,在终端打开,发现里面已经有一个文件夹了。>dockerdockerrun-itnewfiledocker:v1/bin/bashroot@e3bd8ca19ffc:/#lsabinbootdevetchomeliblib64mediamntoptprocrootrunsbinsrv有了Dockerfile的能力,Docker留下了无限可能。能做什么说了这么多,Docker在实际生产环境中能做什么呢?常用的可能有以下几种(欢迎在评论补充)1.多环境部署切换在业务开发中,经常需要区分开发环境和线上环境,使用Docker可以迁移代码和开发环境到线上环境完好无污染,通过一定的自动化流程可以实现自动发布。2.由于前端云搭建的node_modules之痛,不同人在同一个仓库开发,经常会遇到不同人用不同的包版本,自己也不知道自己和别人不一样,最终导致上线后出现问题发布。使用Docker,你可以在云端创建一个新的容器,远程无污染地构建代码,并且成本低廉,让不同的人必须使用相同的版本。3、复杂环境一键配置在某些场景下,可能会配置一些超级复杂的环境(例如:大一有Java环境)。这时候可以使用Docker封装环境配置,直接生成镜像,让大家低成本使用。4.持续集成单元测试类似于travis-ci。5.同一个应用的多个版本和文件的隔离。比如这个项目依赖节点6,那个项目依赖节点8(只是举个例子,如果硬盘足够大,建议通过nodeinstall解决);同一台服务器上运行了100个wordpress程序(可以使用Docker建立隔离,防止相互污染)。6.省钱嘛,安全超卖(雾)成本低。
