背景

无论是在制作java、python或nodejs的docker镜像的过程中,需要编译源码的话,就得忍受一次次地下载依赖的jar或package, 特别耗时。有没有一种方式能如本地编译打包一样,依赖包下载过一次,就无须多次下载。经同事介绍,得知了s2i技术,它能解决此问题,还带来了别的好处。

说明

s2i是source to image的缩写。简单地说,就是通过镜像生成镜像。github上的地址在这里。下面这个图,能很好地说明它的工作流程。

使用s2i后,就无须再为应用程序制作Dockerfile了,这些都交给s2i搞定即可。只需按s2i的要求,制作一个编译镜像Builder Image, 该镜像会从git仓库拉取应用代码,然后生成应用镜像App Image.应用镜像可运行或发布到Docker私服里。可以针对不同的开发语言,制作不同的Builder Image。如果你的脚本语言功力强大的话,也可制作出一款通用的编译镜像出来:)

s2i常用的命令有这几个:create、generate、build和rebuild。通过create和generate命令可制作自己的编译镜像Builder Image。而build和rebuild用来制作应用镜像。下面分别简单介绍下:

s2i create <image name> <destination directory>

image name是编译镜像的名,destination directory是生成的目录。

s2i create java-builder java-builder[root@master java-builder]# tree
.
├── Dockerfile
├── Makefile
├── README.md
├── s2i
│   └── bin
│       ├── assemble
│       ├── run
│       ├── save-artifacts
│       └── usage
└── test├── run└── test-app└── index.html

通过上述命令就能生成名称为java-builder的编译镜像的制作目录框架来。这个用来编译打包java应用。

  • Dockerfile用来引入所需的工具,比如maven和jdk; 同时按s2i要求至少要有tar和/bin/sh
  • s2i/bin/assemble脚本用来编译源码;
  • s2i/bin/run脚本用来启动运用;
  • s2i/bin/save-artifacts脚本用来保存依赖的package, 以便下次编译用

其他文件用途可去官网查看 。

下面简单介绍下其他命令:

# 可用来生成一个builder image的Dockerfie. 这样可利用已有的builder image定制自己的编译镜像
s2i generate <builder image> <output file># 编译和制作应用镜像
s2i build <source location> <builder image> [<tag>] [flags]
# source location可以是应用的git url和目录
# builder image是编译镜像
# tag 指要生成的应用镜像名
# flags是一些参数,常用的有-c, --incremental# 重新编译应用镜像
s2i rebuild <image name> [<new-tag-name>]
# image name是应用镜像名
# new-tag-name是新的镜像名,不提供,就用原来的

使用

github上提供了一些不错的编译镜像,比如fabric8/s2i-java就是一个不错的java编译镜像。可直接拿来用,亦可参考定制自己的java编译镜像。 它是利用fish-pepper和run-java-sh 这两项技术来做的:

  • fish-pepper可通过json文件组装所需的docker 镜像,要什么,配什么。
  • run-java-sh可用来启动java 应用, 特别适合spring-boot和通过main启动的java应用,它会根据MetaInfo信息自动发现主程序入口,无需手动指定,很方便。

下面分享下我的一些实践。

  1. 制作应用镜像
s2i build /data/temp/s2i/paratera-s2i-jdk8/console-gateway/ fabric8/s2i-java  console-gateway-s2i --incremental
# 我使用目录形式来编译,这里的目录要用绝对路径
# console-gateway-s2i 是应用镜像名
# --incremental这个参数很重要,可避免重复下载依赖包。当然第一次执行,也会下载依赖包,以后再执行,就不用了

下面是执行过程,因为执行过一次,采用–incremental, 就不会再下载依赖包了

