美文网首页Docker
S2.9:多语言集合项目的容器实验

S2.9:多语言集合项目的容器实验

作者: 睦月MTK | 来源:发表于2020-01-10 13:25 被阅读0次

声明:所有的实验示例大部分来自《learn-docker-in-a-month-of-lunches》的作者Elton Stoneman,但运行结果并不都是照搬,大部分实验结果可能与原书不同


一、实验目的
  • 为了加深对镜像创建与多阶段镜像创建的理解
  • 为了验证不同类型的语言(Java、Node.JS、Go)在镜像创建上的流程是否一致
  • 利用这个综合性实验加深对docker的理解

二、实验概述
  • 实验的项目分别在ch04/exercises目录下的image-of-the-day、image-gallery、access-log三个子目录内
  • access-log是一个Node.js编写的Web项目,由NPM进行包的管理,功能是提供一个被调用的接口,该接口被调用后,会记录传过来的日志信息,并在网页中显示日志数量
  • image-of-the-day是一个由Java语言编写的,Spring Boot作为框架的Web项目,由Maven进行依赖管理,功能是在网页中显示从NASA获取的每日图片的各种信息,并调用access-log接口记录访问的网站
  • image-gallery是一个由Go语言进行编写的Web项目,功能是调用image-of-the-day的接口获取图片信息,并将图片信息可视化展现出来
  • Java、Node.js、Go这三种语言的执行过程差别很大。Java会先编译成Java字节码文件,然后由Java虚拟机进行运行。Node.Js是脚本类语言,可由解释器直接解释运行。Go语言会被先编译成对应平台的二进制文件,然后由对应平台自己执行。

三、实验预期效果
  • 独立访问三个项目,结果均没有异常
  • 访问image-gallery能够看到获取到的图片、标题等信息,然后刷新access-log页面,可以看到日志数量不为0

四、实验过程
  1. 创建docker虚拟网络(用于容器之间的互相访问,容器在该网络上的地址由Docker在创建容器时分配,该网络上的容器如果要访问另外一个同时也在网络上的容器,只需要使用另一个容器的容器名即可,指定某个容器加入某个虚拟网络使用--network选项就可以了)
