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. 深入探索Java设计模式(四)之享元模式

    享元模式适用于需要大量相同类型对象的情况.在此,设计布局可以减少创建多个对象的方式.对象在运行时会消耗资源,因此最好在内存中使用较少的对象.它减少了内存占用并利用了程序的整体性能.本文是在学习完优锐课 ...

  2. 《MySQL数据库》MySQL数据库安装(windows)

    MySQL安装包和操作工具 链接: https://pan.baidu.com/s/1BTfrHwVR1uNBuB_E27N55g 提取码: dhbv 1.首先解压文件包,我这解压到E:\instal ...

  3. ubuntu14.04编译vim8.1

    安装依赖 这一步其实我没做,直接下载编译成功了.估计有些包不是必需的.姑且列在这里供参考 sudo apt install libncurses5-dev libgnome2-dev libgnome ...

  4. 重构 JAVA 聊天室 —— CS 模式的简单架构实现

    前言 自从开始弄起数据挖掘之后,已经很久没写过技术类的博客了,最近学校 JAVA 课设要求实现一个聊天室,想想去年自己已经写了一个了,但是有些要求到的功能我也没实现,但看着原有的代码想了想加功能好像有 ...

  5. 在CentOS 7 上使用Docker 运行.NetCore项目

    安装Docker CentOS 7 安装 Docker 编写Dockerfile 右键项目->添加->Docker 支持 选择Linux 修改为如下: FROM mcr.microsoft ...

  6. ios学习之路:Xcode+swift+打包ipa一步一坑记录

    咳咳,作为公司的Android开发(兼java接口开发,兼软件测试,兼运维……)由于公司ios开发小伙伴离我而去,ios的app出了问题,急需处理.于是领导决定由我来处理一下.就是用证书重新打包的事儿 ...

  7. Springboot整合redis步骤

    一.加入依赖 <dependency> <groupId>com.github.spt-oss</groupId> <artifactId>spring ...

  8. vue项目 npm run dev在Linux 持久运行

    touch run.dev.logchmod u+w run.dev.log 记录日志文件 nohup npm run dev > run.dev.log 2>run.dev.log &a ...

  9. Android odex,oat文件的反编译,回编译

    现在,许多Android手机的ROM包在生成过程中都启用优化,把jar文件抽空,生成odex/oat和vdex文件,以在运行时省掉编译时间.如果想对这些jar进行修改,就要修改它们所对应的odex或者 ...

  10. React 面试问题

    eact 面试问题 如果你是一位有理想的前端开发人员,并且正在准备面试,那么这篇文章就是为你准备的.本文收集了 React 面试中最常见的 50 大问题,这是一份理想的指南,让你为 React 相关的 ...