GVKun编程网logo

docker 优雅的关闭 spring boot 应用容器(如何关闭docker容器)

23

如果您对docker优雅的关闭springboot应用容器和如何关闭docker容器感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解docker优雅的关闭springboot应用容器的各种细节,

如果您对docker 优雅的关闭 spring boot 应用容器如何关闭docker容器感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解docker 优雅的关闭 spring boot 应用容器的各种细节,并对如何关闭docker容器进行深入的分析,此外还有关于62-docker-compose 结合 dockerfile 部署 springboot 应用、62-docker-compose 结合dockerfile 部署springboot应用、docker - dockerfile构建一个简单的springboot应用镜像、docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)的实用技巧。

本文目录一览:

docker 优雅的关闭 spring boot 应用容器(如何关闭docker容器)

docker 优雅的关闭 spring boot 应用容器(如何关闭docker容器)

============================
docker 微服务的优雅关闭
============================

使用 docker stop 关闭容器时, 只有 init(pid 1)进程能收到中断信号, 如果容器的pid 1 进程是 sh 进程, 它不具备转发结束信号到它的子进程的能力, 所以我们真正的java程序得不到中断信号, 也就不能实现优雅关闭. 解决思路是: 让pid 1 进程具备转发终止信号, 或者将 java 程序配成 pid 1 进程.

需要说明的是, docker stop 默认是等待10秒钟, 这个时间有点太短了, 可以加 -t 参数, 比如 -t 30 等待30秒钟.

 

----------------------------------
背景知识
----------------------------------

上面的 Dockerfile 的pid 1是一个 sh 命令,并不能实现优雅关闭, 需要再改进.

 

ENTRYPOINT/CMD 的几种写法, 会影响 pid 1 进程的产生:
写法1:
"shell" format 的 ENTRYPOINT/CMD, 不带方括号:
ENTRYPOINT top -b
#PID 1 是 /bin/sh -c shell  top -b
#另外有个 pid 7 是 top -b

写法2:
"shell" format 的 ENTRYPOINT/CMD, 不带方括号, 但这次ENTRYPOINT后紧跟了一个 exec :
ENTRYPOINT exec top -b
#PID 1 是 top -b

写法3:
"exec" form 的 ENTRYPOINT/CMD, 方括号括着, 每个部分都是json字符串.
ENTRYPOINT ["top","-b"]
pid 1 进程就是 top -b

所以推荐使用"exec" form的命令, 而不是 "shell" 形式的命令.


----------------------------------
init 进程调整方案
----------------------------------
方案1: 自行确保 pid 1 是我们的java程序.
上面的 Dockerfile 可以确保 java 程序作为 pid 1进程.

方案评价: 有时候不太容易将我们的主程序调整为 pid 1 进程, 另外虽然 docker 容器推荐是单进程, 但实际情形往往不是这么理想. 本方案仅仅适合单进程容器.

方案2: 适合于 Docker 1.13 以上.
Docker 1.13以上的docker run 命令新增了 --init 参数, 加了该参数后, docker 会启用 tini 作为 init (pid 1) 进程, 该 tini 进程能够将终止信号转发给其子进程, 同时能reap 子进程, 不会出现因孤儿进程导致的线程句柄无法回收情形.
详见: https://github.com/krallin/tini

 

方案3(推荐): 在docker镜像中强制 tini 作为 init(pid 1) 进程, 该方案使用范围广, ENTRYPOINT 可以是任意sh脚本文件.

改造之前的 Dockerfile

ENTRYPOINT ["/docker-entrypoint.sh"]

改造后的 Dockerfile

# Add Tini
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini

ENTRYPOINT ["/usr/local/bin/tini", "--", "/docker-entrypoint.sh"]


tini 文档:
https://github.com/krallin/tini
有关 docker run --init 参数的说明
http://stackoverflow.com/a/39593409/6309



===============================
更多推荐
===============================
https://efekahraman.github.io/2018/04/docker-awareness-in-java