$ docker network create nat
  1. 运行image-of-the-day项目

    • 查看Dockerfile并分析
    $ cd diamol/ch04/exercises/image-of-the-day
    $ cat Dockerfile
    FROM diamol/maven AS builder
    
    WORKDIR /usr/src/iotd
    COPY pom.xml .
    RUN mvn -B dependency:go-offline
    
    COPY . .
    RUN mvn package
    
    # app
    FROM diamol/openjdk
    
    WORKDIR /app
    COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar .
    
    EXPOSE 80
    ENTRYPOINT ["java", "-jar", "/app/iotd-service-0.1.0.jar"]
    

    builder阶段使用的是diamol/maven镜像,里面包含Jdk以及Maven等工具,该阶段将项目打包成jar包供下个阶段使用

    final[1]阶段使用的镜像只包含运行jar包的OpenJDK

    • 生成镜像(生成过程较长,会包含springboot的日志和maven的日志,略去不写)
    $ docker image build --tag image-of-the-day .
    $ docker image ls image-of-the-day
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    image-of-the-day    latest              c296340fbed8        46 hours ago        222MB
    
    • 创建一个容器,命名为iotd,并加入虚拟网络nat,开放本机8080端口给容器的80
    $ docker container run --name iotd --network nat --publish 8080:80 --detach image-of-the-day
    $ docker container ls
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
    aa960be5e7ae        image-of-the-day    "java -jar /app/iotd…"   31 seconds ago      Up 30 seconds           0.0.0.0:8080->80/tcp   iotd
    
    • 浏览器访问localhost:8080/image查看结果
      image-of-the-day
  2. 运行access-log项目

    • 查看Dockerfile并分析
    $ cd diamol/ch04/exercises/access-log
    $ cat Dockerfile
    FROM diamol/node AS builder
    
    WORKDIR /src
    COPY src/package.json .
    RUN npm install
    
    # app
    FROM diamol/node
    
    EXPOSE 80
    CMD ["node", "server.js"]
    
    WORKDIR /app
    COPY --from=builder /src/node_modules/ /app/node_modules/
    COPY src/ .
    

    因为Js是一门解释性的语言,其实不存在编译阶段,但它需要NPM来进行包的的管理,npm install会下载所需的依赖到node_modules中,其实也可以进行分阶段(虽然我也觉得意义不大)

    • 生成镜像(略去镜像生成过程)
    $ docker image build --tag access-log .
    $ docker image ls access-log
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    access-log          latest              eef7fdb72b9f        45 hours ago        88MB
    
    • 创建一个容器,命名为accesslog,并加入虚拟网络nat,开放本机8081端口给容器的80
    $ docker container run --name accesslog --network nat --publish 8081:80 --detach access-log
    $ docker container ls
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    89ed197cffb8        access-log          "docker-entrypoint.s…"   9 seconds ago       Up 7 seconds        0.0.0.0:8081->80/tcp   accesslog
    aa960be5e7ae        image-of-the-day    "java -jar /app/iotd…"   38 minutes ago      Up 38 minutes       0.0.0.0:8080->80/tcp   iotd
    
    • 浏览器访问http://localhost:8081/stats查看结果
      access-log
  3. 运行image-gallery项目

    • 查看Dockerfile并分析
    $ cd diamol/ch04/exercises/image-gallery
    $cat Dockerfile
    FROM diamol/golang AS builder
    
    COPY main.go .
    RUN go build -o /server
    
    # app
    FROM diamol/base
    
    ENV IMAGE_API_URL="http://iotd/image" \
        ACCESS_API_URL="http://accesslog/access-log"
    
    CMD ["/web/server"]
    
    WORKDIR /web
    COPY index.html .
    COPY --from=builder /server .
    RUN chmod +x server
    

    Go语言会被编译成所在平台对应的二进制文件,所以在final阶段其实只需要含有对应平台的系统就可以了,设置了两个环境变量IMAGE_API_URLACCESS_API_URL用来指向前两个项目,RUN chmod +x server用来设置在linux上的执行权限

    • 生成镜像(略去镜像生成过程)
    $ docker image build --tag image-gallery .
    $ docker image ls image-gallery
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    image-gallery       latest              e2f1da18e564        45 hours ago        25.5MB
    

    其实你会发现,经过多阶段生成的Go镜像极其的小

    • 创建一个容器,加入虚拟网络nat,开放本机8082端口给容器的80
    $ docker container run --network nat --publish 8082:80 --detach image-gallery
    $ docker container ls
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    ea3888ec096d        image-gallery       "/web/server"            12 seconds ago      Up 11 seconds       0.0.0.0:8082->80/tcp   jovial_cohen
    89ed197cffb8        access-log          "docker-entrypoint.s…"   21 minutes ago      Up 21 minutes       0.0.0.0:8081->80/tcp   accesslog
    aa960be5e7ae        image-of-the-day    "java -jar /app/iotd…"   59 minutes ago      Up 59 minutes       0.0.0.0:8080->80/tcp   iotd
    
    • 浏览器访问http://localhost:8082/查看结果
      image-gallery

五、实验结果

打开http://localhost:8082/能看到图片,打开http://localhost:8081/stats能看到logs不为0,实验达到预期结果

六、实验总结

虽然三种语言执行的流程大相径庭,但是都可以从中发现这么一些规律:

  • 都将繁琐的编译,需要其他工具(final阶段不需要的)进行完成的任务放在了上一个阶段,只保留最简洁的部分给最终镜像,这也避免了潜在的攻击风险
  • 三个项目都经历了创建镜像,创建容器这些流程,说明Docker的执行是具有标准流程的,这也确保了Docker良好的跨平台性与通用性
  • 虽然容器之间是彼此独立的,但是容器可以通过多种方式去和外界沟通,甚至去和其他容器沟通

参考文档:
[1] learn-docker-in-a-month-of-lunches
[2] 官方文档
附:
[1] Elton Stoneman的github项目


  1. 没有特殊说明,final阶段均指最后一个阶段

相关文章

网友评论

    本文标题:S2.9:多语言集合项目的容器实验

    本文链接:https://www.haomeiwen.com/subject/causactx.html