Jib使用

Environment

  • Jib 0.9.10
  • Jdk1.8

Foreward

  • What

    针对Java构建容器镜像.提供以maven插件和gradle插件的方式快速构建镜像.

    特点:1、快速;2、不依赖docker命令,不需要写Dockerfile;3、同docker一样采用分层构建;

    缺点:1、不能指定volume挂载;2、一些java启动命令不能使用,如java -jar **.jar –spring.profiles.active=prod …

Feature

  • Simple

    原来构建步骤

img

现在构建步骤

img

开发人员无需了解Dockerfile的细节,通过jib上传镜像.
  • Fast

    为什么会快呢?学习了docker的层概念,增量构建.传统构建是将jar包打入镜像,而jib的策略的将依赖的class文件上传.

  • 不依赖于docker

    构建过程完成不依赖于本地是否有安装docker.

  • 缺点

    不能通过jib指定volume,只能提前将volume构建在镜像中.

Usage

配置详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<build>
<plugins>
<plugin>
<!-- 依赖包 -->
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>0.9.11</version>
<!-- 将jib:build的命令绑定到maven的生命周期中.
原来执行打包方式为mvn compile jib:build,现在只要执行mvn package -->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 镜像拉取配置. -->
<from>
<!-- 镜像地址. -->
<image></image>
<!-- 用户名/密码安全加密,可以不配置.使用auth -->
<credHelper>none</credHelper>
<auth>
<username>私仓用户名</username>
<password>私仓密码</password>
</auth>
</from>
<!-- 镜像上传配置. -->
<to>
<!-- 镜像地址. -->
<image></image>
<credHelper>none</credHelper>
<auth>
<username>私仓用户名</username>
<password>私仓密码</password>
</auth>
</to>
<!-- 默认值为false,用于gradle的缓存设置. -->
<useOnlyProjectCache>false</useOnlyProjectCache>
<!-- 默认值为false,是否开启HTTPS的认证.(推荐为false) -->
<allowInsecureRegistries>false</allowInsecureRegistries>
<!-- Copies files from 'src/main/custom-extra-dir' instead of 'src/main/jib'
用于将其他文件添加到镜像中.-->
<extraDirectory>${project.basedir}/src/main/custom-extra-dir</extraDirectory>
<container>
<mainClass>com.bsd.proxy.monitor.MonitorApplication</mainClass>
<!-- JVM相关参数. -->
<jvmFlags>
<jvmFlag>-Xms512m</jvmFlag>
<jvmFlag>-Xmx512m</jvmFlag>
</jvmFlags>
<!-- 暴露端口.同docker一样.也可以配置端口范围. -->
<ports>
<port>9999</port>
<port>2000-2003/udp</port>
</ports>
<!-- 生成的Dockerfile中CMD的参数. -->
<args>
<arg>some</arg>
<arg>args</arg>
</args>
<!-- 同docker的labels. -->
<labels>
<key1>value1</key1>
</labels>
<!-- 构建容器镜像类型.还支持OCI -->
<format>docker</format>
<!-- 默认值为false,指在打包镜像是是否带时间戳.-->
<useCurrentTimestamp></useCurrentTimestamp>
<!-- (不建议使用)容器启动命令,同docker中的ENTRYPOINT,如果指定了则jvmFlags和mainClass失效.-->
<entrypoint></entrypoint>
</container>
</configuration>
</plugin>
</plugins>
</build>

常用命令

打包应用镜像并上传

不依赖本地docker
1
2
3
4
5
$ mvn compile com.google.cloud.tools:jib-maven-plugin:0.9.11:build -Dimage=<MY IMAGE>
# 或者
$ mvn compile jib:build
# 指定上传镜像超时时间(毫秒).默认是20000毫秒.或者设置0为没有超时时间.
$ mvn compile jib:build -Djib.httpTimeout=3000
依赖本地docker
1
2
3
$ mvn compile com.google.cloud.tools:jib-maven-plugin:0.9.10:dockerBuild
# 或者
$ mvn compile jib:dockerBuild

镜像打成tar包

1
2
3
4
# 会在项目路径的target目录下生成jib-image.tar.
$ mvn compile jib:buildTar
# 通过docker导入镜像.
$ docker load --input target/jib-image.tar

