容器的基本概念

什么是容器?

容器就是一个视图隔离、资源可限制、独立文件系统的进程集合。所谓“视图隔离”就是能够看到部分进程以及具有独立的主机名等;控制资源使用率则是可以对于内存大小以及 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. 非常诡异的IIS下由配置文件加上svg的mime头导致整个网站的静态文件访问报错误

    调试了两天遇到一个非常诡异的问题 一个系统稳定运行了很多年,是用mvc5+WIN2008R2  + .NET 4.5 +IIS环境下运行,非常稳定,最近想迁移到一台新的服务器,为了少麻烦在阿里云上买了 ...

  2. python文件封装成*.exe

    python文件封装成*.exe文件(单文件和多文件) 环境:win10 64位 python3.7 原文: https://www.cnblogs.com/jackzz/p/9431923.html ...

  3. sql MariaDB 安装contos

    安装和运行MySQL数据库(MariaDB) centos 平台 1.安装和运行 yum install mariadb mariadb-server - 安装 systemctl start mar ...

  4. SVN同步代码问题集锦

    1.删除文件后file missing警告                      相关链接: http://blog.sina.com.cn/s/blog_63e26d560100ve00.htm ...

  5. Java并发基础05. 传统线程同步通信技术

    先看一个问题: 有两个线程,子线程先执行10次,然后主线程执行5次,然后再切换到子线程执行10,再主线程执行5次--如此往返执行50次. 看完这个问题,很明显要用到线程间的通信了, 先分析一下思路:首 ...

  6. MySQL服务使用cmd启动与停止服务

    MySQL未设置自动启动,在使用时需要手动打开服务,方法如下 mysql服务的启动: 以管理员的身份运行cmd命令窗口,输入命名 net start mysql 提示:必须使用管理员身份运行cmd 如 ...

  7. c语言 0与非0

    ------------恢复内容开始------------ 结论: 其它的编程语言中有布尔数据类型,并用百来表示逻辑真和逻辑假,C语言没有这个内置类度型,在C语言中真和假是用整型值来表示知的,0就表 ...

  8. Kubernetes Pod钩子

    目录 1.Pod容器钩子最终目的 2.何为Pod容器钩子 3.基于PostStart演示 4.基于PreStop演示 5.优雅停止Java应用 1.Pod容器钩子最终目的 之前在生产环境中使用dubb ...

  9. 家庭版记账本app开发进度相关界面的规划

    总的app界面包括四个页面,页面可以来回滑动.设计的时候就和微信的四个页面类似. 由于没有找到合适的图标进行替换,在此仍应用微信对应的四个图标. 总的四个页面是: 1.增加收入或者支出的小账单.当点击 ...

  10. 开学java的初步考试

    //第一个.java文件 package project1; //20183777 温学智 信1805-2 public class ScoreInformation { private String ...