Docker

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

2020-01-10  本文已影响0人  睦月MTK

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


一、实验目的

二、实验概述

三、实验预期效果

四、实验过程
  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,实验达到预期结果

六、实验总结

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


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


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

上一篇 下一篇

猜你喜欢

热点阅读