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

往期连接:

http://www.javashuo.com/article/p-zwsmmmid-bm.htmlhtml

http://www.javashuo.com/article/p-ewonxmgb-eq.html前端

 

 

写在前面

容器是应用走向云端以后必然的发展趋势,所以笔者很是乐于和你们分享咱们这段时间对容器的理解、心得和实践。python

本教程持续编写了2个星期左右而且一直在完善、补充具体的细节和实践,预计所有完成须要1到2个月的时间。因为编写的过程当中极其费时,而且还须要配合作一些实践(有些实践存在一些坑,并且极其费时费事)。所以目前产出的速度已经跟不上发布的速度了,后续的发布节奏会放慢,请你们多多理解和多多包含。linux

根据目前和你们的交流,笔者针对你们的状况进行了一些修改和补充,但愿对你们有所帮助。另外,对于熟悉容器服务的你,也能够参与进来,让咱们一块儿打造这个系列教程,咱们但愿可以多多交流,多多分享,以帮助更多的人。同时,咱们也但愿获得你们的支持。nginx

前言

内容发出来以后,有部分小伙伴有些疑惑。这里我特别说明下,Docker for windows 指的是docker官方提供的windows的安装包,并非指的基于windows镜像开发。笔者推荐的方式是——在windows上开发和调测,托管到Linux。git

Docker持续开发工做流

Docker改变了开发以及产品交付流程,如下是通常状况下的Docker应用程序的内部循环的持续开发工做流,本工做流只关注在开发人员的计算机上进行的开发工做,不包括设置环境等初始步骤,由于这些步骤只需进行一次。web

应用程序通常由开发人员本身的服务代码和附加库(依赖项)组成,如下是生成 Docker 应用程序时经常使用的基本步骤,具体以下图所示:redis

在本篇教程中,咱们以开源框架Magicodes.Admin为例进行讲解。docker

Magicodes.Admin,是心莱科技团队打造的一套高效率、易扩展、基础设施强大、代码生成完备、理念和技术先进的敏捷开发框架,同时也是一套分布式(即将提供微服务架构参考)、跨平台(linux、Docker容器支持)、多终端(包括Android、IOS、H五、小程序、微信公众号)支持的统一开发框架和解决方案。框架基于.NET Core 2.一、Angular、Ionic、EF Core、ABP和ASP.NET Zero,并在其基础上进行了封装和完善,而且编写了相关的工具(代码生成)、组件(云存储、支付、微信等等)、生成服务。shell

代码地址:https://gitee.com/xl_wenqiang/Magicodes.Admin.Core

 

在开始以前,咱们先须要准备好相关环境和代码。好比:

Git clone git@gitee.com:xl_wenqiang/Magicodes.Admin.Core.git

相关环境以及前期准备你们能够参阅公众号”magiccodes“中的教程,这里就很少赘述了。

 

开发

开发过程其实和传统开发同样,也就是说,开发Docker 应用的方式与开发非Docker应用的方式相似。两者的主要区别在于,开发 Docker 应用程序时,是在本地环境中的Docker容器中部署和测试,该容器能够是Linux容器或Windows 容器。

 

通常状况下,咱们搭建好框架代码以后,就须要针对需求进行开发,以知足业务为目的,也就是这个开发过程并无什么改变,这里咱们假设全部代码均已就绪,开始下一步。

 

建立Dockerfile

本节内容不少,咱们但愿你们可以了解和使用好Dockerfile。

关于dockerfile

虽然咱们能够经过docker commit命令来手动建立镜像,可是经过Dockerfile文件,能够帮助咱们自动建立镜像,而且可以自定义建立过程。本质上,Dockerfile就是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终建立一个新的镜像。它简化了从头至尾的构建流程并极大的简化了部署工做。使用dockerfile构建镜像有如下好处:

  • 像编程同样构建镜像,支持分层构建以及缓存;

  • 能够快速而精确地从新建立镜像以便于维护和升级;

  • 便于持续集成;

  • 能够在任何地方快速构建镜像

 

Dockerfile指令

咱们须要了解一些基本的Dockerfile 指令,Dockerfile 指令为 Docker 引擎提供了建立容器映像所需的步骤。这些指令按顺序逐一执行。如下是有关一些基本 Dockerfile 指令的详细信息。

1.FROM

FROM 指令用于设置在新映像建立过程期间将使用的容器映像。

格式:FROM 

示例:

FROM nginx

FROM microsoft/dotnet:2.1-aspnetcore-runtime

  

2.RUN

RUN 指令指定将要运行并捕获到新容器映像中的命令。 这些命令包括安装软件、建立文件和目录,以及建立环境配置等。

格式:

RUN ["", "", ""]

RUN

示例:

RUN apt-get update

RUN mkdir -p /usr/src/redis

RUN apt-get update && apt-get install -y libgdiplus

RUN ["apt-get","install","-y","nginx"]

