Docker for Java Developers

1.  基本概念java

1.1.  主要组件git

Docker有三个主要组件:github

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

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

1.2.  Docker Image正则表达式

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

Docker如此轻量级的缘由之一就是这些层(图层)。当你修改镜像(例如,将应用程序更新到新版本)时,将构建一个新的层。所以,只添加或更新该层,而不是像使用虚拟机那样替换整个映像或彻底重建。如今,您不须要发布整个新图像,只须要更新便可,从而使分发Docker镜像更快、更简单。(PS:愈加以为此处用“图像”更好理解,加个新图层或者在原先的图层上作修改便可)docker

每一个镜像都是从一个基本镜像开始的。你也可使用本身的镜像做为新镜像的基础。若是你有一个基本的Apache镜像,那么你可使用它做为全部web应用程序镜像的基础。shell

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

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

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

(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 

相关文章
相关标签/搜索