禅心慧智 發表於 2018-12-5 09:54:00

Docker最全教程——从理论到实战(四)

<h2 style="text-align: left"><strong>往期内容链接</strong></h2>
<p><strong>https://www.cnblogs.com/codelove/p/10030439.html</strong></p>
<p>https://www.cnblogs.com/codelove/p/10036608.html</p>
<p>https://www.cnblogs.com/codelove/p/10056866.html</p>
<p>&nbsp;</p>
<p><strong>在笔者参加腾讯容器服务技术交流会时,我们了解到了藏区牧民的目前的生活艰辛状况,因此除了在同事朋友之间推荐其土特产之外,我们也在此进行初步分享,希望略尽绵薄之力,能够帮助到他们:</strong></p>
<p><strong>货真价实、确保都是3700米海拔以上的超风干牦牛肉,115元一斤包邮(货真价实、低于淘宝京东、我们不赚差价),有香辣、五香两种口味,三斤牦牛肉才能做出一斤超风干牛肉!希望这个冬天,我们能够给他们一点点温暖!有购买意向的朋友可以联系博主。</strong></p>
<p><strong><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205093539931-309712107.jpg" alt=""></strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h1><strong>创建自定义 Docker 镜像</strong></h1>
<p>&nbsp;</p>
<p>创建了Dockerfile之后,需为应用程序中的每项服务创建一个相关镜像。如果应用程序由单个服务或 Web 应用程序组成,则只需创建一个镜像。</p>
<p>我们可以使用docker build命令来创建镜像,例如:</p>
<p>docker build ./ -t {镜像名称}</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205093752069-190167980.png" alt=""></p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205093800977-852870353.png" alt=""></p>
<p>镜像打包好后,我们使用docker image ls命令即可查看当前镜像:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205093855351-595648727.png" alt=""></p>
<p><span style="background-color: rgba(0, 204, 255, 1)">注意:</span>Docker镜像使用分层存储的架构,也就是说镜像实际是由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。因为分层存储的特征,使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。所以,当我们使用Docker images命令,会列出这么多的镜像,我们可以定期清理那些无用的镜像。</p>
<p>如果使用 Visual Studio 创建带 Docker 支持的项目时,不会显式创建镜像。我们按下 F5 并运行时,VS就会自动创建镜像,不会出现明显的过程(在输出面板可以了解整个过程,如下图所示),但我们需要了解其原理,否则出现问题将无从下手。</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094011333-1805231572.png" alt=""></p>
<p>&nbsp;</p>
<h1><strong>在 docker-compose.yml中定义服务</strong></h1>
<p>&nbsp;</p>
<h2>关于Compose</h2>
<p>Compose是一个用于定义和运行多Docker应用程序的工具。使用Compose,我们可以使用YAML文件来配置应用程序的服务。然后,使用单个命令,我们就可以从配置中创建并启动所有服务。</p>
<p>Compose适用于所有环境:生产环境、模拟(演示)环境、开发环境和测试环境以及CI工作流程。</p>
<p>主要功能和特性:</p>
<ul class="list-paddingleft-2">
<li>
<p>单个主机上的多个隔离环境</p>
<p>Compose使用项目名称来隔离环境,因此可以根据不同的环境要求来进行定义。</p>
</li>
<li>
<p>创建容器时保留卷数据</p>
<p>Compose会保留服务使用的所有卷和数据。当使用docker-compose up命令运行时,如果发现该服务之前运行过,它会将进行增量操作,可确保在卷中创建的数据都不会丢失。</p>
</li>
<li>
<p>仅重新创建已更改的容器</p>
<p>Compose存在缓存,可用于创建容器。当重新启动未更改的服务时,Compose将重用现有容器。</p>
</li>
<li>
<p>可以定义变量,而且可以根据不同环境不同用户之间进行组合使用</p>
<p>Compose支持Compose文件的变量定义,我们可以使用这些变量为不同环境或不同用户进行自定义组合。</p>
</li>
</ul>
<p>另外,Compose能够通过命令管理应用程序的整个生命周期,通过命令可以:</p>
<ul class="list-paddingleft-2">
<li>
<p>启动,停止和重建服务等</p>
</li>
<li>
<p>查看正在运行的服务的状态</p>
</li>
<li>
<p>通过流输出正在运行的服务的日志</p>
</li>
<li>
<p>对某个服务执行命令</p>
</li>
</ul>
<p><span style="background-color: rgba(0, 204, 255, 1)">注意:</span>Docker for Windows安装包括:安装提供 Docker Engine,Docker CLI客户端,Docker Compose,Docker Machine和 Kitematic。也就是如果是使用Docker for Windows的用户,无需再独立安装Docker Compose。</p>
<p>我们可以通过运行以下命令来确认我们本地的环境:</p>
<p>docker-compose -v</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094136092-1409834283.png" alt=""></p>
<p>&nbsp;</p>
<h2>常见场景</h2>
<ul class="list-paddingleft-2">
<li>
<p>开发或本地环境运行多个服务</p>
<p>在开发过程时,在隔离环境中运行应用程序并与之交互的能力至关重要。Compose命令行工具可用于创建环境并与之交互。比如通过Compose文件,配置所有应用程序的服务依赖(数据库,消息队列,高速缓存,Web服务的API,等等),然后使用单个命令(docker-compose up)为每个依赖项创建和启动一个或多个容器,使整个程序能够正常运行起来。</p>
</li>
<li>
<p>自动化测试环境</p>
<p>任何持续部署或持续集成过程的一个重要部分是自动化测试套件。自动化端到端测试需要一个运行测试的环境。Compose提供了一种方便的方法来创建和销毁隔离的测试环境。我们只需要通过在Compose文件,即可定义完整环境,并且可以在几个命令中创建和销毁这些环境,如下所示:</p>
</li>
</ul>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094211548-703650178.png" alt=""></p>
<ul>
<li>单主机部署</li>
</ul>
<p>&nbsp;</p>
<h2>使用Compose</h2>
<p>使用Compose有以下三个步骤:</p>
<ol class="list-paddingleft-2">
<li>
<p>使用Dockerfile定义应用环境,以便在任意地方进行复制</p>
</li>
<li>
<p>在 docker-compose.yml 中定义组合应用,以便它们可以在隔离的环境中一起运行</p>
</li>
<li>
<p>最后,执行docker-compose up命令,Compose 将启动并运行整个应用程序。</p>
</li>
</ol>
<p>由此可见,第二步决定了Compose的执行,一个简单的docker-compose.yml文件如下所示:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094328013-186723507.png" alt=""></p>
<p>其定义了web和redis两个应用。接下来,我们一起来了解docker-compose.yml 文件。</p>
<p>&nbsp;</p>
<h2>了解docker-compose.yml</h2>
<p>借助 docker-compose.yml 文件,我们可以定义一组相关服务,通过部署命令将其部署为组合应用程序。简单的说,我们可以通过docker-compose.yml来定义多个服务,以便一次执行。</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094402699-10239551.png" alt=""></p>
<p>这里笔者以Magicodes.Admin为例,基础框架提供了后台接口服务以及后台前端应用两个,那么我们可以定义docker-compose.yml 文件以便部署为组合应用程序,也就是说,一个命令托管和运行多个服务:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094443650-81516303.png" alt=""></p>
<p>以上是一个简化的配置,定义了两个服务以及环境变量和端口。值得说明的是,在docker中我们无法访问localDb,这时我们建议访问独立的数据库服务或者使用数据库镜像,例如:</p>
<p>sql.data:</p>
<p>image: mssql-server-linux:latest</p>
<p>environment:</p>
<p>-&nbsp;SA_PASSWORD=Pass@word</p>
<p>-&nbsp;ACCEPT_EULA=Y</p>
<p>ports:</p>
<p>-&nbsp;"5433:1433"</p>
<p><span style="background-color: rgba(0, 204, 255, 1)">注意:</span>SQL Server也提供了Docker镜像,并且支持Linux容器。在上面的配置中,通过环境变量设置了sa账号的密码。值得注意的是,我们并不推荐在生产环境中使用数据库的容器镜像来托管数据,这点我们后续再来详聊。</p>
<p>&nbsp;</p>
<h2>了解YAML语言</h2>
<p>很多教程并不会讲述这点,但是笔者认为这点也非常重要,因为了解YAML的语法和规范,可以在开发调测的过程中避免很多错误,也便于我们更好的配置基于YAML语法的文件——比如docker-compose.yml文件。</p>
<p>&nbsp;</p>
<p>什么是YAML?</p>
<p>YAML 是一种简洁的非标记语言。YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读。</p>
<p>这里提供一个YAML语法验证网站:http://nodeca.github.io/js-yaml/</p>
<p>基本规则</p>
<ol class="list-paddingleft-2">
<li>
<p>大小写敏感</p>
</li>
<li>
<p>使用缩进表示层级关系</p>
</li>
<li>
<p>禁止使用tab缩进,只能使用空格键</p>
</li>
<li>
<p>缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级</p>
</li>
<li>
<p>使用#表示注释</p>
</li>
<li>
<p>字符串可以不用引号标注</p>
</li>
</ol>
<p>YAML中允许表示三种格式,分别是常量值,对象和数组,如下所示:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094613899-1061816782.png" alt=""></p>
<p>对于YAML的讲解,我们就说到这里,我们继续本篇内容。</p>
<p>&nbsp;</p>
<h2>docker-compose.yml文件配置项</h2>
<p>docker-compose.yml 文件不仅指定正在使用的容器,还指定如何单独配置各容器。常用的配置项如下所示:</p>
<ul class="list-paddingleft-2">
<li>
<p>build:定义镜像生成,可以指定Dockerfile文件所在的目录路径,支持绝对路径和相对路径;</p>
</li>
<li>
<p>image:从指定的镜像中启动容器,可以是存储仓库、标签以及镜像 ID,如果镜像不存在,Compose 会自动拉去镜像;</p>
</li>
<li>
<p>environment:定义环境变量和配置;</p>
</li>
<li>
<p>ports:定义端口映射,比如上面配置中将容器上的公开端口 80 转接到主机上的外部端口 9901和9902;</p>
</li>
<li>
<p>depends_on,定义依赖关系。此定义会让当前服务处于等待状态,直到这些依赖服务启动。比如某个服务依赖数据库服务,那么通过此配置解决了服务的启动顺序的问题;</p>
</li>
<li>
<p>volumes,挂载一个目录或者一个已存在的数据卷容器,可以直接使用 HOST:CONTAINER 这样的格式,或者使用 HOST:CONTAINER:ro 这样的格式,后者对于容器来说,数据卷是只读的,这样可以有效保护宿主机的文件系统;</p>
</li>
<li>
<p>context,指定Dockerfile 的文件路径,也可以是到链接到 git 仓库的 url;</p>
</li>
<li>
<p>args,指定构建参数,这些参数只能在构建过程中访问;</p>
</li>
<li>
<p>target,定义构建指定的阶段Dockerfile,比如针对不同阶段使用不同的dockerfile,开发阶段使用支持编译调试的dockerfile,而生产环境,则使用轻量级的dockerfile;command,覆盖默认命令;</p>
</li>
<li>
<p>container_name,指定自定义容器名称,而不是生成的默认名称。</p>
</li>
</ul>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094653278-1319182904.png" alt=""></p>
<p>由于篇幅有限,我们就不提供过多介绍和示例了。不过我们建议大家访问此地址,来做一个全面的了解:</p>
<p><span style="background-color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1)"><span style="text-decoration: underline; background-color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1)"><span style="background-color: rgba(51, 102, 255, 1)">https://docs.docker.com/compose/compose-file/#reference-and-guidelines</span></span></span></p>
<p>最后,分享几个小技巧:</p>
<ul class="list-paddingleft-2">
<li>
<p>可以通过配置项depends_on来定义依赖关系,这点对于控制服务的执行顺序尤为重要,比如先启动数据库然后再启动web服务。</p>
</li>
<li>
<p>如何使用JSON文件进行配置?可以指定文件名称,如下所示:</p>
<p>docker-compose -f docker-compose.json up</p>
</li>
<li>
<p>如何分阶段构建?推荐使用target配置项。</p>
</li>
</ul>
<p>&nbsp;</p>
<h2>Visual Studio和docker-compose</h2>
<p>我们定义完docker-compose.yml之后,如果是使用Visual Studio进行开发,通过其Docker tool会让开发调测变得非常简单和易用。对于未启用docker支持的项目,我们可以通过右键菜单进行启用:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094912142-316333617.png" alt=""></p>
<p>启用之后,会自动添加相关支持(包括生成dockerfile、docker-compose.yml以及.dockerignore等),然后通过其docker工具可以直接启动运行并且支持调试,如下图所示:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205094942611-1849635804.png" alt=""></p>
<p>点击工具栏的【Docker】按钮或者按下【F5】均可直接运行并调试,启动后如下图所示:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201812/70544-20181205095012745-248528672.png" alt=""></p>
<p>运行完成后,VS还会自动打开相关服务的默认页。</p>
<p>如果不依赖Visual Studio进行运行,我们在下节进行讲述。</p>

</div>
<div id="MySignature" role="contentinfo">
    作者:雪雁<br>出处:http://www.cnblogs.com/codelove/
<br>如果喜欢作者的文章,请关注【CodeSpirit-码灵】公众号以便第一时间获得最新内容。本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。<br><b>静听鸟语花香,漫赏云卷云舒。</b>
<br>
<img src="https://images.cnblogs.com/cnblogs_com/codelove/315887/o_251224070213_%E5%85%AC%E4%BC%97%E5%8F%B7.jpg" width="100" height="100"><br><br>
来源:https://www.cnblogs.com/codelove/p/10069220.html
頁: [1]
查看完整版本: Docker最全教程——从理论到实战(四)