容器的基本概念

什么是容器?

容器就是一个视图隔离、资源可限制、独立文件系统的进程集合。所谓“视图隔离”就是能够看到部分进程以及具有独立的主机名等;控制资源使用率则是可以对于内存大小以及 CPU 使用个数等进行限制。容器就是一个进程集合,它将系统的其他资源隔离开来,具有自己独立的资源视图。

容器具有一个独立的文件系统,因为使用的是系统的资源,所以在独立的文件系统内不需要具备内核相关的代码或者工具,我们只需要提供容器所需的二进制文件、配置文件以及依赖即可。只要容器运行时所需的文件集合都能够具备,那么这个容器就能够运行起来。

如何为进程提供一个独立的运行环境呢?

  • 针对不同进程使用同一个文件系统所造成的问题而言,Linux 和 Unix 操作系统可以通过 chroot 系统调用将子目录变成根目录,达到视图级别的隔离;进程在 chroot 的帮助下可以具有独立的文件系统,对于这样的文件系统进行增删改查不会影响到其他进程;
  • 因为进程之间相互可见并且可以相互通信,使用 Namespace 技术来实现进程在资源的视图上进行隔离。在 chroot 和 Namespace 的帮助下,进程就能够运行在一个独立的环境下了;
  • 但在独立的环境下,进程所使用的还是同一个操作系统的资源,一些进程可能会侵蚀掉整个系统的资源。为了减少进程彼此之间的影响,可以通过 Cgroup 来限制其资源使用率,设置其能够使用的 CPU 以及内存量。

什么是镜像?

我们将容器运行时所需要的所有的文件集合称之为容器镜像。

docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。

那么,一般都是通过什么样的方式来构建镜像的呢?通常情况下,我们会采用 Dockerfile 来构建镜像,这是因为 Dockerfile 提供了非常便利的语法糖,能够帮助我们很好地描述构建的每个步骤。当然,每个构建步骤都会对已有的文件系统进行操作,这样就会带来文件系统内容的变化,我们将这些变化称之为 changeset。当我们把构建步骤所产生的变化依次作用到一个空文件夹上,就能够得到一个完整的镜像。

changeset 的分层以及复用特点能够带来几点优势

第一,能够提高分发效率,简单试想一下,对于大的镜像而言,如果将其拆分成各个小块就能够提高镜像的分发效率,这是因为镜像拆分之后就可以并行下载这些数据;

第二,因为这些数据是相互共享的,也就意味着当本地存储上包含了一些数据的时候,只需要下载本地没有的数据即可,举个简单的例子就是 golang 镜像是基于 alpine 镜像进行构建的,当本地已经具有了 alpine 镜像之后,在下载 golang 镜像的时候只需要下载本地 alpine 镜像中没有的部分即可;

第三,因为镜像数据是共享的,因此可以节约大量的磁盘空间,简单设想一下,当本地存储具有了 alpine 镜像和 golang 镜像,在没有复用的能力之前,alpine 镜像具有 5M 大小,golang 镜像有 300M 大小,因此就会占用 305M 空间;而当具有了复用能力之后,只需要 300M 空间即可。

容器的使用

本部分主要围绕学习赛所用到的命令进行讲解从而学习docker的使用流程

构建Docker镜像

在项目的根目录下,新建一个文本文件Dockerfile,其中包含一组指令来告诉 Docker 如何构建我们的镜像。Docker会根据该文件生成二进制的 image 文件。

# 指定基础镜像
FROM registry.cn-shanghai.aliyuncs.com/tcc-public/java:jdk_13.0.2
# 把当前文件夹里的文件拷贝到镜像的根目录下
ADD . /
# 指定接下来的工作路径为/(根目录)
WORKDIR /
# 指定镜像启动后要执行的命令
CMD ["sh","run.sh"]

构建启动后要执行的run.sh

run.sh内容

java -jar XX.jar

编写业务部分