注意:每个指令都会建立一层,并构成新的镜像。当运行多个指令时,会产生一些很是臃肿、很是多层的镜像,不只仅增长了构建部署的时间,也很容易出错。所以,在不少状况下,咱们能够合并指令并运行,例如:RUN apt-get update && apt-get install -y libgdiplus。在命令过多时,必定要注意格式,好比换行、缩进、注释等,会让维护、排障更为容易,这是一个比较好的习惯。使用换行符时,可能会遇到一些问题,具体能够参阅下节的转义字符。

 

3.COPY

COPY 指令将文件和目录复制到容器的文件系统。文件和目录需位于相对于 Dockerfile 的路径中。

格式:

COPY

若是源或目标包含空格,请将路径括在方括号和双引号中。

 

COPY ["", ""]

示例:

COPY . .

COPY nginx.conf /etc/nginx/nginx.conf

COPY . /usr/share/nginx/html

COPY hom* /mydir/

 

4.ADD

ADD 指令与 COPY 指令很是相似,但它包含更多功能。除了将文件从主机复制到容器映像,ADD 指令还可使用 URL 规范从远程位置复制文件。

格式:

ADD<source> <destination>

示例:

ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe

此示例会将 Python for Windows下载到容器映像的 c:\temp 目录。

 

5.WORKDIR

WORKDIR 指令用于为其余 Dockerfile 指令(如 RUN、CMD)设置一个工做目录,而且还设置用于运行容器映像实例的工做目录。

格式:

WORKDIR

示例:

WORKDIR /app

 

6.CMD

CMD指令用于设置部署容器映像的实例时要运行的默认命令。例如,若是该容器将承载 NGINX Web 服务器,则 CMD 可能包括用于启动Web服务器的指令,如 nginx.exe。 若是 Dockerfile 中指定了多个CMD 指令,只会计算最后一个指令。

格式:

