pkslow.com 南瓜慢说

  • AllArticles
  • Container
  • Spring
  • Life
  • Cloud
  • Collections
  • About
  • GitHub

  • Search
Terraform101 English Terraform Middleware config Go Private Kubernetes pkslow Test HTTPS Redis Docker Mac Plan Stream MongoDB Spring DevOps JVM String Map Set List Performance Email Springboot JavaCollections ArrayList Java

一行代码的变更让我陷入无尽加班,Dockerfile的ENTRYPOINT的两种格式

Created on: 2020-09-04 | Category: Springboot | 0 | View: 1232

1 前言

前几天因为同事改了一行代码,硬是搞了一整天才定位出问题。改的是Dockerfile的ENTRYPOINT,一起来看看怎么回事。

2 问题

通过安装在Kubernetes的Spring Cloud Data Flow跑Spring Cloud Task,发现怎么都无法传参进去,于是开始了漫长的探索历程。

  • 有问题,第一反应当然是看日志,发现日志一直都是读取jar里面的application.properties,传入的参数没有接收到,没有覆盖原来的配置,导致数据库连接错误。

  • 可能是日志信息不够,于是想办法打开debug或trace日志级别。通过传参方式无法改变日志级别,所以修改代码,重新打包。

  • 依然无法查找到有用信息,还是无法传参。

3 将问题分解

目前流程是scdf (Data Flow)传参给Kubernetes,Kubernetes传参给Pod,Pod传给Docker容器。查看Pod的信息Arguments发现已经有传参了,所以问题就在于,为何Docker到Springboot应用之间没有传递成功。(当然早已经确保java -jar运行应用可以传参)。

通过这样分析,问题就明朗起来了,就是在Docker这层传参失败。(当然这是知道了结果才这么快得出结论,实际过程比较曲折)

于是研究Docker在打包镜像时发生了什么事情。原来,是由于Dockerfile的ENTRYPOINT被人修改了。(其实直接查看代码变更也是一种分析方法,但当时我只查看了master分支,也没有拉取最新代码,所以变更记录不全,导致无法快速定位问题。这也是一个教训,应该拉取所有变更再查看。)

4 ENTRYPOINT

对于ENTRYPOINT有两种格式:

exec格式(官方推荐使用):

ENTRYPOINT ["executable", "param1", "param2"]

shell格式:

ENTRYPOINT command param1 param2

这两种不同的格式有一个很大的区别在于:exec格式可以接受参数,而shell格式是会忽略参数的。shell格式相当于在前面还要再添加/bin/sh -c,所以app启动的进程ID不是1。

5 简单示例

准备一个Dockerfile:

FROM adoptopenjdk/openjdk8-openj9
VOLUME /tmp

ARG TIME_ZONE=Asia/Shanghai

ENV TZ=${TIME_ZONE}

COPY target/*.jar pkslow.jar


#ENTRYPOINT java -jar pkslow.jar
ENTRYPOINT ["java", "-jar", "pkslow.jar"]

分别build出两个镜像:

pkslow/noneweb-exec:0.0.1-SNAPSHOT
pkslow/noneweb-shell:0.0.1-SNAPSHOT

查看ENTRYPORT信息:

$ docker inspect pkslow/noneweb-exec:0.0.1-SNAPSHOT
  "Entrypoint": [
                "java",
                "-jar",
                "pkslow.jar"
            ],
            
$ docker inspect pkslow/noneweb-shell:0.0.1-SNAPSHOT
 "Entrypoint": [
                "/bin/sh",
                "-c",
                "java -jar pkslow.jar"
            ],

这就能看出差别来了。

试着传参数启动:

$ docker run pkslow/noneweb-exec:0.0.1-SNAPSHOT --pkslow.webSite=www.pkslow.com

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.3.RELEASE)

com.pkslow.noneweb.NonewebApplication    : Starting NonewebApplication v0.0.1-SNAPSHOT on f3cc36eefeb9 with PID 1 (/pkslow.jar started by root in /)
com.pkslow.noneweb.NonewebApplication    : No active profile set, falling back to default profiles: default
com.pkslow.noneweb.NonewebApplication    : Started NonewebApplication in 1.392 seconds (JVM running for 2.2)
com.pkslow.noneweb.AppCommandRunner      : pkslow commandLine runner
com.pkslow.noneweb.AppCommandRunner      : WebSite: www.pkslow.com

#----------------------------------- 
$ docker run pkslow/noneweb-shell:0.0.1-SNAPSHOT --pkslow.webSite=www.pkslow.com

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.3.RELEASE)

com.pkslow.noneweb.NonewebApplication    : Starting NonewebApplication v0.0.1-SNAPSHOT on 6b046abfecf2 with PID 6 (/pkslow.jar started by root in /)
com.pkslow.noneweb.NonewebApplication    : No active profile set, falling back to default profiles: default
com.pkslow.noneweb.NonewebApplication    : Started NonewebApplication in 1.38 seconds (JVM running for 2.235)
com.pkslow.noneweb.AppCommandRunner      : pkslow commandLine runner
com.pkslow.noneweb.AppCommandRunner      : WebSite: pkslow.com

通过启动Springboot就能发现:

exec格式的镜像启动PID=1,成功接收参数pkslow.webSite;

shell格式的镜像启动PID!=1,没有接收参数pkslow.webSite,打印出默认值;

6 总结

权当记录,以便别人也踩坑吧,也提供一些定位与解决问题的思路。


参考文档:官方文档


Code for all: GitHub

欢迎关注微信公众号<南瓜慢说>,将持续为你更新...

file

Recommendations:
Cloud Native
Terraform
Container: Docker/Kubernetes
Spring Boot / Spring Cloud
Https
如何制定切实可行的计划并好好执行

  • Author 作者: LarryDpk 南瓜慢说
  • Link 链接: https://www.pkslow.com/archives/docker-entrypoint-issue
  • 版权声明: 本博客所有文章除特别声明外,不可转载!
# Terraform101 # English # Terraform # Middleware # config # Go # Private # Kubernetes # pkslow # Test # HTTPS # Redis # Docker # Mac # Plan # Stream # MongoDB # Spring # DevOps # JVM # String # Map # Set # List # Performance # Email # Springboot # JavaCollections # ArrayList # Java
Terraform101 English Terraform Middleware config Go Private Kubernetes pkslow Test HTTPS Redis Docker Mac Plan Stream MongoDB Spring DevOps JVM String Map Set List Performance Email Springboot JavaCollections ArrayList Java
Intellij IDEA同一个项目(窗口)多个代码仓库
哀友文-怀念逝去挚友
  • Contents
  • Site Overview
南瓜慢说

南瓜慢说

多年Java开发,主要专注后端技术:Java/Spring/Springboot/微服务/大数据等。

多读书,多分享;多写作,多整理。

241 Posts
9 Categories
30 Tags
RSS
0%
© 2020 — 2022 南瓜慢说 pkslow The WebSite keeping alive:   粤ICP备20036375号