linux+jdk8+opencv341最轻最小docker基础镜像制作

389 阅读6分钟

前言

在容器化应用中,后端使用java开发时,我们一般会在Dockerfile中会采用 openjdk:8-jre-alpine 作为基础镜像构建自己的image镜像,openjdk:8-jre-alpine 就是一个 java8 + 最小内核的linux,体积大概在85M。

但在有的应用中,我们会用到opencv这个组件,因此以上的基础镜像就不适用了,那我们首先想到的是用 centos7 + jdk8 + opencv 构建一个基础镜像出来。

刚开始拉取centos:7.9.2009镜像作为基础镜像进行制作,发现最后体积有453M,感觉作为基础镜像未免有些过大,后来放弃使用了,大概制作如下仅供参考。

1、centos7 + jdk8 + opencv 制作过程

拉取centos7基础镜像

拉取centos7镜像,启动容器,登录进去:

docker pull centos:7.9.2009
docker run -dit --name centos centos:7.9.2009
docker exec -ti centos bash

下载opencv3.4.1进行编译

在centos容器中下载地址:codeload.github.com/opencv/open…

继续在容器中进行解压编译opencv,编译后会产生一些lib库文件和so文件,将编译完成后的 /usr/local/lib64 目录打包成lib64.tar.gz放在root下,里面有编译后的文件。

修复so文件警告

后期在使用本次创建的基础镜像启动自己容器时会出现警告,为避免再次回来修复再制作,这里提前避坑处理掉先,以下是警告内容:

OpenJDK 64-Bit Server VM warning: You have loaded library /usr/lib/libopencv_java341.so which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.

先安装execstack:

yum install /usr/bin/execstack

然后修复编译出来的so文件,应该在/usr/local/share/lib64/下:

execstack -c libopencv_java341.so

复制编译产物到宿主机

在宿主机上(就是容器外)执行,将容器中的编译产物复制到主机的/root/opencv目录下:

docker cp a78ec65ef50a:/root/lib64.tar.gz /root/opencv
docker cp a78ec65ef50a:/usr/local/share/lib64/libopencv_java341.so /root/opencv

重新拉取centos7

重新拉取一个干净的centos:7.9.2009镜像作为基础镜像,启动另外一个容器登录进去,忘掉上面这个容器(可以删掉),因为上面这个镜像做了一堆操作,我们想让镜像变得纯粹干净体积小,所以重新做一个。

容器中安装java8

在新的centos7容器中,登录进去,安装jdk8:

yum list java-1.8*
yum install java-1.8.0-openjdk.x86_64 -y

复制编译产物到新容器

退出容器,在宿主机里执行命令复制宿主机lib64.tar.gz到新容器中,解压并将全部so文件包括libopencv_java341.so复制到容器的/usr/lib64目录下,删除lib64.tar.gz压缩包:

docker cp 新容器:/root/libopencv_java341.so /usr/lib64/
docker cp 新容器:/root/lib64.tar.gz /root/
tar -xzvf lib64.tar.gz -C /usr/lib64
rm -rf lib64.tar.gz

创建新镜像

以上容器已经具有centos7+jdk8+opencv431的环境,容器外,使用 docker ps -a 命令查看运行的centos镜像,查找镜像Id,或使用 docker container ls 命令查看,根据容器创建一个新的镜像,容器外执行如下命令:

docker commit 172838787f4c centos7-jdk8-opencv341:1.0.0

镜像打标签,推送镜像到自己的镜像仓库里:

docker tag centos7-jdk8-opencv341:1.0.0 192.168.1.xxx:5000/huitu/centos7-jdk8-opencv341:1.0.0
docker push 192.168.1.xxx:5000/huitu/centos7-jdk8-opencv341:1.0.0

以上就是构建基础镜像的过程,发现体积有点大,于是想能不能直接在 openjdk:8-jre-alpine 基础镜像的基础上加入opencv的内容再构建出一个新的基础镜像,于是有了下面部分。

2、openjdk:8-jre-alpine + opencv431 的制作

拉取openjdk:8-jre-alpine基础镜像

拉取镜像、运行容器、登录容器

