wy168 发表于 2024-1-6 18:47:11

微服务架构Docker,K8S,KVM,Hypervisor和微服务有什么区别联系吗?


    <h1 style="text-align: left; margin-bottom: 10px;">DDD的挑战</h1>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">首先,领域驱动设计需要一定的学习成本,而且学习曲线陡峭,在团队中如果不能接受新的设计理念,那么实施起来一定困难重重。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">其次,领域驱动设计需要领域专家持续不断地参与项目,而领域专家多来自客户方,客户方能配合和参与项目团队的设计与讨论的领域专家并不多。最后,领域驱动设计与传统的系统设计思路大不相同,项目团队在适应新的思维方式的同时,还需要考虑许多设计活动,如需要投入时间和精力在沟通与建立统一语言等事情上。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">不过,尽管DDD会面临诸多挑战,仍然建议学习和尝试这一设计方法,领域驱动设计可以使开发人员表达出更加丰富的业务需求,将软件转换为更加富有业务价值的功能,一旦我们采用了DDD的设计并成功应用后,就会习惯并再也离不开它。</span></p>
    <h1 style="text-align: left; margin-bottom: 10px;">Docker和K8s</h1>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">◎ 虚拟化技术</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">◎ Docker容器化</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">◎ 学习使用Docker</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">◎ 容器编排</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">◎ 云商的支持</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">提到微服务,首先想到的是服务小、职责小,如果是一个庞大复杂的系统,我们必然会建立很多的微服务,而且服务都可以水平扩展。在一些大型的互联网企业,服务的数量可能是成百上千的,如何去部署和管理这些服务成了一个难题,一旦发布新的版本,又该如何去更新?所以,Docker容器化、K8s容器编排等技术逐渐登上了舞台。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">下面介绍微服务架构下部署和维护服务的方式。</span></p>
    <h1 style="text-align: left; margin-bottom: 10px;">虚拟化技术</h1>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">在以往的软件项目中,我们会使用虚拟化的技术来实现服务的部署和发布。虚拟化(Virtualization)是一种资源管理技术,将计算机的各种实体资源,如CPU、网络、内存及硬盘空间等,予以抽象、转换后呈现出来并可供分割、组合为一个或多个计算机配置环境,使用户可以通过比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部分不受现有资源的架设方式、地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储,虚拟技术按抽象层次可以分为5个层次:硬件抽象层次、指令集架构抽象层次、操作系统抽象层次、库抽象层次、应用抽象层次。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/8a10705177e34b6bae1b2851999c5735~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=xp1V9yY%2FNX24XchXbsz1Wt3ZvM8%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">抽象程度由硬件到应用逐渐递增,通常我们将计算机硬件虚拟分割成一个或多个虚拟机(Virtual Machine,VM),然后将服务和页面都部署在各个虚拟机上,并提供多用户对大型计算机的同时交互、访问,可以算作硬件抽象层次,通过纵向地扩展虚拟机的配置,或者横向地扩展虚拟机的个数,更加容易增加系统的负载量。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">但传统的虚拟化技术正在遭受到重大挑战,随着微服务的兴起,在笨重的虚拟机上部署应用无法满足我们的需求。笔者曾有一个微服务项目,这是一个庞大且运营了很多年的产品,要完整地运行一个项目需要上百个不同的服务。一般需要20~30个虚拟机,每次新部署一套产品上线,需要花费大量的人力进行虚拟机配置、网络调试、基础环境搭建。例如,数据库的安装部署、服务配置和部署、系统测试等工作,加上虚拟机的调试和启动速度不够理想,每次完整地部署这套产品,哪怕只是测试环境,都需要两周,如果换一个不熟悉系统的人,完成一次新产品的部署工作几乎不可能。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/8d089321cfd04f05994727009f9c10ea~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=7nuur7ppCPT9WHXNZnBHxQZCFV0%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">如今网络信息化技术飞速发展,市场对企业响应速度的要求也越来越高,很多时候一旦慢人一步,很可能带来无法挽回的失败。那么,有没有一项技术可以替代虚拟机技术,加快响应速度,让应用更加便捷、快速部署呢?</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">容器化技术诞生了,Docker是当前最流行的一款容器技术,从原理上,Docker并没有采用与虚拟机一样的虚拟化技术,并不会对硬件进行虚拟化。它是直接基于Linux的内核,对文件系统、网络、进程等进行封装和隔离,由硬件虚拟化上升到了操作系统抽象层次的虚拟化技术,所以Docker更加轻量、快速、便捷。</span></p>
    <h1 style="text-align: left; margin-bottom: 10px;">Docker容器化</h1>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">在软件技术与架构飞速发展时,业界逐渐认识到虚拟机技术既浪费资源,又无法满足业务上的需求,因此容器化技术诞生了,并迅速流行起来。什么是容器化?它与传统的虚拟化相比有什么优势呢?</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><strong style="color: blue;"><span style="color: green;">Docker的概念</span></strong></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">Docker是目前最流行的容器化的软件和平台,可以在如macOS、Windows和Linux等环境中运行,借用官网上的一句话,Docker容器化解锁你的开发和运维的潜力。Docker可以将软件打包成标准化单元:容器,用于开发、迁移和部署。Docker通过创建简单的工具和通用打包方法,将容器内的所有应用程序依赖关系捆绑在一起,并使容器化应用程序能够在任何基础架构上一致地运行,为开发人员和运营团队解决依赖性问题,减少了“我的电脑是好的呀”声音出现。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/87974c4f788042feb6f59b1798076cb9~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=eAbsq4VzUEmHPx388ADwtZpHT4E%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">那么,Docker是如何做到的?由前面章节我们知道,Docker是一款容器技术,是存在着系统抽象层次的虚拟化技术。我们可以把Docker的容器想象成一个集装箱,在项目中拥有多个不同的服务或应用程序,技术栈(如开发语言、框架、数据库等)都不相同,但可以将这些服务或应用程序打包到集装箱中,每个集装箱都用相同的方式运行、存储和运输。例如,在没有使用容器时,要运行或部署一个Java Web的应用程序,首先需要安装JDK,然后安装Web服务器,如Tomcat,接着安装数据库,最后需要将Java程序打包,部署到Tomcat中运行起来,这是相当烦琐且容易出错的过程。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p26-sign.toutiaoimg.com/pgc-image/be8e2e01eecc4dfcbfdb89721a9d45cf~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=McvLgoU1WgvNuYpqhXkFjadYp9w%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">在不同环境中,JDK的版本、Tomcat的版本及数据库的配置等都可能导致程序的运行结果出现差异,当问题发生时,我们很难快速定位是环境问题还是程序问题,这也是为什么程序员都喜欢说“我的电脑是好的呀”。毕竟程序运的环境往往比较复杂,需要很多依赖配置,而程序员的本地环境和程序正式的运的环境差异较大。而Docker可以将这些繁琐的步骤自动化,我们将JDK、Tomcat,甚至是数据库都打包在一起运行,无论是什么环境,我们只需将打包的集装箱进行迁移即可,每个环境运行的程序都完全相同,从而屏蔽复杂的操作和环境的差异。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">每个集装箱都提供统一的接口给外部调用者使用,不用的程序都标准化管理起来,并且屏蔽了差异化,为开发和运维提供便利。例如,有的程序需要启动Tomcat,或者启动MySQL,或者启动Nginx,那么作为运维人员,要根据不同的技术或工具编写不同的操作脚本,运行startup,或者运行start,不同的程序指令层出不穷,这在大规模环境部署时非常痛苦,需要反复修改脚本文件,但我们需要的操作都有规律,如启动、停止、重启和日志等,Docker就提供一系列的操作接口,运维人员只需操作集装箱即可,不需要关注集装箱内部的运行细节。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/c69c5fe0d15b4c4da80ba6a5dd0c9d7c~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=Zdkzdiq%2BcRnntzgbAOwyygdwKq4%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">最后,集装箱还有隔离的特性,每个集装箱都相互独立,集装箱内部的运行互不影响。例如,我们可以在一个容器内使用JDK1.8,同时在另一个容器内使用JDK1.7,两个容器相互独立,这也更加契合微服务的思想。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">Docker提供社区版和企业版两个版本,社区版永久免费,并且内核与企业版完全相同,企业版将容器技术扩展到容器平台,提供企业级容器平台,提供安全和治理等企业级更高级的功能实现。社区版目前完全可以运用于生产环境,不过在大规模的场景下还需要一些(如Kubernetes等)容器编排系统来配合使用。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><strong style="color: blue;"><span style="color: green;">容器的概念</span></strong></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">在介绍Docker时可以看出,容器是Docker的核心技术,那么什么是容器?容器是一个标准的软件单元,它将代码及其所有依赖关系打包,以便应用程序从一个计算环境快速可靠地运行到另一个计算环境。Docker通过容器镜像(Docker Image)将包含运行应用程序所需的一切:代码、运行时、系统工具、系统库和设置,构建成一个轻量级、可独立执行的软件包,而容器镜像在运行时成为容器,无论基础架构如何,容器化软件都将始终运行在相同的配置环境中,容器将软件与其环境隔离开来,并确保它可以统一工作。容器和虚拟机具有类似的资源隔离和分配优势,但功能不同,因为容器是虚拟化操作系统而不是硬件,并且容器更便携、高效。容器的运行依赖于容器runtime,containerd是一个行业标准的容器runtime,利用了runc,创建时强调简单性、健壮性和便携性。而containerd也是Docker Engine的核心容器运行时。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">图8.1所示为Docker Engine的结构,Docker Engine主要包括Server、REST API和Client 3个部分。Server是一种长时间运行的程序,称为Docker守护进程;REST API则可以用来与守护进程通信并指示它做什么接口;Client是一个命令行接口(CLI)的客户端,CLI使用Docker REST API通过脚本或直接CLI命令控制Docker守护进程或与之交互,Docker对象包括图像(Image)、容器(Container)、网络(Network)和volumes。在Docker Engine上运行的Docker容器拥有以下3个特性。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/9a2bd5feaeeb4d23b06d6519df59f109~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=1GNhtH4bnTsxq%2BtHrzDO0kgw7Rg%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">(1)标准:Docker为容器创建了行业标准,因此它们可以随处携带。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">(2)轻量级:容器共享机器的操作系统内核,因此不需要每个应用程序的操作系统,从而提高服务器效率并降低服务器和许可成本。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">(3)安全:应用程序在容器中更安全,Docker提供业界最强大的默认隔离功能。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">Docker使用客户端-服务器架构。Docker客户端与Docker服务器(守护进程)进行通信,服务器负责构建、运行和分发Docker容器。Docker客户端和服务器可以在同一系统上运行,也可以将Docker客户端连接到远程Docker服务器。Docker客户端和服务器使用REST API,并通过UNIX Socket或网络接口进行通信。同时,Docker还提供了镜像仓库的机制,方便我们将构建好的镜像存储在镜像仓库中,快速地进行传输和部署,如图8.2所示。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/939b3fab4aaa4bca8ac03fdd1e98ebbb~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=BYJRvpppkQmFn97%2F%2BgRRERNDySI%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <h1 style="text-align: left; margin-bottom: 10px;">学习使用Docker</h1>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">使用容器可以更快地构建和部署新应用程序,Docker容器将软件及其依赖关系整合到一个标准化的软件开发单元中,包括运行所需的一切:代码、运行时、系统工具和库。这可以保证应用程序始终运行在相同的环境下,并使协作变得像共享容器映像一样简单。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">下面为大家介绍Docker具体的使用方法。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><strong style="color: blue;"><span style="color: green;">Docker的安装方法</span></strong></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">Docker的安装十分简单,且对各平台都很友好。在macOS和Windows中都有相应的安装包,可以一键安装。Docker有社区版和企业版两个版本,下面以社区版为例来介绍Docker具体的使用方式。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">首先,需要下载Docker的安装文件,可以在Docker Hub上找到各自平台的安装包 。以 macOS 为 例,双击下载的安装文件 :</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">Docker.dmg ( Windows 版 本 的 文 件 名 为 Docker for Windows Installer.exe ) , 然 后 在 出 现 的 窗 口 中 将 Docker.app 拖入Applications文件夹即可,如图8.3所示。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/915bccc94d714e36ba0f00c90a70ab7e~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=QD6LdFqUjZag7VT1D3Amb9jSrlk%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">安装好后可以通过双击Docker.app来启动Docker。默认随系统一起启动,然后在快速访问工具栏中看见Docker的图标,单击Docker的图标可以打开快捷菜单,如图8.4所示。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/29224f2085244e87aa8124baf0914310~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=TyTLnyBIkmrk7NNbbap9tWGlfAA%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">图 8.4 中 第一行会显示 Docker 的状态, “Docker Desktopisrunning”表示Docker目前正在运行,打开命令行工具输入如下指令。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker -v</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">如果安装成功,就会得到如下结果。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">Docker version 18.09.0, build 4d60db4</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">如果想要查看Docker完整的版本信息,可以输入以下指令。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker version</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">可以得到具体的Docker的Client和Server的详细信息,结果如下。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/70c0375460e54a1abbbf0412e9a301e0~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=SR7kKGrgZz65Xoz55FWzrLz7wfg%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">详细的安装教程可以在Docker的官网上找到。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><strong style="color: blue;"><span style="color: green;">构建Docker镜像</span></strong></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">如果说容器是Docker的核心,镜像就是核心的基础,正如之前所提到的,镜像在Docker Engine上运行时成为容器,无论基础架构如何,容器化软件都将始终运行在相同的环境中,容器将软件与其环境隔离开来,并确保它可以统一的工作,镜像是根文件系统更改的有序集合,它通常包含堆叠在彼此顶部的分层文件系统的并集,没有状态,而且永远不会改变。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">如何使用Docker镜像?一般在项目中,我们会搭建私有的Docker镜像仓库,或者使用云厂商提供的镜像仓库来存储项目中构建的镜像。当然,Docker也提供了公共的镜像仓库,可以把镜像仓库理解为我们在使用Gradle或Maven时的repository,这里使用Docker默认公网的镜像仓库来体验一下Docker镜像的用法。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">Docker官方提供了一个简单的镜像来让我们体验,镜像名为hello-world,打开命令行工具,输入如下指令,从镜像仓库拉取hello-world的镜像。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker pull hello-world</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">可以看到如下运行结果。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/ee3ad7741fac4c09a7a11246650c94dd~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=0g7wztNxqcJ9Is369VoI9GckrYw%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">通过运行的输出结果可以看出,这里下载了一个新的镜像helloworld:latest,Docker的镜像有tag的概念,tag就好比镜像的版本号,通过指定具体的tag来下载相应版本。例如,我们想要指定下载镜像a的v1.0.0版本,输入“docker pull a:v1.0.0”。这里拉取的hello-world并没有指定具体 的tag,Docker使用默认 的“tag:latest”的镜像进行下载。下载完成后,我们可以通过如下指令查询已经下载的镜像。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker images</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">显示结果如下。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p26-sign.toutiaoimg.com/pgc-image/807edadcdfa04a79b8b3d51521018d3b~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=8zAJchcJNPXiAxAA2v4PVFBY1xA%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">下载完成后,我们可以通过docker run来运行镜像,指令如下。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker run hello-world</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">如果显示结果如下,说明已经成功运行了一个Docker镜像。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/ff39a1b3e36046f6895f667184776e99~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=rKKagAyQRwTdpdrsHu4vIjkXyqA%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">当然,镜像也可以删除,指令如下。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker rmi hello-world</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">得到结果如下。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">Error response from daemon: conflict: unable to remove repository reference "hello-world"(must force)- container f8064c37e60d is using its referenced image fce289c99cb9</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">以上代码说明镜像有引用它的容器存在,还不能删除,并且告诉了我们容器的ID,所以可以先删除容器,指令如下。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker rm f8064e37e60d</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">成功删除容器后,再执行删除镜像的指令,得到结果如下。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/35e5407b6a29499db41ee93081ab5a8a~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=O3OC0mPpkOWjr3%2BW7sBuyBhCdi0%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">说明镜像已经成功被删除,那么一个镜像又是如何产生的?</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">Docker通过从Dockerfile的方式来定义所有命令,在构建镜像时从文本文件(Dockerfile)中读取指令来自动构建镜像Dockerfile遵循特定的格式和指令集,每层都代表一个Dockerfile指令,这些层是堆叠的,每层都是前一层变化的增量,且会按顺序构建给定镜像。下面是一个Dockerfile的例子。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/ec656915f6634725ae24ad754506e0fc~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=6irQuj2wqmgzLvmd9Ei%2BIfD5eJw%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">这里解释得比较模糊,下面以一个真实的项目为例来构建并运行一个镜像。例如,一个Spring Boot的工程项目,我们快速创建一个Spring Boot的Web,然后添加一个hello world的接口,代码如下。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/7b4ec717815347f9bd4bb41e8781a2cf~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=uOFZ5uANEzS284J0luXFxdrkF5A%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">由上述代码可知,这里提供了一个接口,URL是“/hello”,然后返回“World”的字符串,如果我们使用的是Gradle,编译之后在项目根目录的build/libs文件夹下产生一个jar包,即项目本身的最终产物,包名为</p>docker-test-webapp-0.0.1-SNAPSHOT.jar,然后通过Java指令运行这个jar包,指令如下。
            
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">java -jar build/libs/docker-test-webapp-0.0.1-SNAPSHOT.jar</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">我们可以将指令写在一个Shell文件中,在项目根目录创建名为run.sh的文件,并添加启动指令,这里稍作修改,让指令可以估计指定名称的关键字自动寻找jar包,内容如下。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/1dd4389f080e4ccbace618177b73bc2e~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=YqZq3qTWSXzgsNavOiRSQhMiCMQ%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">需要给run.sh配置权限,指令如下。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">chmod 755 run.sh</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">接下来就可以编写Dockerfile文件,首先来分析一下,我们的目的很简单,就是要将项目构建成镜像并运行,传统的方式会使用shell脚本来运行编译好的jar包,运行jar包需要在Java环境下执行,也就是jre或jdk;其次需要shell脚本来运行jar包,所以镜像中还应该包含shell脚本和jar包两个文件;最后需要在容器运行时执行shell脚本,接下来在项目的根目录下新建一个名为Dockerfile的文件,并添加如下内容。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/86305317a0c440eb94879f0fde54db50~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=O27VLjMXQKULBRT74wyP9i9hslo%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">指令的意思很明显,首先FROM来构建基础镜像,也就是以openjdk的镜像作为基础镜像,这样就有了jdk的运行环境,然后在COPY,复制我们的jar包和shell脚本到指定的目录,这里是/app目录,最后通过CMD指令,即在容器运行时运行shell脚本run.sh。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">构建之前还需要运行Gradle的编译指令生成jar包,指令如下。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">-./gradlew clean build</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">下面来试一下,运行如下指令来构建镜像。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">docker build -t docker-test-webapp:001 .</p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">“.”表示从当前目录读取Dockerfile文件来构建镜像,设置镜像的名称为docker-test webapp,tag是001,如果得到结果如下就说明构建成功了。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/9c849c13df9848029ded3590a51c81c8~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=5KBf9mBRbf1tj%2BSDlsdsBjhI6y4%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">通过输出可以清楚地看出这里按照顺序执行了4步操作,与我们定义在Dockerfile中的一致,然后通过之前提过的docker image指令来查看本地镜像,结果如下。</span></p>
    <div style="text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/2a97c9bc793043efb1b6fb2a03a4a60f~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1704569214&amp;x-signature=cGfVm8mJqxypIJU9r9aUIbot5ag%3D" style="width: 100%; margin-bottom: 20px;"></div>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">可以看到,在本地的镜像仓库中,已经存在了一个名为dockertest-webapp且tag为001的镜像,当然,在构建镜像之前不要忘记执行“./gradlew clean build”来构建好jar包,不然在构建镜像时会报错“找不到文件”。</span></p>
    <p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;"><span style="color: green;">这里只是列举了一些常用的指令来帮助大家理解Docker镜像的用法,详细的Dockerfile的指令还有很多。例如,通过ENV来设置环境变量,通过EXPOSE来设置容器在运行时侦听指定的网络端口,通过ADD指令复制文件、目录或远程文件,并将它们添加到镜像的文件系统中。此外,还有ENTRYPOINT、VOLUME和USER等指令,具体用法由于篇幅关系不再列举,可以在Docker的官网上找到详细的介绍。</span></p>
    <h1 style="text-align: left; margin-bottom: 10px;">本文给大家讲解的内容是DDD的挑战;</h1><span style="color: green;">下篇文章给大家讲解的是</span><span style="color: green;">运行Docker容器</span><span style="color: green;">觉得文章不错的朋友可以转发此文关注小编;</span><span style="color: green;">感谢大家的支持!</span>


页: [1]
查看完整版本: 微服务架构Docker,K8S,KVM,Hypervisor和微服务有什么区别联系吗?