DICOM:Docker实现增量发布之前期准备

原创 2016年07月24日 00:40:51

背景:

为了方便整体产品的发布,希望通过docker实现增量发布。大致的思路如下:
is-there-a-way-to-add-only-changed-files-to-a-docker-image-as-a-new-layer-with。本博文对这种方式进行了尝试,与此同时简单介绍如何通过Dockerfile来创建Docker镜像。

前期准备:

  1. 解决centos的网络问题【can not find a valid baseurl for repo: base/7/x86_64】,使用dhclient命令
    http://stackoverflow.com/questions/30424860/yum-error-centos-7-1-x86-64
  2. 解决下载docker官方镜像问题【Docker - dial tcp: lookup index.docker.io: no such host - Solution】,解决方案:https://linuxconfig.org/docker-dial-tcp-lookup-index-docker-io-no-such-host-fix
    这里写图片描述
  3. centos命令行中解析json串。【How to parse JSON string via command line on Linux】,使用一个开源库,详情参考:http://xmodulo.com/how-to-parse-json-string-via-command-line-on-linux.html
    【备注】:建议在windows下先下载jq库,然后再使用pscp等工具上传到linux中,我在多款linux系统下尝试使用wget直接下载,速度卡的要死。

docker镜像和容器再学习:

1. docker image

官方的解释
- 镜像:An image is a filesystem and parameters to use at runtime. It doesn’t have state and never changes.
- 容器:A container is a running instance of an image.
- 引擎:When you ran the command, Docker Engine:
(1)checked to see if you had the hello-world software image;
(2)downloaded the image from the Docker Hub (more about the hub later);
(3)loaded the image into the container and “ran” it

我们之所以使用docker,就如同他的logo中的集装箱一样:通过docker镜像来创建和分发软件,即

Docker Engine lets people (or companies) create and share software through Docker images. Using Docker Engine, you don’t have to worry about whether your computer can run the software in a Docker image — a Docker container can always run it.

2. docker image 在本地


之前博文中专门介绍过通过Docker来发布C-STORE服务Docker实现DICOM服务虚拟化,以及详细介绍过Docker的数据卷其实当我们安装完Docker服务后(Docker主要包括Server、Engine、Client三大模块,后续博文会详细介绍),会跟其他软件一样,在本地生成很多目录结构,对于AUFS文件系统的本地结构可以仔细阅读博文Where are Docker images stored?,但是由于AUFS一直没有纳入Linux内核,所以Docker会支持多种文件系统,我本地centos系统支持的是devicemapper文件系统,该文件系统在本地的存储结构如下(详细介绍可以阅读博文 Docker Supported Filesystems):
这里写图片描述

这里写图片描述

这里写图片描述
这里就不详细介绍每个目录、每个文件的含义了,后续有时间再补充。

Dockerfile创建docker镜像


docekr可以通过读取Dockerfile中的指令来自动创建镜像。下面简单介绍一下如何使用Dockerfile创建自己的镜像(关于Dockerfile的详细说明,参见官方文档Dockerfile Reference
本地的目录存档结构如下(【备注】:在本地如何有规律的归档各类文件是一种良好的习惯,提高效率的同时能够减少错误的发生,建议大家形成自己的习惯):
这里写图片描述
其中addfiles文件夹下存档的是一组dcm医学图像,用于测试后续Dockerfile中的ADD指令;copyfiles文件夹下存档的是一组放疗dicom-rt数据,用于测试后续Dockerfile中的COPY指令。详情见下文对应章节。

1. FROM指令


FROM指令是所有Dockerfile的第一条,目的是设置基础镜像来源,可以是远程仓库也可以是本地。FROM指令有三种格式,如下:

FROM <image> #只给出基础镜像名称
FROM <image>:<tag>#给出制定的tag标签
FROM <image>@<digest>

如果镜像在本地存在会优先使用本地镜像,如果不存在需要从官方仓库中pull下来。
我本地已经将centos:latest最新镜像拉了下来,所以对Dockerfile的build会很迅速,我本地的Dockerfile内容如下:

FROM centos #默认tag=latest,即我本地的centos镜像
MAINTAINER zssure@linkingmed.com

运行过程如下:
这里写图片描述
此时docker images查看本地镜像,结果如下:
这里写图片描述

2. ADD指令

有些时候使用docker来发布服务或软件时,需要将本地的项目拷贝到docker镜像中,ADD指令就是完成这个工作的。
例如我本地的目录结构如下
这里写图片描述
现在希望将上文提到的addfiles目录下的医学影像文件拷贝到镜像中,新的Dockerfile如下:
这里写图片描述
在Dockerfile当前目录运行,竟然出现了错误:Forbidden path outside of the build context: ../addfiles ()
这里写图片描述
出现该错误的原因是因为跟docker的build context有关,上述docker build指令会将路径作为build context,然而../addfiles并不包含在上述build context之内。所以两种解决方案:
1. 将addfiles目录拷贝到Dockerfile所在的目录
2. 返回到上一级运行docker build,(详情参考How to include files outside of Docker’s build context?
具体结果如下:
这里写图片描述
【备注】:注意此时需要修改之前的Dockerfile,将ADD ../addfiles /root/addfiles指令改成ADD ./addfiles /root/addfiles
此刻可以看到本地多了一个镜像:
这里写图片描述
虽然从上图镜像的大小我们可以推断出结果应该是成功的,但是还是使用docker run命令行启动一个容器进入该镜像确认一下是否已经将addfiles添加成功:
这里写图片描述
由上图所示已经成功。

3. COPY指令

COPY指令与ADD指令类似,同样可以将本地文件拷贝到镜像内,目前我了解的唯一区别是ADD可以添加src为URL的源数据到镜像,而COPY只能是本地数据。
本地运行测试结果如下:
这里写图片描述
同样进入到容器内部查看一下:
这里写图片描述
结果完全正确。

具体示例:


这里节选一个博文 《Getting Started with Docker: Simplifying Devops》中的示例,大家可以去原文浏览详情。
博文中用示例给出使用docker发布web服务的大致流程如下:
1. 本地编写服务代码

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class PingPong {

    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
        server.createContext("/ping", new MyHandler());
        server.setExecutor(null);
        server.start();
    }

    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            String response = "pong\n";
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

2. 使用Dockerfile创建docker镜像
Dockerfile内容如下:

FROM java:8
COPY PingPong.java /
RUN javac PingPong.java
EXPOSE 8080
ENTRYPOINT ["java"]
CMD ["PingPong"]

使用Dockerfile创建镜像指令如下:

docker build -t toptal/pingpong .

3. 启动发布的服务

docker run -d -p 8080:8080 toptal/pingpong

4. 测试服务运行

curl http://localhost:8080/ping

总结:

博文在给出上述真实示例之前,详细介绍了Dockfile中的ADD和COPY指令,因为这两个是使用docker来发布应用中必要的关键步骤。
从ADD和COPY两次创建本地镜像的实际运行状态中可以看出,使用Dockerfile构建新的镜像与我们手动启动容器,运行相关指令,再commit容器到镜像是一样的。如下图所示:
这里写图片描述
这说明Dcokerfile中的上述指令MAINTAINER、ADD、COPY都会在基础影像Base Image(即FROM指向)之上创先新的layer并commit提交为新的镜像文件,使得修改固化存储在本地。即每次发布服务时,通过更新Dockerfile文件,将本地有所变动的文件通过ADD(或者COPY)指令添加到新的layer层并生成新的镜像,从而实现自动化&增量发布的目的。






作者:zssure@163.com
时间:2016-07-24

版权声明:本文为zssure原创文章,转载请注明出处,未经允许不得转载。

Docker 使用总结

从贴出Docker 资料汇总那篇水帖, 到现在已经完整的做过一个用Docker部署的小型website集群并且已经上线运行了。 对docker的使用也有了些许体会(不过现在对Docker的理解还停留在...
  • liukun321
  • liukun321
  • 2016年03月01日 10:11
  • 7397

使用Dockerfile创建docker镜像

使用Dockerfile创建docker镜像
  • rznice
  • rznice
  • 2016年08月15日 15:28
  • 21086

Android应用增量更新库(Smart App Updates)

 介绍 你所看到的,是一个用于Android应用程序增量更新的开源库。 包括客户端、服务端两部分代码。 原理 自从 Android 4.1 开始,Google引入了应用程序的增量更新...
  • rznice
  • rznice
  • 2014年12月10日 09:43
  • 2325

es增量自定义更新的脚本

es增量自定义更新的脚本
  • ggz631047367
  • ggz631047367
  • 2016年01月01日 20:29
  • 1607

使用Dockerfile创建docker镜像

语法 FROM     FROM指定一个基础镜像, 一般情况下一个可用的 Dockerfile一定是 FROM 为第一个指令。至于image则可以是任何合理存在的image镜像。     FROM 一...
  • zhugewendu
  • zhugewendu
  • 2017年06月19日 17:13
  • 423

快速发布 docker 应用之神器 - docker Maven

在开发集群应用或微服务架构应用(云原生 cloud native app)时需要启动多个应用服务容器,每次构建新的容器镜像比较麻烦,也不利于调试,使用 docker Maven 镜像就是最佳开发实践之...
  • pmlpml
  • pmlpml
  • 2016年12月14日 11:50
  • 510

Hive中实现增量更新

保险公司有一个表记录客户的信息,其中包括有客户的id,name和age(为了演示只列出这几个字段)。 创建Hive的表: create table customer ( id int, age tin...
  • jiangshouzhuang
  • jiangshouzhuang
  • 2015年06月22日 22:18
  • 4023

Docker之镜像

Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会尝试先从默认镜像仓库下载,用户也可以通过配置,使用自定义的镜像仓库。获取镜像镜像是Docker运行容器的前提。 可以使...
  • zhujun_xiaoxin
  • zhujun_xiaoxin
  • 2017年09月06日 14:38
  • 107

深刻理解Docker镜像大小

都说容器大法好,但是如果没有Docker镜像,Docker该是多无趣啊。 是否还记得第一个接触Docker的时候,你从Docker Hub下拉的那个镜像呢?在那个处女镜像的基础上,你运行了容器生涯的...
  • shlazww
  • shlazww
  • 2015年08月09日 22:45
  • 7902

【Docker江湖】之docker部署与理解

转载请注明出处:http://blog.csdn.net/gamer_gyt 博主微博:http://weibo.com/234654758 Github:https://github.com...
  • Gamer_gyt
  • Gamer_gyt
  • 2016年10月12日 00:10
  • 7440
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DICOM:Docker实现增量发布之前期准备
举报原因:
原因补充:

(最多只允许输入30个字)