==================================================================
Starting S2I Java Build .....
S2I source build for Maven detected
Using MAVEN_OPTS '-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:+ExitOnOutOfMemoryError'
Found pom.xml ...
Running 'mvn -Dmaven.repo.local=/tmp/artifacts/m2 package -DskipTests -Dmaven.javadoc.skip=true -Dmaven.site.skip=true -Dmaven.source.skip=true -Djacoco.skip=true -Dcheckstyle.skip=true -Dfindbugs.skip=true -Dpmd.skip=true -Dfabric8.skip=true -e -B '
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T18:33:14Z)
Maven home: /opt/maven
Java version: 1.8.0_262, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.262.b10-0.el7_8.x86_64/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "5.4.98-1.el7.elrepo.x86_64", arch: "amd64", family: "unix"
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.paratera.console:consoleGateway >-----------------
[INFO] Building consoleGateway 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (enforce-versions) @ consoleGateway ---
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ consoleGateway ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 4 resources
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ consoleGateway ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 10 source files to /tmp/src/target/classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ consoleGateway ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /tmp/src/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ consoleGateway ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /tmp/src/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ consoleGateway ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ consoleGateway ---
[INFO] Building jar: /tmp/src/target/consoleGateway-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.3.4.RELEASE:repackage (repackage) @ consoleGateway ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.713 s
[INFO] Finished at: 2021-04-02T05:30:48Z
[INFO] ------------------------------------------------------------------------
Copying Maven artifacts from /tmp/src/target to /deployments ...
Running: cp -v *.jar /deployments
'consoleGateway-0.0.1-SNAPSHOT.jar' -> '/deployments/consoleGateway-0.0.1-SNAPSHOT.jar'
Checking for fat jar archive...
Found consoleGateway-0.0.1-SNAPSHOT.jar...
... done
Build completed successfully

查看应用镜像

[root@master yml]# docker images | grep gateway
console-gateway-s2i                                              latest              d9edfaffa16e        About a minute ago   650MB

遇到的坑
我的工程是从git仓库里clone来的,然后我修改了配置,但发现打出的应用镜像里却没有我的修改,一直和git仓库里的一样。原来编译时s2i会自动拉取git代码。后来删除了.git目录才行。除了删目录这种方法,还有别的吗?答案是有的,那就是用-c(或–copy)参数,这样s2i就不会从git来取了。如下:

s2i build -c /data/temp/s2i/paratera-s2i-jdk8/console-gateway/ fabric8/s2i-java  console-gateway-s2i --incremental

但是如采用rebuild,还是会拉取。这个还没找到解决方案。用–exclude也不好使。

  1. 运行应用镜像
    运行java应用,需指定一些参数。比如我的是spring boot,需指定运行时的profile. 在docker里可以用如下方式:
# 通过-e 指定
docker run -p 40000:8080 -e spring.profiles.active=prod console-gateway-s2i

下面是启动日志,可以看到run-java-sh启动了运用

Starting the Java application using /opt/run-java/run-java.sh ...
exec java -javaagent:/opt/jolokia/jolokia.jar=config=/opt/jolokia/etc/jolokia.properties -javaagent:/opt/prometheus/jmx_prometheus_javaagent.jar=9779:/opt/prometheus/prometheus-config.yml -Xmx2560m -XX:ParallelGCThreads=1 -XX:ConcGCThreads=1 -Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -XX:CICompilerCount=2 -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:+ExitOnOutOfMemoryError -cp . -jar /deployments/consoleGateway-0.0.1-SNAPSHOT.jar
I> No access restrictor found, access to any MBean is allowed
Jolokia: Agent started with URL http://10.88.1.30:8778/jolokia/.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::        (v2.3.4.RELEASE)2021-04-01 06:06:32.113  INFO 1 --- [           main] c.p.console.gateway.GatewayApplication   : The following profiles are active: prod
2021-04-01 06:06:42.117  INFO 1 --- [           main] c.p.console.gateway.GatewayApplication   : Started GatewayApplication in 14.114 seconds (JVM running for 15.899)

在k8s里可以利用kustomize和configmap来启动。先将应用镜像推送到harbor私服里

# 先定义一个env
[root@master yml]# cat bizGateway/biz-gateway.env
spring.profiles.active=prod# 然后在kustomization.yml里指定env
[root@master yml]# cat bizGateway/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: consoleconfigMapGenerator:
- name: console-biz-gateway-envenvs:- biz-gateway.envresources:- deployment.yaml- service.yaml#接着在deployment.yml里通过envFrom引用envspec:containers:- name: console-biz-gatewayimage: harbor-console.paratera.com:8443/library/console-biz-gatewayenvFrom:- configMapRef:name: console-biz-gateway-env# 最后通过如下方式启动
kustomize build bizGateway | kubectl apply -f -

小结

s2i为云原生的编译发布运用带来了捷径。后续有时间再研究下java里多个项目依赖的应用发布如何实现,估计和maven的多项目依赖编译相关。同时还要看看是否有类似run-python-sh, run-nodejs-sh的功能,这样编译其他语言的应用镜像就方便了。

