1.  基本概念

1.1.  主要组件

Docker有三个主要组件:

  • 镜像是Docker的构建组件,而且是定义应用程序操作系统的只读模板
  • 容器是Docker的运行组件,它是从镜像创建的。容器可以运行、启动、停止、移动和删除
  • 镜像在注册中心中存储、共享和管理,并且是Docker的分发组件。Docker Store 是一个公开可用的注册中心。https://hub.docker.com/

为了上这三个组件协同工作,Docker守护进程(或者叫Docker容器)运行在一个主机上,并负责构建、运行和分发Docker容器。此外,客户端是一个Docker二进制文件,它接受来自用户的命令并与引擎来回通信。

1.2.  Docker Image

Docker镜像是一个可以从其中启动Docker容器的只读模板。每个镜像又一系列的层组成。(PS:现在发现,把“Image”翻译成专业术语“镜像”的话这里就感觉跟别扭。原文是“Each image consists of a series of layers”,如果按“Image”本来的意思“图像”去理解就很好理解了,对PhotoShop有点儿了解的人都能理解这句话,“图像由一系列图层组成”,真是太形象了。)

Docker如此轻量级的原因之一就是这些层(图层)。当你修改镜像(例如,将应用程序更新到新版本)时,将构建一个新的层。因此,只添加或更新该层,而不是像使用虚拟机那样替换整个映像或完全重建。现在,您不需要发布整个新图像,只需要更新即可,从而使分发Docker镜像更快、更简单。(PS:越发觉得此处用“图像”更好理解,加个新图层或者在原先的图层上做修改即可)

每个镜像都是从一个基本镜像开始的。你也可以使用自己的镜像作为新镜像的基础。如果你有一个基本的Apache镜像,那么你可以使用它作为所有web应用程序镜像的基础。

Docker使用一组称为指令的简单描述性步骤来构建镜像。每条指令在镜像中创建一个新层。

  1. 运行一条命令
  2. 添加一个文件或目录
  3. 创建一个环境变量
  4. 当启动一个容器时运行一个进程

这些指令被存储在一个叫“Dockerfile”的文件中。当你请求构建镜像时,Docker读取这个Dockerfile文件,然后执行这些指令,并返回最终的镜像。