docker pull openjdk:8-jre-alpine
docker run -dit --name alpine openjdk:8-jre-alpine
docker exec -ti alpine sh

容器中加入opencv的编译产物

在openjdk:8-jre-alpine容器里,把centos-opencv-java8容器编译出的so文件以及其他的依赖文件复制到alpine容器里,主要有以下文件:

docker cp feb70ae1d2f0:/usr/lib64/libopencv_java341.so /root/
docker cp feb70ae1d2f0:/usr/lib64/libjpeg.so.62 /root/
docker cp feb70ae1d2f0:/usr/lib64/libjpeg.so.62.1.0 /root/
docker cp feb70ae1d2f0:/usr/lib64/libwebp.so.4 /root/
docker cp feb70ae1d2f0:/usr/lib64/libwebp.so.4.0.2 /root/
docker cp feb70ae1d2f0:/usr/lib64/libpng15.so.15 /root/
docker cp feb70ae1d2f0:/usr/lib64/libpng15.so.15.13.0 /root/
docker cp feb70ae1d2f0:/usr/lib64/libtiff.so.5 /root/
docker cp feb70ae1d2f0:/usr/lib64/libtiff.so.5.2.0 /root/
docker cp feb70ae1d2f0:/usr/lib64/libtiffxx.so.5 /root/
docker cp feb70ae1d2f0:/usr/lib64/libtiffxx.so.5.2.0 /root/
docker cp feb70ae1d2f0:/usr/lib64/libungif.so.4 /root/
docker cp feb70ae1d2f0:/usr/lib64/libungif.so.4.1.6 /root/
docker cp feb70ae1d2f0:/usr/lib64/libungif.so.4 /root/
docker cp feb70ae1d2f0:/usr/lib64/ld-2.17.so /root/
docker cp feb70ae1d2f0:/usr/lib64/ld-linux-x86-64.so.2 /root/

以上为从centos-opencv-java8容器拷出到宿主机

以下为从宿主机拷进openjdk:8-jre-alpine容器

docker cp /root/libopencv_java341.so 011d0832f2c2:/usr/lib/
docker cp /root/libjpeg.so.62 011d0832f2c2:/usr/lib/
docker cp /root/libjpeg.so.62.1.0 011d0832f2c2:/usr/lib/
docker cp /root/libwebp.so.4 011d0832f2c2:/usr/lib/
docker cp /root/libwebp.so.4.0.2 011d0832f2c2:/usr/lib/
docker cp /root/libpng15.so.15 011d0832f2c2:/usr/lib/
docker cp /root/libpng15.so.15.13.0 011d0832f2c2:/usr/lib/
docker cp /root/libtiff.so.5 011d0832f2c2:/usr/lib/
docker cp /root/libtiff.so.5.2.0 011d0832f2c2:/usr/lib/
docker cp /root/libtiffxx.so.5 011d0832f2c2:/usr/lib/
docker cp /root/libtiffxx.so.5.2.0 011d0832f2c2:/usr/lib/
docker cp /root/libungif.so.4 011d0832f2c2:/usr/lib/
docker cp /root/libungif.so.4.1.6 011d0832f2c2:/usr/lib/
docker cp /root/ld-2.17.so 011d0832f2c2:/usr/lib/
docker cp /root/ld-linux-x86-64.so.2 011d0832f2c2:/usr/lib/

创建新镜像

根据以上容器创建出新的镜像,commit、tag、push

docker commit 011d0832f2c2 jre-alpine-opencv:1.0.4
docker tag jre-alpine-opencv:1.0.3 192.168.1.xxx:5000/huitu/jre-alpine-opencv:1.0.4
docker push 192.168.1.xxx:5000/huitu/jre-alpine-opencv:1.0.4

打包后的镜像差不多157M。

3、下载

不想自己亲自实践的,也可以直接从以下地址拉取我创建好的镜像:

docker pull ccr.ccs.tencentyun.com/galar/jre-alpine-opencv:1.0.4

docker pull registry.cn-hangzhou.aliyuncs.com/galar/jre-alpine-opencv:1.0.4