使用s2i制作docker镜像相关推荐

  1. Java Spring Boot 2.0 实战之制作Docker镜像并推送到Docker Hub和阿里云仓库

    内容摘要:大规模集群快速部署Java应用,需要制作Docker镜像,本次课程详细介绍如何制作Java程序的Docker镜像文件,深入解析DockerFile核心参数,以及实践演练把我们制作的Docke ...

  2. mysql sshd_制作Docker镜像之mysqlkeepalivedsshd

    制作Docker镜像之mysql&keepalived&sshd mysql docker keepalived ssh 注:该实验采用的docker版本:Docker version ...

  3. 制作Docker镜像的两种方式

    此文已由作者朱笑天授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 一.使用docker commit命令制作docker镜像 1. pull一个centos6.6的基础镜像, ...

  4. 【记录】利用jar包制作docker镜像

    [记录]利用jar包制作docker镜像 前提说明 创建构建docker文件 构建docker镜像 构建成功后启动容器 前提说明 jar包已上传linux服务器 jar包名称:demo.jar jar ...

  5. docker hub push_如何制作Docker镜像(image)?

    制作Docker镜像一般有2种方法: 使用hub仓库中已有的环境,安装自己使用的软件环境后完成image创建 通过Dockerfile,完成镜像image的创建 下面通过展示具体操作方法: 第一种:使 ...

  6. 龙芯Fedora21平台制作docker镜像,并且解决vi乱码问题

    http://ask.loongnix.org/?/article/81 实验环境   本文的实验都是在龙芯3A3000机器上. 操作系统是loongnix(Fedora21)20170726版本, ...

  7. 用GitHub Actions制作Docker镜像

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于GitHub Actions GitHub Act ...

  8. jar包制作Docker镜像

    一.编写Dokcerfile ###FROM 指定该docker镜像运行环境(必须有此docker镜像,此处选择jdk:8) FROM ubuntu_java8:v1 ###将准备的配置文件添加到容器 ...

  9. 在jetson xavier nx上制作docker镜像

    概览: 一.docker简介 二.在jetson xavier nx上制作docker镜像 一.docker简介 用途:对于一项工程,不同的机器都需要单独为其配置环境,且有时配环境是一件相当麻烦的事情 ...

最新文章

  1. MySQL · 捉虫动态 · 并行复制外键约束问题二
  2. 【Flutter】Flutter 拍照示例 ( 拍照并获取照片源码示例 | image_picker: ^0.5.2 版本 )
  3. 程序员的编程艺术第一章
  4. python构建知识库_手把手教导实战Python Web项目
  5. Flex-iframe在SWF中嵌入网页的组件(推荐)
  6. 安卓案例:标准化测试
  7. 启航~算法刷题第一天
  8. 使用Jackson解析JSON
  9. 将字符转换成带有圆圈的字符
  10. python基础刷题_数据结构与算法LeetCode刷题(Python)
  11. python 通用数据库类型_Python开发基础之Python常用的数据类型
  12. 采用Kettle分页处理大数据量抽取任务
  13. TDMA WIFI 技术
  14. 仿网易云音乐小程序-uniapp
  15. 狂神说 | Spring完整版笔记
  16. poker网络 -2
  17. 基于ssm智能仓库(进销存)管理系统获取(java毕业设计)
  18. STW(stop the )
  19. 哈利波特c++千行代码
  20. 基于Visual C#2010开发Windows7应用 多点触摸图片处理应用程序(1)-同时处理多张图片...

热门文章

  1. 数据技术专家能力模型
  2. 映客都是互刷礼物吗_iOS 基于 IM 实现仿映客刷礼物连击效果
  3. 啥?以后找工作面试求职者的将不是人!那是啥?道翰天琼认知智能机器人平台API接口为您揭秘-1。
  4. 毛利润,净利润和营业利润有什么区别
  5. 火柴棍等式(暴力枚举)
  6. 程序员如何看待码农这个称谓?
  7. 服务器护卫神怎么上传文件,护卫神异地备份系统怎么将数、据上传到服务器上?...
  8. Linux--日志分析查看——grep,sed,sort,awk运用
  9. 上节Pandas学会了吗?那我可教你进阶啦~
  10. S5PV210 WM8960音频驱动 学习