(PS:关于镜像,记住下面两句话

  • Each image consists of a series of layers.
  • Each instruction creates a new layer in our image. 

1.3.  Docker Container

容器由操作系统、用户添加的文件和元数据组成。正如我们所看到的,每个容器都是由一个镜像构建的。镜像告诉Docker容器持有什么、启动容器时运行什么进程以及各种其他配置数据。镜像是只读的。当Docker从映像运行容器时,它会在镜像之上添加一个读写层,然后你的应用程序就可以在其中运行了。

1.4.  Docker Engine

Docker Host是在安装Docker的时候创建的。一旦Docker Host被创建了,那么你就可以管理镜像和容器了。例如,你可以下载镜像、启动或停止容器。

1.5.  Docker Client

Docker Client与Docker Host通信,进而你就可以操作镜像和容器了。

2.  构建一个镜像

2.1.  Dockerfile

Docker通过从Dockerfile文件中读取指令来构建镜像。Dockerfile是一个文本文档,它包含用户可以在命令行上调用的所有命令来组装一个镜像。docker image build命令会使用这个文件,并执行其中的所有命令。

build命令还传递一个在创建映像期间使用的上下文。这个上下文可以是本地文件系统上的路径,也可以是Git存储库的URL。

关于Dockerfile中可以使用的命令,详见 https://docs.docker.com/engine/reference/builder/

下面是一些常用的命令:

2.2.  创建你的第一个镜像

首先,创建一个目录hellodocker,然后在此目录下创建一个名为Dockerfile的文本文件,编辑该文件,内容如下:

从以上两行命令我们可以看到,该镜像是以ubuntu作为基础基础,CMD命令定义了需要运行的命令。它提供了一个不同的入口/bin/echo,并给出了一个参数“hello world”。

2.3.  用Java创建你的第一个镜像

补充:OpenJDK是Java平台标准版的一个开源实现,是Docker官方提供的镜像

首先,让我们创建一个java工程,然后打个jar包,接着创建并编辑Dockerfile

使用docker image build构建镜像

使用docker container run启动容器

其实,跟我们平常那一套没多大区别,不过是把打好的jar包做成镜像而已

2.4.  使用Docker Maven Plugin构建镜像

利用Docker Maven Plugin插件我们可以使用Maven来管理Docker镜像和容器。下面是一些预定义的目标:

详见 https://github.com/fabric8io/docker-maven-plugin

补充:Maven中的生命周期、阶段、目标

  1. 生命周期有三套:clean、default、site
  2. 生命周期由多个阶段组成的,比如default生命周期的阶段包括:clean、validate、compile、
  3. 每个阶段由多个目标组成,也就是说目标才是定义具体行为的
  4. 插件是目标的具体实现

稍微留一下IDEA里面的Maven区域就不难理解了

言归正传,利用docker-maven-plugin来构建镜像的方式有很多,比如,可以配置插件或属性文件,还可以结合Dockerfile,都在这里:

https://github.com/fabric8io/docker-maven-plugin/tree/master/samples

此处,我们演示用属性文件的方式,首先,定义一段profile配置,比如这样:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <parent>
6 <groupId>org.springframework.boot</groupId>
7 <artifactId>spring-boot-starter-parent</artifactId>
8 <version>2.1.4.RELEASE</version>
9 <relativePath/> <!-- lookup parent from repository -->
10 </parent>
11 <groupId>com.cjs.example</groupId>
12 <artifactId>hello-demo</artifactId>
13 <version>0.0.1-SNAPSHOT</version>
14 <name>hello-demo</name>
15 <description>Demo project for Spring Boot</description>
16
17 <properties>
18 <java.version>1.8</java.version>
19 </properties>
20
21 <dependencies>
22 <dependency>
23 <groupId>org.springframework.boot</groupId>
24 <artifactId>spring-boot-starter-web</artifactId>
25 </dependency>
26
27 <dependency>
28 <groupId>org.springframework.boot</groupId>
29 <artifactId>spring-boot-starter-test</artifactId>
30 <scope>test</scope>
31 </dependency>
32 </dependencies>
33
34 <build>
35 <plugins>
36 <plugin>
37 <groupId>org.springframework.boot</groupId>
38 <artifactId>spring-boot-maven-plugin</artifactId>
39 </plugin>
40 </plugins>
41 </build>
42
43 <profiles>
44 <profile>
45 <id>docker</id>
46 <build>
47 <plugins>
48 <plugin>
49 <groupId>io.fabric8</groupId>
50 <artifactId>docker-maven-plugin</artifactId>
51 <version>0.30.0</version>
52 <configuration>
53 <images>
54 <image>
55 <name>hellodemo</name>
56 <build>
57 <from>openjdk:latest</from>
58 <assembly>
59 <descriptorRef>artifact</descriptorRef>
60 </assembly>
61 <cmd>java -jar maven/${project.name}-${project.version}.jar</cmd>
62 </build>
63 </image>
64 </images>
65 </configuration>
66 <executions>
67 <execution>
68 <id>docker:build</id>
69 <phase>package</phase>
70 <goals>
71 <goal>build</goal>
72 </goals>
73 </execution>
74 <execution>
75 <id>docker:start</id>
76 <phase>install</phase>
77 <goals>
78 <goal>run</goal>
79 <goal>logs</goal>
80 </goals>
81 </execution>
82 </executions>
83 </plugin>
84 </plugins>
85 </build>
86 </profile>
87 </profiles>
88 </project> 

然后,在构建的时候指定使用docker这个profile即可

1 mvn clean package -Pdocker

2.5.  Dockerfile命令(番外篇)

CMD 与 ENTRYPOINT 的区别

容器默认的入口点是 /bin/sh,这是默认的shell。

当你运行 docker container run -it ubuntu 的时候,启动的是默认shell。

ENTRYPOINT 允许你覆盖默认的入口点。例如:

这里默认的入口点被换成了/bin/cat

ADD 与 COPY 的区别

ADD有COPY所有的能力,而且还有一些额外的特性:

  1. 允许在镜像中自动提取tar文件
  2. 允许从远程URL下载文件

3.  运行一个Docker容器

3.1.  交互

以交互模式运行WildFly容器,如下:

1 docker container run -it jboss/wildfly

默认情况下,Docker在前台运行。-i允许与STDIN交互,-t将TTY附加到进程上。它们可以一起用作 -it

按Ctrl+C停止容器

3.2.  分离容器

1 docker container run -d jboss/wildfly

用-d选项代替-it,这样容器就以分离模式运行

(PS:-it前台运行,-d后台运行)

3.3.  用默认端口

如果你想要容器接受输入连接,则需要在调用docker run时提供特殊选项。

1 $ docker container ls
2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3 93712e8e5233 jboss/wildfly "/opt/jboss/wildfly/…" 4 minutes ago Up 4 minutes 8080/tcp serene_margulis
4 02aa2ed22725 ubuntu "/bin/bash" 2 hours ago Up 2 hours frosty_bhabha 

重启容器

1 docker container stop `docker container ps | grep wildfly | awk '{print $1}'`
2 docker container run -d -P --name wildfly jboss/wildfly

-P选项将镜像中的任何公开端口映射到Docker主机上的随机端口。--name选项给这个容器起个名字。

1 $ docker container ls
2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3 3f2babcc1df7 jboss/wildfly "/opt/jboss/wildfly/…" 47 seconds ago Up 47 seconds 0.0.0.0:32768->8080/tcp wildfly

3.4.  用指定端口

1 docker container stop wildfly
2 docker container rm wildfly 

或者你还可以用 docker container rm -f wildfly 来停止并删除容器

1 docker container run -d -p 8080:8080 --name wildfly jboss/wildfly

格式是: -p hostPort:containerPort

此选项将主机上的端口映射到容器中的端口。这样就使得我们可以通过主机上的特定的端口来访问容器。

现在我们访问http://localhost:8080/跟刚才http://localhost:32768/是一样的

3.5.  停止容器

1 # 按id或name停止指定的容器
2 docker container stop <CONTAINER ID>
3 docker container stop <NAME>
4
5 # 停止所有容器
6 docker container stop $(docker container ps -q)
7
8 # 停止已经退出的容器
9 docker container ps -a -f "exited=-1"

3.6.  删除容器

1 # 按id或name删除指定的容器
2 docker container rm <CONTAINER ID>
3 docker container rm <NAME>
4
5 # 用正则表达式删除匹配到的容器
6 docker container ps -a | grep wildfly | awk '{print $1}' | xargs docker container rm
7
8 # 删除所有容器
9 docker container rm $(docker container ps -aq)

3.7.  查看端口映射

1 docker container port <CONTAINER ID> or <NAME>

4.  参考

https://github.com/docker/labs/tree/master/developer-tools/java/

https://github.com/fabric8io/docker-maven-plugin

Docker for Java Developers的更多相关文章

  1. Deployment Pipeline using Docker, Jenkins, Java

    Deployment Pipeline using Docker, Jenkins, Java and Couchbase http://blog.couchbase.com/2016/septemb ...

  2. Watch out for these 10 common pitfalls of experienced Java developers & architects--转

    原文地址:http://zeroturnaround.com/rebellabs/watch-out-for-these-10-common-pitfalls-of-experienced-java- ...

  3. Top 10 Mistakes Java Developers Make--reference

    This list summarizes the top 10 mistakes that Java developers frequently make. #1. Convert Array to ...

  4. 100 high quality blogs from java developers

    This list collects 100 high quality blogs from Java developers from all over the world. Some of thes ...

  5. Yet Another 10 Common Mistakes Java Developers Make When Writing SQL (You Won’t BELIEVE the Last One)--reference

    (Sorry for that click-bait heading. Couldn’t resist ;-) ) We’re on a mission. To teach you SQL. But ...

  6. Top 10 Mistakes Java Developers Make(转)

    文章列出了Java开发者最常犯的是个错误. 1.将数组转换为ArrayList 为了将数组转换为ArrayList,开发者经常会这样做: ? 1 List<String> list = A ...

  7. Top 10 Books For Advanced Level Java Developers

    Java is one of the most popular programming language nowadays. There are plenty of books for beginne ...

  8. Docker最全教程之使用Docker搭建Java开发环境(十七)

    前言 Java是一门面向对象的优秀编程语言,市场占有率极高,但是在容器化实践过程中,发现官方支持并不友好,同时与其他编程语言的基础镜像相比(具体见各语言镜像比较),确实是非常臃肿. 本篇仅作探索,希望 ...

  9. Forget Guava: 5 Google Libraries Java Developers Should Know

    Forget Guava: 5 Google Libraries Java Developers Should Know Published on 2016 7 13 Somenath PandaFo ...

