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. AJAX中的dataType

    参考ajax的api文档 dataType的类型:String ajax中的dataType的属性: text:返回纯文本字符串 json:返回json数据 jsonp:jsonp格式(我没用过) h ...

  2. webpack学习_webpack-dev-server自动编译代码

    之前每次修改完之后都要执行npm run build来编译,下面有三种方式可以实现代码变化后自动编译代码,下面只重点说webpack-dev-server,其他的请看webpack开发文档 1.web ...

  3. 6. abp中的拦截器

    abp拦截器基本定义 拦截器接口定义: public interface IAbpInterceptor { void Intercept(IAbpMethodInvocation invocatio ...

  4. Dubbo环境搭建-管理控制台dubbo-admin实现服务监控

    场景 Dubbo环境搭建-ZooKeeper注册中心: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103555470 在上面搭 ...

  5. 松软科技Web课堂:JavaScript While 循环

    只要条件为 true,循环能够一直执行代码块. While 循环 while 循环会一直循环代码块,只要指定的条件为 true. 语法 while (条件) { 要执行的代码块 } 实例 在下面的例子 ...

  6. iOS开发集成支付宝支付、支付宝&微信支付

    支付宝支付: 参考链接:https://www.jianshu.com/p/60175e525c0e https://blog.csdn.net/zhonggaorong/article/detail ...

  7. centos7安装python3.7.4

    yum install gcc make zlib  zlib-devel openssl openssl-devel libffi-devel bzip2-devel ncurses-devel g ...

  8. utf8和utf8mb4的区别

    一.简介 MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode.好在utf8mb4是utf8的超集,除了将编码改为ut ...

  9. Leetcode题解 - 双指针求n数之和

    1. 两数之和 """ 双指针,题目需要返回下标,所以记录一个数字对应的下标 """ class Solution: def twoSum( ...

  10. CSS transition 的默认值

    语法 transition: property duration timing-function delay|initial|inherit; 示例: div {   width: 100px;    ...