CMD ["<executable", "

CMD

示例:

CMD ["c:\\Apache24\\bin\\httpd.exe", "-w"]

CMD c:\\Apache24\\bin\\httpd.exe -w

 

7.ENTRYPOINT

配置容器启动后执行的命令,而且不可被 docker run 提供的参数覆盖。每一个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。

格式:

ENTRYPOINT ["", ""]

示例:

ENTRYPOINT ["dotnet", "Magicodes.Admin.Web.Host.dll"]

 

8.ENV

ENV命令用于设置环境变量。这些变量以”key=value”的形式存在,并能够在容器内被脚本或者程序调用。这个机制给在容器中运行应用带来了极大的便利。

格式:

ENV==...

示例:

ENV VERSION=1.0 DEBUG=on \

NAME="Magicodes"

 

9.EXPOSE

EXPOSE用来指定端口,使容器内的应用能够经过端口和外界交互。

格式:

EXPOSE

示例:

EXPOSE 80

 

说了这么多,咱们能够用下图来一言以蔽之:

 

转义字符

在许多状况下,Dockerfile 指令须要跨多个行;这可经过转义字符完成。 默认 Dockerfile 转义字符是反斜杠 \。 因为反斜杠在 Windows 中也是一个文件路径分隔符,这可能致使出现问题。

如下示例显示使用默认转义字符跨多个行的单个 RUN 指令。

FROM microsoft/windowsservercore

 

RUN powershell.exe -Command \

$ErrorActionPreference = 'Stop'; \

wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; \

Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \

Remove-Item c:\python-3.5.1.exe -Force

 

要修改转义字符,必须在 Dockerfile 最开始的行上放置一个转义分析程序指令。 如如下示例所示:

# escape=`

 

FROM microsoft/windowsservercore

 

RUN powershell.exe -Command `

$ErrorActionPreference = 'Stop'; `

wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; `

Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; `

Remove-Item c:\python-3.5.1.exe -Force

注意,只有两个值可用做转义字符:\ 和 ` 。

 

优化

篇幅有限,咱们这里只进行简单讲解,后续结合实际案例再进行细说。可是有几点值得注意的是:

  1. 不能忽视dockerfile的优化,一般状况下,咱们能够忽略那些细小的优化,可是咱们须要知道优化的原理,为何要优化

  2. 不能为了优化而优化。镜像的构建过程视业务状况状况不一样,指令就有多到少的区别,在不少状况下,咱们先要以知足业务目标为准,而不是镜像层数。若是须要减小镜像的层数,咱们必定要选择合适的基础镜像,或者建立符合咱们须要的基础镜像。

下面是一些优化的准则:

  • 选择合适的基础镜像

    这点相对最为重要。为何这么说,咱们结合现实社会也能够看到,在大部分状况下,一我的一辈子的成就更多的是看出身。不少状况下,基因和出身决定了你的高度和终点,这点拿到技术层面来讲,也是有很大道理的,所以咱们须要选择合适的父母——一个合适的镜像。

    一个合适的基础镜像是指能知足运行应用所须要的最小的镜像,理论上是能用小的就不要用大的,能用轻量的就不要用重量级的,能用性能好的就不要用性能差的。这里有时候还须要考虑那些可以减小咱们构建层数的基础镜像。

     

  • 优化指令顺序

    Docker会缓存Dockerfile中还没有更改的全部步骤,可是,若是更改任何指令,将重作其后的全部步骤。也就是指令3有变更,那么四、五、6就会重作。所以,咱们须要将最不可能产生更改的指令放在前面,按照这个顺序来编写dockerfile指令。这样,在构建过程当中,就能够节省不少时间。好比,咱们能够把WORKDIR、ENV等命令放前面,COPY、ADD放后面。

     

  • 合并指令

    前面其实咱们提到过这点,甚至还特意讲到了转义字符,其实主要是为此服务。前面咱们说到了,每个指令都会建立一层,并构成新的镜像。当运行多个指令时,会产生一些很是臃肿、很是多层的镜像,不只仅增长了构建部署的时间,也很容易出错。所以,在不少状况下,咱们能够合并指令并运行,例如:RUN apt-get update && apt-get install -y libgdiplus。在命令过多时,必定要注意格式,好比换行、缩进、注释等,会让维护、排障更为容易,这是一个比较好的习惯。

     

  • 删除多余文件和清理没用的中间结果

    这点很易于理解,一般来说,体积更小,部署更快!所以在构建过程当中,咱们须要清理那些最终不须要的代码或文件。好比说,临时文件、源代码、缓存等等。

      

  • 使用 .dockerignore

    .dockerignore文件用于忽略那些镜像构建时非必须的文件,这些文件能够是开发文档、日志、其余无用的文件。例如:

说了这么多,其实咱们更多的仍是须要根据命令的实际执行状况来进行调整。

 

Visual studio和dockerfile

如上所示,要生成自定义镜像,需为每一个自定义镜像提供一个 Dockerfile。不管是从Visual Studio 自动部署,仍是使用 Docker CLI(docker run 和 docker-compose 命令)手动部署,都需为每一个要部署的容器提供一个 Dockerfile。若是应用程序只包含一个自定义服务,则只须要一个 Dockerfile。若是应用程序包含多个服务(如在微服务体系结构中),则每一个服务都须要一个 Dockerfile。Dockerfile文件须要放在应用程序或服务的根文件夹中。

可是,对于.NET开发人员来讲,利用Visual Studio只需单击几回鼠标便可完成此任务。以下图所示:

还可经过在 Visual Studio 中右键单击项目文件,选择“添加 Docker 项目支持”选项,为新项目或现有项目启用 Docker 支持:

对项目(如 ASP.NET Web 应用程序或 Web API 服务)应用此操做后,系统会向含有所需配置的项目添加 Dockerfile。

在更多的状况下,笔者建议你们选择下面的菜单——容器业务流程协调程序支持:

由于会向整个解决方案添加 docker-compose.yml 等文件。整个过程,Visual Studio 代为执行了操做,可是,咱们也须要了解 Dockerfile中的内容,不然遇到问题,会抓虾,哦,是抓瞎。

启用了以后,咱们就能够看到顶部的菜单栏出现了一些便捷操做:

不只支持一键启动,还可以调试!!!这对于大部分开发者来讲,简直是天籁之音哈!

接下来,咱们以Magicodes.Admin为例。在Magicodes.Admin中,存在多个应用,好比后台服务和后台UI,目前框架中已经提供了多个dockerfile的配置,分别在相应的工程目录之中。

 

.net core后台服务的dockerfile

文件所在目录以下所示:

相关指令我在注释中进行了一一说明,不过,因为Excel的导出在Linux环境须要libgdiplus库的支持,以设置字体,所以咱们须要在dockerfile中配置安装此库。同时,咱们还推荐使用如下简化的dockerfile:

其中,包还原、编译、单元测试运行以及发布等过程咱们经过脚本进行了实现,所以在Dockerfile中,命令比较简单干净,关键是整个过程咱们可以在本地进行更多的自定义——好比执行单元测试并再经过以后才进行部署和推送。固然,使用第一个配置可以让咱们能够更好地和线上的CI工具配套使用。

注意:这里咱们并无使用其余web服务器,咱们直接在代码中使用了Kestrel服务器进行托管。

 

 

后台前端应用的dockerfile

文件所在目录以下所示:

后台前端应用使用nginx web服务器进行托管,同时执行了copy命令复制相关配置、静态文件和ssl证书。其中nginx.conf的配置以下所示:

关于dockerfile的相关内容,咱们先讲述到这里,但愿你们对此有个全面的了解。若是你有疑问或者建议,欢迎讨论交流。

往期连接:

http://www.javashuo.com/article/p-zwsmmmid-bm.html

http://www.javashuo.com/article/p-ewonxmgb-eq.html

相关文章
相关标签/搜索