导出镜像的Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
# 默认生成在target/jib-docker-context下.-DjibTargetDir用于指定生成路径.
$ mvn compile jib:exportDockerContext -DjibTargetDir=my/docker/context/
# 下面是我pom中的配置,并生成的一个Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/jiuming/java-alpine-openjdk8-jre-shanghai

COPY libs /app/libs/
COPY resources /app/resources/
COPY classes /app/classes/

EXPOSE 9999
ENTRYPOINT ["java","-Xms512m, -Xmx512m", -cp","/app/resources/:/app/classes/:/app/libs/*","com.bsd.proxy.monitor.MonitorApplication"]
CMD []

配置私仓身份认证

如果没有使用credHelper,

通过Docker Credential Helps

待补充,Docker Credential Helps

通过Maven配置

配置Setting.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
<settings>
...
<servers>
...
<server>
<!-- id为仓库名称 -->
<id>MY_REGISTRY</id>
<username>MY_USERNAME</username>
<!-- maven encryption -->
<password>{MY_SECRET}</password>
</server>
</servers>
</settings>

Example

  • 目标描述

    使用spring boot构建一个java应用程序镜像,并指定profile运行.

为了能够指定profile运行,main启动代码要改动.

平常启动应用的命令是:

1
java -jar -Xms512m -Xmx512m **.jar --spring.profiles.active=prod

Jib打成的镜像,ENTRYPOINT实际的启动命令是:

1
java -Xms512m -Xmx512m -cp app/libs/*:app/resources:app/classes package.MonitorApplication

为了能够指定profile运行,需要在docker启动添加参数.

1
2
3
4
5
6
7
8
9
10
11
12
13
@SpringBootApplication
public class MonitorApplication {

private final static String ACTIVE = "prod";

public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder(MonitorApplication.class);
if (Arrays.stream(args).anyMatch(t -> t.equals(ACTIVE))) {
builder.profiles(ACTIVE);
}
builder.run(args);
}
}

配置pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

......
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>0.9.10</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<from>
<image>指定拉取镜像的私仓地址</image>
<auth>
<username>私仓用户名</username>
<password>私仓密码</password>
</auth>
</from>
<to>
<image>指定推送镜像的私仓地址</image>
<auth>
<username>指定推送镜像的私仓地址</username>
<password>私仓密码</password>
</auth>
</to>
<container>
<!-- 指定MonitorApplication的全路径. -->
<mainClass>mypackage.MonitorApplication</mainClass>
<jvmFlags>
<jvmFlag>-Xms512m</jvmFlag>
<jvmFlag>-Xmx512m</jvmFlag>
</jvmFlags>
<ports>
<port>9999</port>
</ports>
<!-- 这里用于配置默认执行的profile,可以不用配置,在docker启动命令中配置 -->
<!--args>
<arg>prod</arg>
</args-->
</container>
</configuration>
</plugin>
</plugins>
</build>
<profile>

构建并上传images

1
$ mvn package

启动容器

1
2
$ docker pull [镜像名称]
$ docker run -ti --network host --name [容器名称] -v /store/logs:/store/logs -p 9999:9999 -d [镜像名称] [指定profile]

结合Ansible Scripts

配置ansible脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ mkdir -p /opt/ansible-biz/roles/monitor/tasks
$ cd /opt/ansible-biz
$ vim site.yml
- name: deploy proxy
hosts: all
gather_facts: false
roles:
- {role: monitor, tags: "monitor"}
$ vim hosts
[product]
xxyp-dev ansible_host=192.168.1.222 ansible_port=22
$ vim /opt/ansible-biz/roles/monitor/tasks/main.yml
- pip:
name: docker-py
state: present
- name: Pull monitor image
docker_image:
name: registry.cn-hangzhou.aliyuncs.com/yuanshi/monitor
tag: v1.0.0
force: yes
- name: Restart monitor container
docker_container:
name: operation
image: registry.cn-hangzhou.aliyuncs.com/yuanshi/monitor:v1.0.0
network_mode: host
volumes:
- /store/logs:/store/logs
exposed_ports:
- 9082
recreate: yes
command: "{{ profile }}"
# env:
# zooCluster="{{ zooCluster }}"
restart_policy: always
state: started

启动

$ ansible-playbook -i hosts -e profile=prod sity.yml

Expend Study

使用alpine镜像或distroless镜像作为基础构建镜像.

Reference Resources

坚持原创技术分享,您的支持将鼓励我继续创作!
Fork me on GitHub