阿里云Docker新人赛

本文详述了作者参与阿里云Docker新人赛的经历,包括使用Java实现功能、创建Maven工程、解决打包问题、编写run.sh脚本、构建Dockerfile,以及将镜像推送到阿里云Registry的过程。在实践中遇到的主类名指定和依赖打包问题通过Maven插件得以解决,强调了熟悉Docker基本流程的重要性。
摘要由CSDN通过智能技术生成

本文首发于个人博客: https://joemendezckh.github.io/posts/249f9dc1.html
主要是记录参加阿里云docker新人赛 Docker练习场 的过程以及自已遇到的一些坑
使用 java 实现

  • 首先, 官方的帮助文档将流程介绍的已经很详细了, 在此不做赘述
  • 直接从Java实现写起

如何实现 run.sh 调用我们的函数

  1. 一个 web 工程, 通过 curl 发送 get 请求调用函数
    • 优点: 可以重复调用
    • 缺点: 感觉有点跑题, 目的是学习docker, 不是web…
  2. 直接 main 函数, 打成jar包后直接运行
    • 简单粗暴

综上: 我选择了方案 2 (中间有个小坑)

新建一个 maven 工程

  • 编写实现功能的代码

    public static final String NUM_LIST = "/tcdata/num_list.csv";
    public static final String PATH = "result.json";
    
    public static void main(String[] args) {
    
        File resultFile = new File(PATH);
        File numFile = new File(NUM_LIST);
        try {
            if (!resultFile.exists()) {
                resultFile.createNewFile();
            }
            
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("Q1", "Hello world");
            final List<String> list = FileUtils.readLines(numFile, "UTF-8");
            
            final ArrayList<Integer> integers = new ArrayList<>(10);
            
            list.forEach(num -> integers.add(Integer.parseInt(num)));
            int sum = integers.stream().mapToInt(num -> num).sum();
    
            final int[] result = integers.stream()
                .sorted(Comparator.comparing(Integer::intValue).reversed())
                .mapToInt(n -> n).limit(10).toArray();
    
            jsonObject.put("Q2", sum);
            jsonObject.put("Q3", result);
    
            FileOutputStream fileOutputStream = new FileOutputStream(resultFile);
            fileOutputStream.write(jsonObject.toJSONString().getBytes());
    
            System.out.println("success");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("failed");
        }
    }
    
    • 使用了 2 个工具类 fastjsoncommons-io
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.68</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>
    
小坑
  • 要指定 java -jar 运行的主类名, 方可执行

  • 直接运行是可以的, 但是直接打包再在本地运行jar包的话, 会抛异常

    Exception in thread "main" java.lang.NoClassDefFoundError: com/alibaba/fastjson/JSONObject
            at com.joe.tcdata.TaskRun.main(TaskRun.java:13)
    Caused by: java.lang.ClassNotFoundException: com.alibaba.fastjson.JSONObject
            at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            ... 1 more
    
    • 这是因为maven在打包的过程中, 没有将 fastjsoncommons-io打包进去

    • 修改 pom 和 手动添加 jar 包都不生效, 最后通过 maven 插件解决

      详细分析见: Maven构建可执行的jar包(包含依赖jar包)

      此时就可以解决了

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <appendAssemblyId>false</appendAssemblyId>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifest>
                    <!-- 此处指定main方法入口的class -->
                    <mainClass>com.joe.tcdata.TaskRun</mainClass>
                </manifest>
            </archive>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>assembly</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    

编写run.sh

#!/bin/sh
java -jar tcdata-1.0.0.jar > tcdata.log

编写Dockerfile

FROM            registry.cn-shanghai.aliyuncs.com/tcc-public/java:jdk_13.0.2
MAINTAINER      作者<作者邮箱>
# 添加当前文件夹下所有内容(包括 jar包和 run.sh) 到 container 的 / 目录
ADD 		. /
WORKDIR 	/
CMD 		["sh", "run.sh"]
  • 注意:

    /tcdata/num_list.csv 该文件在提交回答的时候, 会自动生成, 不需要我们自己编写

    但是在build 好镜像后, 是不存在这个目录的, 所以 build 好的镜像是不能执行的

    也就是说, 需要提前在本地测试好 jar 包没有问题, 这样提交后出现错误才是 docker 方面的问题

推送到自己的仓库

这一步可以看官方的指导, 很详细

登录阿里云Docker Registry
$ sudo docker login --username=用户名 registry.cn-shanghai.aliyuncs.com

用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。

从Registry中拉取镜像
$ sudo docker pull registry.cn-shanghai.aliyuncs.com/用户名/仓库名:[镜像版本号]
将镜像推送到Registry
$ sudo docker login --username=用户名 registry.cn-shanghai.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/用户名/仓库名:[镜像版本号]
$ sudo docker push registry.cn-shanghai.aliyuncs.com/用户名/仓库名:[镜像版本号]

提交回答

  • 建议将该仓库设置为公有仓库, 这样比较省事, 不然要写用户名和密码, 可能出错
    image-20200517130659535.png

小结

这个 docker新人赛最大的作用就是熟悉整个 docker 的基本运行流程, 以及基础的知识, 只是一个起步.

继续努力学习!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值