当前位置: 首页 > 科技观察

前端写的Docker入门终极指南,别说你不会用Docker了!

时间:2023-03-17 18:07:38 科技观察

在富Web时代,应用越来越强大,同时也越来越复杂。集群部署、环境隔离、灰度发布、动态扩展缺一不可,容器化成为这中间必不可少的桥梁。本节我们将探索Docker的神秘世界,从零到一掌握Docker的基本原理和实战操作。别守着前端的一亩三分地了,该开疆拓土了。1.讲故事为了更好的理解Docker是什么,我们先讲一个故事:我要盖房子,所以我搬石头、砍柴、画图纸、盖房子。经过一番手术,房子终于盖好了。结果住了一段时间,心血来潮就决定搬到海边去了。这时候,按照以前的办法,只能去海边,搬石头,砍柴,画图纸,重新盖房子。正在我苦恼的时候,一位魔术师来教我一种魔术。这种魔法可以把我盖的房子复制一份,做成“镜像”,放在我的背包里。黑魔法当我到达海滩时,我用这个“镜像”复制了一个房子并搬进了我的包。是不是很神奇?对应我们的项目,房子就是项目本身,镜像就是项目的副本,背包就是镜像仓库。如果想动态扩容,就从仓库中取出项目镜像,随便复制过来。一次构建,随处运行!无需关注版本、兼容性、部署等问题,彻底解决“上线即崩溃,构建无休止”的尴尬。2、在启动虚拟机和容器之前,我们先准备一些基础知识:1、虚拟机:虚拟化硬件虚拟机虚拟机是指通过软件模拟出具有完整硬件系统功能的虚拟机,运行在一个完整的计算机系统中孤立的环境。在物理计算机上可以完成的所有事情都可以在虚拟机上完成。在计算机上创建虚拟机时,需要使用物理机的部分硬盘和内存容量作为虚拟机的硬盘和内存容量。每个虚拟机都有独立的CMOS、硬盘和操作系统,可以像物理机一样操作。在容器技术出现之前,业界的网红就是虚拟机。虚拟机技术的代表是VMWare和OpenStack。更多信息请参考:https://baike.baidu.com/item/%E8%99%9A%E6%8B%9F%E6%9C%BA/104440?fr=aladdin2。容器:将操作系统层虚拟化,是一个无处不在的标准软件单元:容器可以将代码、配置文件和相关依赖包进行打包,保证在任何环境下运行一致。资源利用率高:容器提供进程级隔离,可以更精细地设置CPU和内存使用率,从而更好地利用服务器的计算资源。快速伸缩:每个容器都可以作为一个单独的进程运行,可以共享底层操作系统的系统资源,可以加快容器的启停效率。3、区别与联系虚拟机虽然可以隔离出很多“子机”,但占用空间大,启动速度慢。虚拟机软件也可能要花钱,比如VMWare;容器技术不需要虚拟化整个操作系统,只需要虚拟化一个小范围的环境,类似于“沙盒”;虚拟机的运行空间一般需要几GB到几十GB的空间,而容器只需要MB级别甚至KB级别;我们来看一下对比数据:与虚拟机相比,容器更轻更快,因为它在隔离环境下使用Linux底层操作系统运行。虚拟机的Hypervisor创建了一个非常强大的边界以防止应用程序突破它,而容器的边界则没有那么强大。物理机部署不能充分利用资源,造成资源浪费。以虚拟机的形式部署,虚拟机本身会占用大量资源,造成资源浪费,虚拟机的性能也较差。容器化部署更灵活、轻量级,性能更优。虚拟机属于虚拟化技术,Docker等容器技术属于轻量级虚拟化。三、认识DockerDocker一、概念Docker是一个开源的应用容器引擎,它允许开发者将他们的应用和依赖包打包到一个可移植的容器中,然后发布到任何流行的Linux机器上,虚拟化也是可能的。容器完全使用沙箱机制,它们之间不会有任何接口。Docker技术的三个核心概念是:镜像Image、容器Container、仓库Repository。2、Docker为什么是轻量级的?相信大家也会有这样的疑惑:Docker为什么启动快?如何与主机共享内核?当我们要求Docker运行一个容器时,Docker会在计算机上设置一个资源隔离的环境。然后将打包的应用程序和相关文件复制到命名空间内的文件系统中,环境的配置就完成了。然后Docker将执行我们预先指定的命令来运行应用程序。镜像不包含任何动态数据,构建后内容不会改变。四、核心概念1.Build,ShipandRun(建造、运输、运行);2.Buildonce,Runanywhere(构建一次,到处运行);3.Docker本身并不是容器,它是一个创建容器的工具,是一个应用容器引擎;4.Docker三个核心概念是:镜像Image,containerContainer,warehouseRepository5.Docker技术利用Linux内核以及Cgroups、namespaces等内核特性将进程分离,使它们各自独立运行其他。6.由于Namespace和Cgroups功能只在Linux上可用,容器无法运行在其他操作系统上。那么Docker如何在macOS或Windows上运行呢?Docker其实用了一个trick,在非Linux操作系统上安装一个Linux虚拟机,然后在虚拟机内部运行容器。另外,搜索公众号python人工智能科技后台回复“杰作”,即可获得惊喜大礼包。7.镜像是一个可执行包,包含运行应用程序所需的代码、运行时、库、环境变量和配置文件,容器是镜像的运行时实例。5.安装Docker1。命令行安装Homebrew的Cask已经支持DockerforMac,所以你可以很方便的使用HomebrewCask进行安装,执行如下命令:brewcaskinstalldocker更多安装方法请查看官方文档:https://www.docker.com/get-started2.检查版本docker-v3。配置镜像加速设置DockerEngine写入配置:{"registry-mirrors":["http://hub-mirror.c.163.com/","https://registry.docker-cn.com"],"不安全注册表”:[],“实验”:假,“调试”:真}4。桌面端安装Docker桌面端操作很简单,先去官网下载。通过Docker桌面,我们可以轻松操作:clone:克隆一个项目build:打包镜像run:运行实例share:共享镜像,准备工作就绪,接下来就可以大显身手了!6.快速入门安装好Docker之后,我们来制作一个实际项目的镜像,边学边用。1.首先我们需要对将要用到的11条命令有个大概的了解2.为了快速新建一个项目,我们直接使用Vue脚手架搭建项目:vuecreatedocker-demo尝试启动一下:yarnserve访问地址:http://localhost:8080/。项目准备好了,接下来我们对项目进行打包:yarnbuild此时项目目录下的Dist就是我们要部署的静态资源,继续下一步。注意:前端项目一般分为两类,一类是直接通过Nginx静态部署,一类需要启动Node服务。本节我们只考虑第一个。3.新建一个Dockerfilecddocker-demo&&touchDockerfile此时的项目目录如下:├──Dockerfile├──README.md├──babel.config.js├──dist├──node_modules├──package.json├──public├──src└──yarn.lock可以看到我们在docker-demo目录下成功创建了Dockerfile。4.准备Nginx镜像运行你的Docker桌面,实例会默认启动。WepulltheNginximageontheconsole:dockerpullnginxTheconsolewilldisplaythefollowinginformation:Usingdefaulttag:latestlatest:Pullingfromlibrary/nginx8559a31e96f4:Pullcomplete8d69e59170f7:Pullcomplete3f9f1ec1d262:Pullcompleted1f5ff4f210d:Pullcomplete1e22bfa8652e:PullcompleteDigest:sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133Status:Downloadednewerimagefornginx:latestdocker.io/library/nginx:latest如果您出现这种异常,请确认Docker实例是否正常运行。无法连接到位于unix:///var/run/docker.sock的Docker守护程序。docker守护进程是否正在运行?镜像准备好了,我们在根目录下创建Nginx配置文件:touchdefault。conf写:服务器{听80;服务器名称本地主机;#charsetkoi8-r;access_log/var/log/nginx/host.access.logmain;error_log/var/log/nginx/error.log错误;位置/{root/usr/share/nginx/html;indexindex.htmlindex.htm;}error_page500502503504/50x.html;location=/50x.html{root/usr/share/nginx/html;}}5。配置镜像打开Dockerfile,写入如下内容:FROMnginxCOPYdist//usr/share/nginx/html/COPYdefault.conf/etc/nginx/conf.d/default.conf下面逐行解释代码:FROMnginx指定镜像基于nginx:latest镜像构建;COPYdist//usr/share/nginx/html/命令表示将项目根目录下dist文件夹下的所有文件复制到镜像/usr/share/nginx/html/目录下;COPYdefault.conf/etc/nginx/conf.d/default.conf将default.conf复制到etc/nginx/conf.d/default.conf,用本地default.conf配置,替换Nginx镜像中的默认配置。6.构建镜像Docker通过构建命令构建镜像:dockerbuild-tjartto-docker-demo。按照惯例,我们来解释一下上面的代码:-t参数命名镜像jartto-docker-demo。它基于当前目录的Dockerfile构建镜像成功后,会输出:SendingbuildcontexttoDockerdaemon115.4MBStep1/3:FROMnginx--->2622e6cca7ebStep2/3:COPYdist//usr/share/nginx/html/--->使用缓存--->82b31f98dce6Step3/3:COPYdefault.conf/etc/nginx/conf.d/default.conf--->7df6efaf9592Successfullybuilt7df6efaf9592Successfullytaggedjartto-docker-demo:最新图片制作成功!我们来看看容器:dockerimagels|grepjartto-docker-demo可以看到我们创建了一个133MB的工程镜像:jartto-docker-demolatest7df6efaf9592大约一分钟前133MB的镜像也有优劣之分,后面会介绍如何优化,可以暂时此处忽略。延伸:接私活7.运行容器dockerrun-d-p3000:80--namedocker-vuejartto-docker-demo这里对参数进行解释:-d设置容器运行在background-p表示端口映射,将本机的3000端口映射到容器的80端口(这样就可以通过本机的3000端口访问外网了。另外搜索公众号编程技术圈,回复“神器”在后台获得惊喜大礼包。--name设置容器名称docker-vuejartto-docker-demo就是我们上面构建的镜像的名称。还有一点:在控制台中,我们可以通过dockerps查看刚刚运行的容器ID:dockerps-aconsole会输出:CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESab1375befb0bjartto-docker-demo"/docker-entrypoint.…"8分钟前Up7分钟0.0.0.0:3000->80/tcpdocker-vue如果你用的是桌面,那么打开Docker就可以在Dashboard看到容器列表,如下图:8.访问项目因为我们映射了本机的3000端口,执行:curl-v-ilocalhost:3000或者打开浏览器访问:localhost:30009.发布镜像如果你想贡献社区,您需要发布图像供其他开发人员使用。发布镜像需要以下步骤:登录[dockerhub](https://hub.docker.com),注册账号;在命令行执行dockerlogin,然后输入我们的账号密码进行登录;在推送镜像之前,需要打一个Tag,执行dockertag/:整个过程就结束了。以后我们就用上了,再也不用“搬石头、砍柴、画图纸、盖房子”,背着行囊搬进来了。这也是docker的独特魅力。七、常规操作到这里,恭喜你完成了Docker的入门项目!如果还想再深入一点,不妨继续往下看。1.参数使用FROM指定基础镜像,所有构建的镜像都必须有一个基础镜像,并且FROM命令必须是Dockerfile的第一条命令FROM[AS]指定构建一个新的imagenamefromanimageFROM[:][AS]指定镜像的版本Tag示例:FROMmysql:5.0ASdatabaseMAINTAINER镜像维护者信息MAINTAINER例子:MAINTAINERJarttoJartto@qq.comRUN构建镜像时要执行的命令RUN例子:RUN["executable","param1","param2"]ADD将将本地文件添加复制到容器中,压缩包解压,可以访问网络上的文件,ADD会自动下载示例:ADD*.js/App添加js文件到容器中的app目录。COPY功能与ADD相同。它只是复制,并不解压缩或下载文件。CMD在启动容器后执行的命令与RUN不同。RUN是构建映像时要运行的命令。使用dockerrun运行容器时,可以在命令行覆盖这个例子:CMD["executable","param1","param2"]ENTRYPOINT也是一个执行命令,和CMD一样,但是这个命令不会可以被命令行覆盖==...例子:LABELversion="1.0"description="Thisisawebapplication"ENV:设置环境变量,有些容器在运行ENV时会需要一定的环境变量一次设置一个环境变量ENV;===设置多个环境变量示例:ENVJAVA_HOME/usr/java1.8/EXPOSE:对外暴露的端口(容器内部的端口程序,虽然会和宿主机一样,但实际上是两个端口)EXPOSE例子:EXPOSE80容器运行时,需要用-p映射外部端口,访问里面的端口容器VOLUME:指定数据持久化的目录,官方语言叫mountingVOLUME/var/log来指定容器中需要挂载的目录,这个目录会映射到宿主机上的一个随机目录以实现数据持久化和同步VOLUME["/var/log","/var/test"...]指定容器中需要挂载的多个目录,这些目录会映射到宿主机上的多个随机目录实现数据持久化和同步VOLUME/var/datavar/logspecifies是将容器中的var/log目录挂载到宿主机的/var/data目录下。这种形式可以手动指定主机上的目录WORKDIR:设置工作目录,设置后,RUN,CMD,COPY,ADDWORKDIR示例:WORKDIR/app/testUSER:指定运行命令时使用的用户。为了安全和权限,根据要执行的命令选择不同的用户。USER:[]示例:USERtestARG:设置构建镜像时要传递的参数ARG[=]ARGname=sss更多操作请移步官方文档:https://docs.docker.com/eight,Bestpractices在掌握了Docker的常规操作之后,我们就可以轻松的创建自己想要的项目镜像了。但是,不同的操作产生的图像也有很大的不同。究竟是什么造成了镜像差异,我们不妨继续探索。以下是应用Docker过程中的最佳实践。请尽可能遵循以下准则:RequireClear:需要什么镜像Stepstreamlined:步骤少改动PrioritizeversionClear:mirror命名清晰说明文档:整个镜像打包步骤可以重现。推荐以下两篇文章:https://www.docker.com/blog/intro-guide-to-dockerfile-best-practices/https://docs.docker。com/develop/develop-images/dockerfile_best-practices/9.总结容器化技术将是云时代不可或缺的技能之一,而Docker只是沧海一粟。然后是集群容器管理K8s、ServiceMesh、Istio等技术。打开Docker的大门,继续抽丝剥茧,层层深入,你会感受到容器化的无穷魅力。