容器的基本概念

什么是容器?

容器就是一个视图隔离、资源可限制、独立文件系统的进程集合。所谓“视图隔离”就是能够看到部分进程以及具有独立的主机名等;控制资源使用率则是可以对于内存大小以及 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. 面试刷题27:程序员如何防护java界的新冠肺炎?

    背景 安全是软件设计的第二个非功能性需求,一般是当软件出现安全问题的时候才会得到重视. 最明显的比如 数据库用户信息和密码泄漏等: 数据加解密技术 单向加密 md5+salt值, 这个是软件设计中使用 ...

  2. coding++:RateLimiter 限流算法之漏桶算法、令牌桶算法--简介

    RateLimiter是Guava的concurrent包下的一个用于限制访问频率的类 <dependency> <groupId>com.google.guava</g ...

  3. ElasticSearch 倒排索引

    倒排索引 倒排表以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的所有文档,一个表项就是一个字表段,它记录该文档的ID和字符在该文档中出现的位置情况. 由于每个字或词对应的文档 ...

  4. h5 js数组Array方法总结

    重新复习数组方法. 一.首先说一下构建一个数组. 1.直接定义一个数组. var a = [1,2,3]; 2.通过Array 对象new一个数组,但Array对象根据传参的不同会返回不同的数组对象. ...

  5. Prism 源码解读5-数据绑定和命令

    介绍 WPF本身就支持通知.绑定和命令,实现ViewModel和VIew之间的通讯,但相对来说功能比较少,Prism扩充了这些功能并提供更加强有力,简洁的数据绑定和命令. 0 绑定通知 WPF的绑定通 ...

  6. 关于k12领域Lucene.net+pangu搜索引擎设计开发的一些回顾

    在中国最大的教育资源门户网站两年期间, 黄药师负责学科网搜吧的设计与开发…正好赶上了公司飞速发展的阶段.. 作为专注于k12领域内容与服务的互联网公司的一员,同时整个公司又在积极提升用户体验的氛围中, ...

  7. opentsdb探索之路——部分设计与实现

    opentsdb 概览(overview) opentsdb 存储细节(Writing) rowkey的设计 rowkey的具体实现 压缩(compaction) 追加模式(appends) open ...

  8. Spring Cache 缺陷,我好像有解决方案了

    Spring Cache 缺陷 Spring Cache 是一个非常优秀的缓存组件. 但是在使用 Spring Cache 的过程当中,小黑同学也遇到了一些痛点. 比如,现在有一个需求:通过多个 us ...

  9. Blazor入门笔记(1)-从0构建一个组件

    1.环境 VS2019 16.5.1 .NET Core SDK 3.1.200 Blazor WebAssembly Templates 3.2.0-preview2.20160.5 2.创建项目 ...

  10. P1343 地震逃生(最大流板题)

    P1343 地震逃生 题目描述 汶川地震发生时,四川**中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边.1号点为教室,n号点为安全地带, ...