62-docker-compose 结合 dockerfile 部署 springboot 应用

62-docker-compose 结合 dockerfile 部署 springboot 应用

dockerfile 内容:

# 基础镜像
FROM  openjdk:8-jre
# author
MAINTAINER lw

# 挂载目录
VOLUME /home/ybss
# 创建目录
RUN mkdir -p /home/ybss
# 指定路径
WORKDIR /home/ybss

ADD ./jar/lib /home/ybss/lib
ADD ./jar/*.yml /home/ybss/
# 复制jar文件到路径
COPY ./jar/run.jar /home/ybss/run.jar
# 启动认证服务
ENTRYPOINT ["java","-jar","-Dserver.port=9200","-Dspring.profiles.active=dev","run.jar"]

docker-compose.yml 内容:

version : ''3.8''
services:
  ybss-auth:
    container_name: ybss-auth
    build:
      context: ./ybss/auth
      dockerfile: dockerfile
    ports:
      - "19200:9200"
    volumes:
      - /home/ybss/ybss/auth/jar:/home/ybss

networks:
  ybss_default:
    driver: bridge

volumes 挂载目录 /home/ybss/ybss/auth/jar,有更新时,只需要把更新 jar 和文件替换即可。

部署脚本 shell:

#!/bin/sh
auth(){
  chmod 777 -R ./ybss/auth/*
  docker-compose up -d ybss-auth
}
stop(){
	docker-compose stop
}
case "$1" in
"auth")
	auth
;;
"s")
	stop
;;

62-docker-compose 结合dockerfile 部署springboot应用

62-docker-compose 结合dockerfile 部署springboot应用

dockerfile内容:

# 基础镜像
FROM  openjdk:8-jre
# author
MAINTAINER lw

# 挂载目录
VOLUME /home/ybss
# 创建目录
RUN mkdir -p /home/ybss
# 指定路径
WORKDIR /home/ybss

ADD ./jar/lib /home/ybss/lib
ADD ./jar/*.yml /home/ybss/
# 复制jar文件到路径
COPY ./jar/run.jar /home/ybss/run.jar
# 启动认证服务
ENTRYPOINT ["java","-jar","-Dserver.port=9200","-Dspring.profiles.active=dev","run.jar"]

docker-compose.yml 内容:

version : ''3.8''
services:
  ybss-auth:
    container_name: ybss-auth
    build:
      context: ./ybss/auth
      dockerfile: dockerfile
    ports:
      - "19200:9200"
    volumes:
      - /home/ybss/ybss/auth/jar:/home/ybss

networks:
  ybss_default:
    driver: bridge

volumes挂载目录/home/ybss/ybss/auth/jar,有更新时,只需要把更新jar和文件替换即可。

部署脚本shell:

#!/bin/sh
auth(){
  chmod 777 -R ./ybss/auth/*
  docker-compose up -d ybss-auth
}
stop(){
    docker-compose stop
}
case "$1" in
"auth")
    auth
;;
"s")
    stop
;;

docker - dockerfile构建一个简单的springboot应用镜像

docker - dockerfile构建一个简单的springboot应用镜像

      在前面的 《docker - 构建一个简单的docker镜像》中,介绍了两种构建镜像的方法,其中,通过dockerfile文件构建镜像是在实际生产中常用的;除此之外,还通过 docker - Dockerfile常用指令 和  docker - 常用命令 两篇文章介绍了dockerfile的指令和docker的常用命令,接下来,我们将会使用所学的知识构建一个简单的springboot应用。

    该springboot应用对外暴露了一个api,对外暴露8080端口,日志文件写在应用当前目录,部分代码以及配置文件如下:

@Slf4j
@SpringBootApplication
@RestController
public class SpringbootDockerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootDockerApplication.class, args);
    }

    @RequestMapping("/docker")
    public String docker() {
        log.info("access docker home at " + LocalTime.now());
        return "Hello Docker!";
    }
}

application.properties

spring.application.name=springboot-docker
server.port=8080
logging.file=app.log

把jar和dockerfile文件上传到一个springboot-docker目录中

[root@localhost springboot-docker]# ls
Dockerfile  springboot-docker-1.0.jar

Dockerfile:

FROM openjdk:8u181-jdk-alpine
ARG workdir=/app
VOLUME ${workdir}
WORKDIR ${workdir}
ADD springboot-docker-1.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
  • FROM openjdk:8u181-jdk-alpine : 从docker仓库中获取基础镜像
  • ARG workdir=/app : 添加变量,该变量只在当前的dockerfile中有效,如果换成ENV,则在容器中生效。这里需要注意的是,ARG和ENV对哪些指令是起效的,可以参考  docker - Dockerfile常用指令 
  • VOLUME ${workdir} : 把宿主机的目录(该目录可以通过docker inspect dockerName查看)挂载到容器中的/app这个目录,这样可以在宿主机中查看该目录的内容。还有一个很重要的原因,就是数据持久化,如果不挂载,当容器关闭删除后,数据将会跟着被删除。这里因为/app是应用所在的目录,该目录会产生日志等其它内容。
  • WORKDIR ${workdir} :指定工作目录,下面的指令操作将在这个指定目录中执行。还有一点是,当通过交互模式的exec命令进入到该容器时,默认当前路径是/app
  • ADD springboot-docker-1.0.jar app.jar : 添加文件到WORKDIR
  • EXPOSE 8080 : 暴露8080端口,需要通过容器IP和端口访问应用。如果想通过宿主机的IP和端口访问应用,需要在RUN容器的时候绑定。可以参考docker - Dockerfile常用指令 的run命令
  • ENTRYPOINT: 运行容器后执行的第一条命令,这里通过java -jar命令运行应用。

接下通过BUILD命令构建镜像

[root@localhost springboot-docker]# docker build -t springboot-docker:1.0 .

Sending build context to Docker daemon  17.85MB
Step 1/7 : FROM openjdk:8u181-jdk-alpine
 ---> 97bc1352afde
Step 2/7 : ARG workdir=/app
 ---> Using cache
 ---> a3818e8696c2
Step 3/7 : VOLUME ${workdir}
 ---> Using cache
 ---> e2faefe34aa6
Step 4/7 : WORKDIR ${workdir}
 ---> Using cache
 ---> 144b537c1b57
Step 5/7 : ADD springboot-docker-1.0.jar app.jar
 ---> Using cache
 ---> daca849e1012
Step 6/7 : EXPOSE 8080
 ---> Using cache
 ---> 123da0847dd3
Step 7/7 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
 ---> Using cache
 ---> de46a3f96d91
Successfully built de46a3f96d91
Successfully tagged springboot-docker:1.0

查看当前本地仓库的镜像,已经构建springboot-docker:1.0镜像

[root@localhost springboot-docker]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
springboot-docker   1.0                 de46a3f96d91        38 minutes ago      121MB
openjdk             8u181-jdk-alpine    97bc1352afde        5 weeks ago         103MB

运行镜像

docker run -p 8080:8080 -d --name springboot-docker springboot-docker:1.0

通过-p参数,把容器中的8080端口映射到宿主机中的8080端口。--name,给容器起一个名字

可以查看springboot应用的启动情况

docker logs -f springboot-docker 

查看容器的运行情况

docker inspect springboot-docker

只看一些关键的信息

"Mounts": [
            {
                "Type": "volume",
                "Name": "90df5c82f11290eddfc86faead12e4a79649672845b2a816e04f868da76851a3",
                "Source": "/var/lib/docker/volumes/90df5c82f11290eddfc86faead12e4a79649672845b2a816e04f868da76851a3/_data",
                "Destination": "/app",
                "Driver": "local",
            }
        ],
"Networks": {
	"bridge": {
		"Gateway": "172.17.0.1",
		"IPAddress": "172.17.0.2",
	}
}

    宿主机中的 /var/lib/docker/volumes/90df5c82f11290eddfc86faead12e4a79649672845b2a816e04f868da76851a3/_data 目录挂载到 容器的 /app目录

    容器的IP地址 172.17.0.2

    运行成功后,在宿主机中通过命令访问服务

curl 172.17.0.2:8080/docker

    也可以通过宿主机的IP或者localhost访问,因为已经绑定

curl 127.0.0.1:8080/docker

 

 

docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)

docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)

上一篇  docker 使用教程3-(Docker安装Nginx) 学习如何拷贝文件到容器

本篇介绍如何使用docker创建Java容器运行SpringBoot项目

 

大部分教程都是使用Dockerfile来创建镜像再去运行,当然这也是一种办法,本篇两种方法都有介绍: 

思路1:先拉取java镜像,构建java容器,再把SpringBoot的jar包拷进容器,然后进入容器运行jar包就OK了。

思路2:构建DockerFile创建SpringBoot容器运行。

 

实现方式一

①、拉取镜像

docker pull java:8

 

②、运行容器

docker run -p 8888:8001 --name java-test -d java:8 tail -f /dev/null

参数解释:

-p 端口映射:(主机端口:容器端口)
--name 容器名称(java-test)
-d 后台运行
java:8 镜像名称:版本号
tail -f /dev/null 有事可做(不然运行了就退出了)

 

 

 

 

 

 

 

③、拷贝 jar 包到容器内部

    1、先下载SpringBoot项目jar包

          jar包下载地址:https://gitee.com/cnetopro/springboot-dcoker

    2、通过Xftp或者其他软件把 springboot-0.0.1-SNAPSHOT.jar 传输到主机

    3、把 springboot-0.0.1-SNAPSHOT.jar 拷贝到容器内部

docker cp /root/springboot-0.0.1-SNAPSHOT.jar 容器ID:/

 

④、进入容器运行项目

进入容器

docker exec -it 容器ID bash

运行SpringBoot项目

nohup java -jar springboot-0.0.1-SNAPSHOT.jar /dev/null 2>&1 &

参数解释:

buhup 谐音no hope,用于后台运行退出不终止项目。
dev/null 日志输入地址(不保留日志)
2>&1 & 标准输出

 

 

 

 

查看运行情况

ps -aux|grep java

 

⑤万事大吉

在浏览器输入 IP:8888 即可看到:

Hello SpringBoot Docker

 

实现方式二

使用Dockerfile构建SpringBoot项目运行环境

①、拉取镜像

docker pull java:8

 

②、下载 SpringBoot 项目 jar 包

    1、先下载SpringBoot项目jar包

          jar包下载地址:https://gitee.com/cnetopro/springboot-dcoker

    2、通过Xftp或者其他软件把 springboot-0.0.1-SNAPSHOT.jar 传输到主机

 

③、创建Dockerfile

vim Dockerfile

内容:

FROM java:8
copY springboot-0.0.1-SNAPSHOT.jar /
CMD java -jar springboot-0.0.1-SNAPSHOT.jar

解释:

FROM 基于 java:8镜像创建
copY 把当前目录的springboot-0.0.1-SNAPSHOT.jar拷贝到容器内的/目录下
CMD 执行命令java -jar springboot-0.0.1-SNAPSHOT.jar 运行项目

 

 

 

 

 

④、构建镜像

docker build -t springboot_test .

解释:

build -t

构建镜像名为 springboot_test
. 表示当前目录的Dockerflie文件

 

 

 

 

 

⑤、运行镜像

docker run -p 8888:8001 --name java-test -d springboot_test

 

⑥、万事大吉

在浏览器输入 IP:8888 即可看到:

Hello SpringBoot Docker

 

关于docker 优雅的关闭 spring boot 应用容器如何关闭docker容器的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于62-docker-compose 结合 dockerfile 部署 springboot 应用、62-docker-compose 结合dockerfile 部署springboot应用、docker - dockerfile构建一个简单的springboot应用镜像、docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)等相关知识的信息别忘了在本站进行查找喔。

本文标签: