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

Docker入门终极指南,别再说你不会用Docker了!

时间:2023-03-15 00:52:31 科技观察

在丰富的网络时代,应用程序变得越来越强大,同时也越来越复杂。集群部署、环境隔离、灰度发布、动态扩展缺一不可,容器化成为这中间必不可少的桥梁。本节我们将探索Docker的神秘世界,从零到一掌握Docker的基本原理和实战操作。别守着前端的一亩三分地了,该开疆拓土了。我们将重点关注以下几点:讲一个故事虚拟机和容器了解Docker的核心概念我需要盖房子,所以我搬石头、砍柴、画蓝图、盖房子。经过一番手术,房子终于盖好了。结果住了一段时间,心血来潮就决定搬到海边去了。这时候,按照以前的办法,只能去海边,搬石头,砍柴,画图纸,重新盖房子。正在我苦恼的时候,一位魔术师来教我一种魔术。这种魔法可以把我盖的房子复制一份,做成“镜像”,放在我的背包里。黑魔法当我到达海滩时,我用这个“镜像”复制了一个房子并搬进了我的包。是不是很神奇?对应我们的项目,房子就是项目本身,镜像就是项目的副本,背包就是镜像仓库。如果想动态扩容,就从仓库中取出项目镜像,随便复制过来。一次构建,随处运行!无需关注版本、兼容性、部署等问题,彻底解决“上线即崩溃,构建无休止”的尴尬。二、在启动虚拟机和容器之前,我们先准备一些基础知识: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到几十GBContainer只需要MB甚至KB;我们来看对比数据:与虚拟机相比,容器更轻更快,因为它使用底层Linux操作系统运行在隔离的环境中。虚拟机的管理程序创建了一个非常强大的边界以防止应用程序破坏它,而容器的边界则没有那么强大。物理机部署不能充分利用资源,造成资源浪费。以虚拟机的形式部署,虚拟机本身会占用大量资源,造成资源浪费,虚拟机的性能也较差。容器化部署更灵活、轻量级,性能更优。虚拟机属于虚拟化技术,Docker等容器技术属于轻量级虚拟化。3.认识DockerDocker1。ConceptDocker是一个开源的应用容器引擎,允许开发者将他们的应用和依赖包打包到一个可移植的容器中,然后发布到任何流行的Linux机器上,它还可以实现虚拟化。容器完全使用沙箱机制,它们之间不会有任何接口。Docker技术的三个核心概念是:镜像Image、容器Container、仓库Repository。2、Docker为什么是轻量级的?相信大家也会有这样的疑惑:Docker为什么启动快?如何与主机共享内核?当我们要求Docker运行一个容器时,Docker会在计算机上设置一个资源隔离的环境。然后将打包后的应用程序和相关文件复制到Namespace内的文件系统中,环境配置完成。然后Docker将执行我们预先指定的命令来运行应用程序。镜像不包含任何动态数据,构建后内容不会改变。四、核心概念1.Build,ShipandRun(建造、运输、运行);2.Buildonce,Runanywhere(构建一次,到处运行);3.Docker本身不是容器,它是创建容器的工具,是Application容器引擎;4、Docker的三个核心概念是:镜像Image、容器Container、仓库Repository;5.Docker技术利用Linux内核和内核功能(如Cgroups和namespaces)来分离进程,使每个进程相互独立运行。6.由于Namespace和Cgroups特性仅在Linux上可用,容器无法在其他操作系统上运行。那么Docker如何在macOS或Windows上工作?Docker其实用了一个trick,在非Linux操作系统上安装一个Linux虚拟机,然后在虚拟机内部运行容器。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"],"insecure-registries":[],"experimental":false,"debug":true}4.桌面安装Docker桌面操作很简单,先去官网下载。通过Docker桌面,我们可以方便的操作:clone:克隆一个项目build:打包镜像run:运行instanceshare:共享镜像,准备工作就绪,下面就来一展身手吧!6.快速入门安装好Docker之后,我们来制作一个实际项目的镜像,边学边用。1.首先我们需要对将要用到的11条命令有个大概的了解2.为了快速新建一个项目,我们直接使用Vue脚手架搭建项目:vuecreatedocker-demo尝试启动一下:yarnserve访问地址:http//本地主机:8080/。项目准备好了,接下来我们对项目进行打包:yarnbuild此时项目目录下的Dist就是我们要部署的静态资源,继续下一步。注意:前端项目一般分为两类,一类是直接通过Nginx静态部署,一类需要启动Node服务。本节我们只考虑第一个。3.CreateanewDockerfilecddocker-demo&&touchDockerfileTheprojectdirectoryatthistimeisasfollows:.├──Dockerfile├──README.md├──babel.config.js├──dist├──node_modules├──package.json├──public├──src└──yarn.lockYoucanseethatwehavesuccessfullycreatedtheDockerfileinthedocker-demodirectory.4.准备Nginx镜像运行你的Docker桌面端,就会默认启动实例,我们在控制台拉取Nginx镜像:dockerpullnginx控制台会出现如下信息:Usingdefaulttag:latestlatest:Pullingfromlibrary/nginx8559a31e96f4:Pullcomplete8d69e59170f7:Pullcomplete3f9f1ec1d262:Pullcompleted1f5ff4f210d:Pullcomplete1e22bfa8652e:PullcompleteDigest:sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133Status:Downloadednewerimagefornginx:latestdocker.io/library/nginx:latestIfyouhavesuchanexception,pleaseconfirmwhethertheDockerinstanceisrunningnormally.无法连接到Docker守护进程tunix:///var/run/docker.sock。docker守护进程是否正在运行?镜像准备好了,我们在根目录下创建Nginx配置文件:touchdefault.conf写:server{listen80;server_namelocalhost;#charsetkoi8-r;access_log/var/log/nginx/host.access.logmain;error_log/var/log/nginx/error.logerror;location/{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,将Nginx镜像中的default配置替换为本地的default.conf配置。6、构建镜像Docker通过构建命令构建镜像:dockerbuild-tjartto-docker-demo。按照惯例,我们来解释一下上面的代码:-t参数将镜像命名为jartto-docker-demo。它是基于当前目录下的Dockerfile构建镜像执行成功后会输出:SendingbuildcontexttoDockerdaemon115.4MBStep1/3:FROMnginx--->2622e6cca7ebStep2/3:COPYdist//usr/share/nginx/html/--->Usingcache--->82b31f98dce6Step3/3:COPYdefault.conf/etc/nginx/conf.d/default.conf--->7df6efaf9592成功构建7df6efaf9592成功标记jartto-docker-demo:latestimage制作成功!我们来看看容器:dockerimagels|grepjartto-docker-demo可以看到我们创建了一个133MB的工程镜像:jartto-docker-demolatest7df6efaf9592大约133MB的镜像也有好有坏,后面会介绍如何优化,这里可以暂时忽略。7.运行容器dockerrun-d-p3000:80--namedocker-vuejartto-docker-demo这里对参数进行解释:-d设置容器在后台运行-p表示端口映射,映射端口的3000机器到容器的80端口(这样就可以通过本机的3000端口访问外网了--name设置容器名称docker-vuejartto-docker-demo就是我们上面构建的镜像的名称。还有一点:在控制台中,我们可以使用dockerps查看刚刚运行的ContainerID:dockerps-a控制台会输出:CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESab1375befb0bjartto-docker-demo"/docker-entrypoint.…"8minutesagoUp7minutes0.0.0.0:3000->80/tcpdocker-vue如果你使用的是桌面,那么打开DockerDashboard可以看到容器列表,如下图:8.访问项目因为我们映射了本地3000端口,执行:curl-v-ilocalhost:3000或打开浏览器访问:localhost:30009发布镜像t要为社区做贡献,您需要发布镜像供其他开发者使用。发布镜像需要以下步骤:登录[dockerhub](https://hub.docker.com),注册账号;在命令行执行dockerlogin,然后输入我们的账号密码,进行登录;在推送镜像之前,需要打一个Tag,执行dockertag/:整个过程就结束了,以后会用到,不用“搬石头”》,砍木头,画图纸,盖房子,背着行囊搬进去。这也是docker的独特魅力。7.常规操作在这里。恭喜,你已经完成了Docker入门项目!如果想继续深入,不妨继续往下看。1.参数使用FROM:#指定基础镜像,所有构建的镜像都必须有一个基础镜像,并且FROM命令必须是Dockerfile的第一条命令FROM[AS]指定从中构建镜像一个镜像NewimagenameFROM[:][AS]指定镜像版本TagExample:FROMmysql:5.0ASdatabaseMAINTAINER:#ImagemaintainerinformationMAINTAINERExample:MAINTAINERJarttoJartto@qq.comRUN:#构建镜像时执行的命令RUN例子:RUN[executable,param1,param2]ADD:#添加并复制本地文件到容器中,压缩包会解压,网络上的文件可以自动访问DownloadADD例子:ADD*.js/app将js文件添加到容器中的app目录COPY:#功能同ADD,只是复制,不解压或下载文件CMD:#启动容器后执行命令与RUN不同。RUN是构建映像时要运行的命令。使用dockerrun运行容器时,可以在命令行中将其覆盖。Example:CMD[executable,param1,param2]ENTRYPOINT:#也是一个执行命令,和CMD一样,但是这个命令不会被命令行覆盖ENTRYPOINT[executable,param1,param2]Example:ENTRYPOINT[donnet,myapp.dll]LABEL:#为图片添加元数据,键值格式LABEL==...例子:LABELversion=1.0description=ThisisawebapplicationENV:#Set环境变量,有些容器会需要某些环境变量ENVsetonce一个环境变量ENV===设置多个环境变量例子:环境变量JAVA_HOME/usr/java1.8/EXPOSE:#Expose外部端口(容器内部程序的端口,虽然会和host一样,但实际上是两个端口)EXPOSE例子:EXPOSE80当容器运行时,需要使用-p映射外部端口来访问容器中的端口在容器中,这个目录会映射到宿主机的任意一个目录上,实现数据的持久化和同步VOLUME[/var/log,/var/test....]#指定容器中的多个目录需要挂载,这些目录会映射到宿主机上的多个随机目录,实现数据持久化和同步VOLUME/var/datavar/log#指定容器中的var/log目录挂载到/var/data主机上的目录,这种形式可以手动指定主机上的目录WORKDIR:#设置工作目录。设置后RUN、CMD、COPY、ADD的工作目录会同步改变WORKDIR例子:WORKDIR/app/testUSER:#指定运行命令时使用的用户,为了安全和权限,选择根据要执行的命令不同的用户USER:[]Example:USERtestARG:#设置构建镜像传递的参数ARG[=]ARGname=用于更多sss操作,请参考官方文档:https://docs.docker.com/八、最佳实践掌握了Docker的常规操作后,我们就可以轻松创建自己想要的项目镜像但是不同的操作打出的镜像也大不相同.究竟是什么造成了镜像差异,我们不妨继续探索。以下是应用Docker过程中的最佳实践。请尽可能遵循以下准则:RequireClear:需要哪些镜像步骤Simplified:改动少的步骤,版本优先Clear:镜像命名清晰Documentation:整个镜像打包步骤可以复现推荐以下两篇文章: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的大门,继续抽丝剥茧,层层深入,你会感受到容器化的无穷魅力。赶快打开技能边界,为你的前端技术赋能吧!