这部分就是我们真正的项目内容,按照赛题来说,其实业务代码逻辑很简单,生成json就可以了,镜像下面也已经给好了csv文件,json这块我用了fastjson,打jar包的时候把依赖一起打进去就可以啦。

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; public class TC {
public static void main(String[] args) {
List<Integer> res = new ArrayList<>();
int sum = 0;
try (BufferedReader file = new BufferedReader(new InputStreamReader(new FileInputStream("/tcdata/num_list.csv"), "UTF-8"))) {
String record;
while ((record = file.readLine()) != null) {
res.add(Integer.parseInt(record));
sum += Integer.parseInt(record);
}
} catch (Exception e) { }
Collections.sort(res,Collections.reverseOrder());
JSONObject jsonObject = new JSONObject();
JSONArray jsonArray = new JSONArray();
for(int i = 0;i < 10;i++){
if(i >= res.size())
break;
jsonArray.add(res.get(i));
}
jsonObject.put("Q1","Hello world");
jsonObject.put("Q2",sum);
jsonObject.put("Q3",jsonArray); String sourceString = jsonObject.toJSONString(); //待写入字符串
byte[] sourceByte = sourceString.getBytes();
if(null != sourceByte) {
try {
File file = new File("result.json"); //文件路径(路径+文件名)
if (!file.exists()) { //文件不存在则创建文件,先创建目录
file.createNewFile();
}
FileOutputStream outStream = new FileOutputStream(file); //文件输出流用于将数据写入文件
outStream.write(sourceByte);
outStream.close(); //关闭文件输出流
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

本地测试

镜像抓取

镜像抓取命令

docker image pull library/hello-world

上面代码中,docker image pull是抓取 image 文件的命令。library/hello-world是 image 文件在仓库里面的位置,其中library是 image 文件所在的组,hello-world是 image 文件的名字。

Base Docker Image List中给出了主办方为我们提供的镜像列表,所以我们通过以下指令获取java镜像

docker pull registry.cn-shanghai.aliyuncs.com/tcc-public/java:jdk_13.0.2

本地构建

docker build -t registry.cn-shanghai.aliyuncs.com/wx_namespace/wx_namespace_learning:2 .

本地运行测试

这块我还有一点疑问,就是我docker run container后进入到容器中查看并没有发现/tcdata/num_list.csv文件,可是提交却能够通过,这块还不知道是为什么?

回答:跟群友交流得知,这个文件并不在提供给我们的镜像中,而是在评测环境中。

docker run -v /data:/tcdata your_image sh run.sh

可以通过 -v 把运行环境的某个路径映射成镜像里的/tcdata。比如这里我把我主机的/data目录映射成 /tcdata目录。

有点类似windows上面的映射网络驱动器。

sudo docker run –it registry.cn-shanghai.aliyuncs.com/wx_namespace/wx_namespace_learning:2 /bin/bash

-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。

/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。

我们可以通过run指令查看运行结果,进行本地测试。

构建镜像并推送

命令行推送

推送的话说起来其实很简单

docker push registry.cn-shenzhen.aliyuncs.com/test_for_tianchi/test_for_tianchi_submit:1.0

但是由于比赛推荐我们使用私有仓库,所以要先登录下阿里云账号

sudo docker login --username=XXX registry.cn-shanghai.aliyuncs.com

IDE + Cloud Toolkit方法

IDE + Cloud Toolkit

这种方式推送到镜像仓库比较便捷,具体可以见链接

提交运行

推送到镜像仓库后,在竞赛界面提交运行即可。

天池Docker学习赛笔记的更多相关文章

  1. Docker 学习新手笔记:从入门到放弃

    本文记录的是作为一个新手,从了解 Docker 是什么.Docker 技术包含哪些概念到上手使用.安装以及发布 Docker 镜像的整个过程.作者在学习过程中参阅了诸多文档和教程,在此一并感谢,与此同 ...

  2. Docker 学习记录笔记(一)

    Docker 一些简单的命令列表docker build -t friendlyhello . # Create image using this directory's Dockerfiledock ...

  3. docker学习读书笔记-一期-整理

    0.Docker - 第零章:前言 1.Docker - 第一章:Docker简介 2.Docker - 第二章:第一个Docker应用 3.Docker - 第三章:Docker常用命令 4.Doc ...

  4. Docker学习笔记 — 配置国内免费registry mirror

    Docker学习笔记 — 配置国内免费registry mirror Docker学习笔记 — 配置国内免费registry mirror

  5. docker学习笔记1 -- 安装和配置

    技术资料 docker中文官网:http://www.docker.org.cn/ 中文入门课程:http://www.docker.org.cn/book/docker.html docker学习笔 ...

  6. Docker学习笔记之一,搭建一个JAVA Tomcat运行环境

    Docker学习笔记之一,搭建一个JAVA Tomcat运行环境 前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序 ...

  7. docker~学习笔记索引

    回到占占推荐博客索引 使用docker也有段时间了,写了不少文章与总结,下面把它整理个目录出来,方便大家去学习与检索! docker~学习笔记索引 docker~linux下的部署和基本命令(2017 ...

  8. Docker学习笔记 - Docker容器内部署redis

    Docker学习笔记(2-4)Docker应用实验-redist server 和client的安装使用 一.获取redis容器(含客户端和服务端) 二.创建服务端容器 1.在终端A中运行redis- ...

  9. docker学习笔记(一)—— ubuntu16.04下安装docker

    docker学习笔记(一)—— ubuntu16.04下安装docker 原创 2018年03月01日 14:53:00 标签: docker / ubuntu 1682 本文开发环境为Ubuntu ...

随机推荐

  1. 【翻译】.NET 5 Preview2发布

    在4月2日,发布了.NET 5.0 Preview2,这次发布对一些功能和性能做了相关的改进,同时后面也会实施5.0版本更多的功能,其中一些功能目前也dotnet/designs在.NET 5 Pre ...

  2. Activiti网关--包含网关

    1.什么是包含网关 包含网关可以看做是排他网关和并行网关的结合体:和排他网关一样,你可以在外出顺序流上定义条件,包含网关会解析它们:但是主要的区别是包含网关可以选择多于一条顺序流,这和并行网关一样,包 ...

  3. Java并发基础04. 线程技术之死锁问题

    我们知道,使用 synchronized 关键字可以有效的解决线程同步问题,但是如果不恰当的使用 synchronized 关键字的话也会出问题,即我们所说的死锁.死锁是这样一种情形:多个线程同时被阻 ...

  4. Oracle给权限和同义词

    在同一个DB下,用户A创建了一个Table(student),用户B无法访问.如果B想要访问,就需要A赋予B权限. 登录用户A执行下面语句: GRANT SELECT, INSERT, UPDATE, ...

  5. 1020 Tree Traversals (25 分)

    Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and i ...

  6. VXLAN 基础教程:VXLAN 协议原理介绍

    VXLAN(Virtual eXtensible Local Area Network,虚拟可扩展局域网),是一种虚拟化隧道通信技术.它是一种 Overlay(覆盖网络)技术,通过三层的网络来搭建虚拟 ...

  7. MTK Android 权限大全

    Android权限大全 1.android.permission.WRITE_USER_DICTIONARY允许应用程序向用户词典中写入新词 2.android.permission.WRITE_SY ...

  8. (js描述的)数据结构[哈希表1.2](9)

    一. 优秀的哈希函数 1.快速的计算: 需要快速的计算来获得对应的hashCode(霍纳法则来减少乘除次数) 2.均匀的分布: 尽可能将元素映射到不同的位置,让元素在哈希表中均匀分布 二.哈希表的扩容 ...

  9. Mac 系统root

    没错,你没看错,就是root mac系统安装件的时候,你有没有遇到过这种情况 总之,就是安装不上软件,肿么办? 网上解觉办法是: 进入系统偏好设置,设置为允许任何人,可是进去后这样: 别着急,打开命令 ...

  10. 33.1 File 获取目录下的所有文件及子目录

    重要获取功能 String[] list() 返回当前路径下所有的文件和文件夹名称 //注意:只有指向文件夹的File对象才可以调用该方法(指向文件的file对象使用list会报错npe) File[ ...