jib-maven 弹簧靴型材
Posted
技术标签:
【中文标题】jib-maven 弹簧靴型材【英文标题】:jib-maven spring boot profile 【发布时间】:2020-03-01 08:44:59 【问题描述】:在我的springboot项目中,有三个配置文件
application.yml --> 用于本地开发 application-test.yml --> 在测试环境中运行 application-prod.yml --> 在生产环境中运行
pom.xml
...
<properties>
<docker-repository>self-ip:port</docker-repository>
</properties>
...
<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>1.7.0</version>
<configuration>
<allowInsecureRegistries>true</allowInsecureRegistries>
<from>
<image>openjdk:8-jre-alpine</image>
</from>
<to>
<image>$docker-repository/$project.groupId/$project.artifactId</image>
</to>
<container>
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
<jvmFlags>
<jvmFlag>$JAVA_OPTS</jvmFlag>
<jvmFlag>-Dfile.encoding=UTF-8</jvmFlag>
<jvmFlag>-XX:+UseG1GC</jvmFlag>
<jvmFlag>-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log</jvmFlag>
<jvmFlag>-Djava.security.egd=file:/dev/./urandom</jvmFlag>
</jvmFlags>
</container>
</configuration>
</plugin>
</plugins>
</build>
然后push到我自己私有的docker仓库,就OK了
mvn -DsendCredentialsOverHttp=true jib:build
在不同的机器上运行
# On my test machine, I want to run like this
docker run --name test-xxx -d \
-p 8080:8080 -p 9080:9080 \
-e JAVA_OPTS="-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
-v ~/logs:/logs \
self-ip:port/xxx/yyy
# on my production machine, I want to run like this
docker run --name prod-xxx -d \
-p 8080:8080 \
-e JAVA_OPTS="-server -Xms1G -Xmx1G -Dspring.profiles.active=prod" \
-v /mnt/logs:/logs \
self-ip:port/xxx/yyy
当我在测试机器上运行时,它失败了
docker container ls -al
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
XXXXXXXXXXXX xxx "java $JAVA_OPTS -Df…" 3 seconds ago Exited (1) 2 seconds ago test-xxx
我的期望是这样的
# test machine
java -Xms256m -Xmx256m -Dspring.profiles.active=test \
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080 \
-Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps \
-XX:+PrintGCTimeStamps -Xloggc:/logs/gc.log \
-Djava.security.egd=file:/dev/./urandom \
-cp /app/resources:/app/classes:/app/libs/* \
xxx.yyy.MainClass
# production machine
java -server -Xms1G -Xmx1G -Dspring.profiles.active=prod \
-Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps \
-XX:+PrintGCTimeStamps -Xloggc:/logs/gc.log \
-Djava.security.egd=file:/dev/./urandom \
-cp /app/resources:/app/classes:/app/libs/* \
xxx.yyy.MainClass
我应该如何配置它? container --> environment
或 dockerClient --> environment
?
我在文档中没有找到任何相关的例子,它们都只是一个句子
更新 1
嗨@Haran 我将<jvmFlag>$JAVA_OPTS</jvmFlag>
修改为JAVA_TOOL_OPTS
并重新推送
并在测试中运行
docker container rm test-xxx
docker run --name test-xxx -d \
-p 8080:8080 \
-e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
ip:port/xx/yy
它也运行失败
$ docker container ls -al
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
XXXXXXXXXXXX xxx "java $JAVA_TOOL_OPTS -Df…" 3 seconds ago Exited (1) 2 seconds ago test-xxx
然后我删除 $JAVA_TOOL_OPTS 并重复上述 repush 和 docker rm & run
,运行成功,但没有自定义环境
$ docker exec -it test-xxx ps auxf
PID USER TIME COMMAND
1 root 0:05 java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+P
59 root 0:00 ps auxf
$ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
xx yy "java -Dfile.encoding=UTF-8 -XX:+UseG1GC '-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/logs/gc.log' -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass" 34 seconds ago Up 34 seconds 0.0.0.0:8080->8080/tcp test-xxx
更新 2
docker -e ...
命令的引号在里面和外面没有区别。
$ docker run --name test-xxx -d -p 8080:8080 \
-e JAVA_TOOL_OPTIONS="-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
ip:port/xx/yy
xxxxx
$ docker exec -it test-xxx env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin
HOSTNAME=4a7c5045109b
TERM=xterm
JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080
JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk/jre
JAVA_VERSION=8u212
JAVA_ALPINE_VERSION=8.212.04-r0
LANG=C.UTF-8
HOME=/root
$ docker run --name test-xxx1 -d -p 8081:8080 \
-e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
ip:port/xx/yy
xxxx
$ docker exec -it test-xxx1 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin
HOSTNAME=ae333ad8836f
TERM=xterm
JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080
JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk/jre
JAVA_VERSION=8u212
JAVA_ALPINE_VERSION=8.212.04-r0
LANG=C.UTF-8
HOME=/root
$ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
xxx ip:port/xx/yy "java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass" 3 minutes ago Up 3 minutes 0.0.0.0:8081->8080/tcp test-xxx1
xx ip:port/xx/yy "java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass" 3 minutes ago Up 3 minutes 0.0.0.0:8080->8080/tcp test-xxx
【问题讨论】:
试试 JAVA_TOOL_OPTIONS,docker run -e "JAVA_TOOL_OPTIONS=<JVM flags>" <image name>
。有关更多信息,请参阅:github.com/GoogleContainerTools/jib/blob/master/docs/faq.md 另外,请尝试在引号内传递 Env 变量。类似于: docker run -e "JAVA_OPTS=-server -Xms1G -Xmx1G -Dspring.profiles.active=prod" imagename
@Haran 试过了,还是有问题,下面看我的长回复。
你能不能再试试:将 JAVA_TOOL_OPTIONS 放在引号内(") -e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server= y,suspend=n,address=9080"
哦,对不起,我的错...命令是docker run --name test-xxx -d -p 8080:8080 -p 9080:9080 -e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" ip:port/xx/yy
,java_tool_options 用双引号括起来,运行成功,但没有自定义环境
只需设置一个名为 SPRING_PROFILES_ACTIVE
的 docker 环境变量,Spring Boot 就会选择它。您不需要将其作为系统变量传递。您可以通过这种方式覆盖所有定义的变量。 IE。 SPRING_DATASOURCE_URL
将被视为 spring.datasource.url
等的值。
【参考方案1】:
要设置JVM参数,只需在运行时设置JAVA_TOOL_OPTIONS
即可。实际上,我可以从您的更新中看到您已经尝试过。
$ docker run ... -e "JAVA_TOOL_OPTIONS=..."
大多数 JVM 会自动获取 JAVA_TOOL_OPTIONS 环境变量,因此您无需将 JAVA_TOOL_OPTIONS
中的内容作为命令行参数传递给 java
二进制文件。您可以在您的机器上本地验证此行为(在容器内部或外部):
$ JAVA_TOOL_OPTIONS=-Xmx256m java ABCD # no need to pass extra arguments
Picked up JAVA_TOOL_OPTIONS: -Xmx256m
Error: Could not find or load main class ABCD
$ docker run -e "JAVA_TOOL_OPTIONS=-Xmx256m" --entrypoint java openjdk:11 ABCD
Picked up JAVA_TOOL_OPTIONS: -Xmx256m
Error: Could not find or load main class ABCD
Caused by: java.lang.ClassNotFoundException: ABCD
所以,只需在运行时定义 JAVA_TOOL_OPTIONS
(您已经使用 docker run -e
完成了),不要定义 <jvmFlags>
或修改 <entrypoint>
。
最后,是JAVA_TOOL_OPTIONS
,而不是JAVA_TOOL_OPTS
。
【讨论】:
感谢提醒自己的问题,好几次看了docker logs test-xxx日志信息,看到消息 Picked up JAVA_TOOL_OPTIONS: ...(加上-server选项,Information: Unrecognized选项:-server),然后测试测试命令一段时间,然后测试生产命令。时间久了,整个人都迷失了。【参考方案2】:JAVA_TOOL_OPTIONS 有效,现在我只需要这样做。
<properties>
<docker-repository>self-ip:port</docker-repository>
</properties>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.7.0</version>
<configuration>
<allowInsecureRegistries>true</allowInsecureRegistries>
<from>
<image>openjdk:8-jre-alpine</image>
</from>
<to>
<image>$docker-repository/$project.groupId/$project.artifactId</image>
</to>
<container>
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
<jvmFlags>
<!-- global java option -->
<jvmFlag>-Dfile.encoding=UTF-8</jvmFlag>
<jvmFlag>-XX:+UseG1GC</jvmFlag>
<jvmFlag>-verbose:gc</jvmFlag>
<jvmFlag>-XX:+PrintGCDetails</jvmFlag>
<jvmFlag>-XX:+PrintGCDateStamps</jvmFlag>
<jvmFlag>-XX:+PrintGCTimeStamps</jvmFlag>
<jvmFlag>-Xloggc:/var/log/gc.log</jvmFlag>
<jvmFlag>-Djava.security.egd=file:/dev/./urandom</jvmFlag>
</jvmFlags>
</container>
</configuration>
</plugin>
# on test machine
docker run --name test-xxx -d \
-p 8080:8080 -p 9080:9080 \
-e JAVA_TOOL_OPTIONS="-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
-v ~/logs:/var/log \
self-ip:port/xxx/yyy
# on production machine
docker run --name prod-xxx -d \
-p 8080:8080 \
-e JAVA_TOOL_OPTIONS="-Xms1G -Xmx1G -Dspring.profiles.active=prod" \
-v /mnt/logs:/var/log \
self-ip:port/xxx/yyy
PS:无法在 JAVA_TOOL_OPTIONS 中添加-client
-server
选项:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/envvars002.html
用于测试
$ docker top test-xxx
UID PID PPID C STIME TTY TIME CMD
root 32157 32138 15 11:05 ? 00:00:05 java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass
$ docker logs test-xxx
Picked up JAVA_TOOL_OPTIONS: -Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080
Listening for transport dt_socket at address: 9080
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (...)
产品
$ docker top prod-xxx
UID PID PPID C STIME TTY TIME CMD
root 13989 13970 8 11:09 ? 00:00:05 java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass
$ docker logs prod-xxx
Picked up JAVA_TOOL_OPTIONS: -Xms1G -Xmx1G -Dspring.profiles.active=prod
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (...)
只有参数不附加到命令行选项,但它们是有效的。
【讨论】:
【参考方案3】:选项 1:Java 系统属性(VM 参数)
重要的是 -D 参数在您的 application.jar 之前,否则它们将无法识别。
java -jar -Dspring.profiles.active=prod application.jar
选项 2:程序参数
java -jar application.jar --spring.profiles.active=prod --spring.config.location=c:\config
使用 jib 作为 maven 插件时 - 更改 spring 配置文件位置的加载: 然后 entryPoint 将在容器内传递,但似乎 jib 插件没有选择它。 因此需要在 pom 中进行以下更改以获取位置的参数访问权限:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>2.2.0</version>
<configuration>
<to>
<image>image-url</image>
</to>
<container>
<creationTime>$maven.build.timestamp</creationTime>
<mainClass>com.package.SpringBootMainClass</mainClass>
<args>
<arg>--spring.config.location=/demo/location/application.yml</arg>
</args>
</container>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
【讨论】:
以上是关于jib-maven 弹簧靴型材的主要内容,如果未能解决你的问题,请参考以下文章
在某些机器上构建时,带有弹簧靴的 Swagger 可以工作,但在其他机器上则不行