随机推荐

  1. CCF-CSP题解 201709-3 JSON查询

    要求写一个小程序完成JSON查询的功能. 查询dfs就好了. 存储JSON对象用图(树)就好,把\(<key[],type,val[]>\)作为节点,然后又是字符串处理了. 其实就是个简化 ...

  2. 《Java基础知识》Java集合(Map)

    Java集合主要由2大体系构成,分别是Collection体系和Map体系,其中Collection和Map分别是2大体系中的顶层接口. 今天主要讲:Map主要有二个子接口,分别为HashMap.Tr ...

  3. LeetCode 11月第2周题目汇总

    开源地址:点击该链接 前言 最近比较忙,这周几乎没有刷题,只刷了6道题~ 题目汇总 0387_first_unique_character_in_a_string类似的题目比较多了,字符串中找出特别的 ...

  4. C#线程学习笔记七:Task详细用法

    一.Task类简介: Task类是在.NET Framework 4.0中提供的新功能,主要用于异步操作的控制.它比Thread和ThreadPool提供了更为强大的功能,并且更方便使用. Task和 ...

  5. 一起学MyBatis之入门篇

    概述 本文以一个简单的小例子,简述在Java项目开发中MyBatis的基本用法,属于入门级文章,仅供学习分享使用,如有不足之处,还请指正. 什么是MyBatis? MyBatis 是一款优秀的持久层框 ...

  6. [20191213]toad 12下BIND_AWARE提示无效.txt

    [20191213]toad 12下BIND_AWARE提示无效.txt --//链接http://blog.itpub.net/267265/viewspace-2130781/的测试,发现当时测试 ...

  7. Git常用进阶操作之一

    提起Git,经常做项目的我们都不陌生,我们常用的功能有哪些呢? 这里按个人使用情况简单总结一下. 像新建远程仓库.新建分支这些就不说了,不熟的同学可以翻看我前面写的git基本操作. 1.首先提一下为每 ...

  8. 删除列表中重复元素以及求list中元素个数

    Python 去除列表中重复的元素 来自比较容易记忆的是用内置的set l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) print l2 还 ...

  9. js 对象 / json / jsonb / jsonp 区别

    一.JSON vs JS 对象 1.区别 区别 Javascript 对象 Json 含义 对象的实例 一种数据格式(序列化格式) 传输 不能传输 可以跨平台传输,轻量级 格式 1.键不加引号.加单引 ...

  10. 一分钟教你编写Linux全局内置命令

    前言:在linux命令使用中,有些命令总是又长又难记,就算是经常使用的命令每次都敲也真的很烦,所以今天教大家一个方法,来简化命令,创建我们自己的内建命令!!! 创建内置命令 创建命令存储目录 现在li ...