天池Docker练习场实践

基本的操作框架详细参考官方的手把手教程即可,主要记录下自己实践过程中遇到的问题。

任务描述

参与者可分阶段提交容器镜像完成以下3个任务(分数依次占 30/30/40),根据评分系统的分数返回验证任务的完成情况。

  • 输出Hello world
  • 计算 /tcdata/num_list.csv中一列数字的总和。
  • /tcdata/num_list.csv文件中寻找最大的10个数,从大到小生成一个ListList.

num_list.csv文件中只有一列不为负的整数,其中存在重复值,示例如下:

102
6
11
11

生成入口脚本run.sh,放置于镜像工作目录。运行后生成结果result.json放置于工作目录(与run.sh同目录),评分系统将根据result.json进行打分。json文件如下所示:

1
2
3
4
5
{  
"Q1":"Hello world",
"Q2":sum值,
"Q3":[top10_list]
}

数据生成

生成测试文件

首先需要在自己本地的机子上面构造一个和官方格式一样的csv文件以方便自己调试。

因为是csv文件所以很自然的想到使用pandas来处理。

1
2
3
4
from pandas import DataFrame as df
import pandas as pd
import numpy as np
import json

使用随机数来生成数据,然后转换为dataframe,再保存在csv文件中。

1
2
3
4
data_dict = []
for i in range(100):
data_dict.append(np.random.randint(0,20))
data_df = df(data_dict)

因为csv文件只有一列,所以保存的时候需要关闭header和index

1
data_df.to_csv("num_list.csv",header=False,index=False)

读取文件处理

有了测试数据后就可以开始读入数据并进行处理了,读入的时候依然需要关闭header

1
data_df.to_csv("num_list.csv",header=False,index=False)

任务的要求很简单直接放代码了,建立一个solution.py,内容如下:

1
2
3
4
5
6
7
8
9
10
data_df.to_csv("/tcdata/num_list.csv",header=False,index=False)
read_list = list(read_df.index)
read_list = sorted(read_list,reverse=True)
result = {
"Q1":"Hello world",
"Q2":sum(read_list),
"Q3":read_list[0:10]
}
with open ("result.json","w") as f:
json.dump(result,f)

镜像构建

Dockerfile

在自己的工作目录下建立对应的Dockerfile,run.sh,和上面的solution.py

其中Dockerfile的内容和官方教程一致:

1
2
3
4
5
6
7
8
9
10
11
12
# Base Images
## 从天池基础镜像构建
FROM registry.cn-shanghai.aliyuncs.com/tcc-public/python:3

## 把当前文件夹里的文件构建到镜像的根目录下
ADD . /

## 指定默认工作目录为根目录(需要把run.sh和生成的结果文件都放在该文件夹下,提交后才能运行)
WORKDIR /

## 镜像启动后统一执行 sh run.sh
CMD ["sh", "run.sh"]

run.sh的内容为:

1
python3 solution.py

然后构建镜像

1
docker build -t registry.cn-shenzhen.aliyuncs.com/test_for_tianchi/test_for_tianchi_submit:1.0 .

官方构建的镜像名字特别长,所以可以先使用个比较短的名字test,方便后面调试。

1
docker build -t test:1.0 .

从镜像构建一个新容器然后进入容器:

1
docker run -it test:1.0 bash

其中-it是交互模式,bash是需要执行的命令,表示进入容器的终端。

依赖安装

在构建镜像的时候如果直接就按照官方的教程不调试的话直接提交会出现很多包未安装的问题,因为构建的镜像是个新的操作系统,从官方的python3基础镜像构建时,基础的镜像是没有安装很多常用的包的,比如上面需要使用到的pandas包。

在进入镜像后会发现,并没有安装vim,直接执行apt-get install vim也会报错找不到包,这时因为并没有更新源,所以需要先执行apt-get update来更新源,然后再安装vim。

之后使用pip安装pandaspip install pandas

需要注意的是,在容器中安装完对应的包或者对容器的文件执行了修改后,不能直接退出,需要在另外一个终端使用docker ps列出当前容器的id,然后使用docker commit container-id保存修改到镜像。如果没有保存而直接退出,下次使用镜像构建容器的时候依然需要重新安装对应的依赖。

数据挂载

在本地生成了num_list.csv后,可以将对应的目录挂载到容器上,这样就可以在容器中进行完整的调试,挂载的命令为:

1
docker run -it -v /local/dir:/tcdata image:version bash

冒号前面的是本地的数据文件目录,后面的是容器中的目录。

镜像推送

在完成本地容器调试后,就可以将镜像推送到仓库中了。

首先必须先进行登陆

1
sudo docker login --username=name registry.cn-shenzhen.aliyuncs.com

然后如果前面的镜像名字是test等自定义的则需要重命名镜像

1
sudo docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/yky_docker/image_name:[镜像版本号]

最后执行推送命令就可以了:

1
sudo docker push registry.cn-shenzhen.aliyuncs.com/yky_docker/image_name:[镜像版本号]

完成推送后到比赛界面提交对应的镜像即可。

参考

官方手把手教程