docker for windows调取dll动态库
本次docker的环境是安装在win10系统,在docker容器内部访问dll动态库文件一、本次项目的服务节点是多模块协作的,需要在每个容器中运行一个服务节点,所以需要部署多个docker,最后用k8s统一管理1、win10环境下docker的安装,参照网上的其他教程,这里就不贴了,浪费时间。2、注意,win10系统的docker for windows的可视化管理,设置为windows容器...
本次docker的环境是安装在win10系统,在docker容器内部访问dll动态库文件
一、本次项目的服务节点是多模块协作的,需要在每个容器中运行一个服务节点,所以需要部署多个docker,最后用k8s统一管理
1、win10环境下docker的安装,参照网上的其他教程,这里就不贴了,浪费时间。
2、注意,win10系统的docker for windows的可视化管理,设置为windows容器,Settings中Daemon顺便把镜像加速设置好,在拉取镜像的时候可以稍微快一点,但是没什么卵用,好像还是很慢,拉取个300多MB的openjdk镜像拉了一天,各种重连。
3、关于拉取镜像,能弄到镜像的tar包可以直接docker load < tar包名,直接安装镜像,弄不到就老实在dockerhub拉取。
二、服务节点需要与动态库dll文件使用jna调取,在docker容器中,服务节点的可执行jar要调取dll动态库
1、开发的时候,使用的是jna,版本这里尽量使用新版本的jna,低版本可能不太兼容windows for docker,如果调取不成功,可以尝试换下版本试试。
2、调取dll动态库文件时,加载的依赖项比较多,要保证依赖项全部都可以调取,不然就会报Native library解析失败
错误1:java.lang.UnsatisfiedLinkError:Unable to load library ‘test’: The specified module could not be found.
错误2:java.lang.NoClassDefFoundError: Could not initialize class com.example.demo.Test
错误3:Unload 什么的,这个错误提示没有记录,原因是java项目中调取动态库的路径不对,没有读取到。
三、docker的镜像底包要选择好,windows环境有win/amd64的底包,linux有linux/amd64的底包,在dockerhub上进行相应的底包选择,windows环境下docker容器只能访问dll文件,linux环境下docker容器访问的是so文件,需要注意这一点
1、这里根据自己的环境下载相应的底包。
四、docker的操作指令
镜像操作:
1、去镜像仓库中搜索
docker search openjdk:latest
2、从镜像仓库中拉取
docker pull openjdk:latest
3、查看镜像
docker images
4、信息查看
docker info
5、docker的版本信息
docker version
6、删除镜像
docker rmi openjdk
容器操作:
1、启动容器
docker start 容器ID
2、终止容器
docker stop 容器ID
3、重启容器
docker restart 容器ID
4、暂停容器中所有的进程
docker pause 容器ID
5、重启使用pause命令暂停的容器
docker unpause 容器ID
6、删除一个或多个容器
docker rm -f 容器ID
docker rm -f 容器ID1 容器ID2 容器ID3
7、删除容器并删除挂载的数据卷
docke rm -v 容器ID
8、以交互模式进入容器内部
docker exec -it 容器ID(或容器名称) cmd
docker exec -it 容器ID(或容器名称) /bin/bash
9、输出运行中的容器列表
docker ps
10、输出全部容器列表
docker ps -a
11、获取容器日志
docker logs 容器ID(或容器名称)
12、动态跟踪并查看容器的日志详情
docker logs -tf --details 容器ID(或容器名称)
13、列出指定容器的端口映射
docker port 容器ID
五、dockerfile文件生成docker镜像,基础的语法
组成部分
部分 | 命令 |
---|---|
基础镜像信息 | FROM |
维护者信息 | MAINTAINER |
镜像操作指令 | RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME等 |
容器启动时执行指令 | CMD、ENTRYPOINT |
各命令详解
FROM
指定哪种镜像作为新镜像的基础镜像,如:
FROM openjdk:latest
MAINTAINER
指明该镜像的作者
MAINTAINER xiyue
RUN
在新镜像内部执行的命令,比如安装一些软件、配置一些基础环境,可使用\来换行,如:
RUN vc_redist.x64.exe /install /quiet /log Install_vc_redist_2017_x64.log
RUN Write-Host 'Configuring environment'; \
pushd 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC' ; \
cmd /c 'vcvarsall.bat amd64&set' | foreach { \
if ($_ -match '=') { \
$v = $_.split('='); \
[Environment]::SetEnvironmentVariable($v[0], $v[1], [EnvironmentVariableTarget]::Machine); \
} \
} ; \
popd
COPY
将主机的文件复制到镜像内,如果目的位置不存在,Docker会自动创建所有需要的目录结构,但是它只是单纯的复制,并不会去做文件提取和解压工作。如:
复制文件夹要以/结尾
复制文件不需要
COPY ./ospl.xml C:/
COPY ./external/ C:/external
ADD
将主机的文件复制到镜像中,跟COPY一样,限制条件和使用方式都一样,但是ADD会对压缩文件(tar, gzip, bzip2, etc)做提取和解压操作。
EXPOSE
暴露镜像的端口供主机做映射,启动镜像时,使用-P参数来讲镜像端口与宿主机的随机端口做映射。使用方式(可指定多个):
EXPOSE 8080
EXPOSE 8081
...
WORKDIR
在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录。如:
WORKDIR C:/
VOLUME
用来向基于镜像创建的容器添加卷。比如你可以将mongodb镜像中存储数据的data文件指定为主机的某个文件。(容器内部建议不要存储任何数据),如:
注意:VOLUME 主机目录 容器目录
使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。
VOLUME /data/db /data/configdb
CMD
容器启动时需要执行的命令,如:
CMD vc_redist.x64.exe /install /quiet /log Install_vc_redist_2017_x64.log
ENTRYPOINT
作用和用法和CMD一模一样
CMD和ENTRYPOINT的区别
CMD和ENTRYPOINT同样作为容器启动时执行的命令:
CMD的命令会被 docker run 的命令覆盖而ENTRYPOINT不会
ENV
容器设置环境变量,如:
注意:ENV 环境变量名称=环境变量地址
ENV OSPL_URI=file://C:/ospl.xml
六、关于windows镜像的动态库依赖
1、拉取好了底包,就可以使用底包进行生成镜像操作了,我这里要发布可执行jar,拉取的openjdk镜像,作为底包来生成项目镜像。
2、因为dll动态库需要依赖一些系统的dll依赖项,可以进入镜像内部去查看下C:/Windows下的System32和SysWOW64文件夹下的依赖项,没有这些可以自己找个VC_redist.x64.exe安装到容器里,安装命令就写在dockerfile中,CMD命令就行
七、动态库dll文件及依赖文件过大,可以采用数据卷挂载的方式,一种是采用本地挂载让docker容器调取本地的动态库dll文件,一种是在docker部署一个动态库文件容器作为访问文件服务器
1、本地挂载的方式:
直接run命令:
docker run -d -v C:/test:C:/test -p 8030:8030 --name 容器名称 镜像名称
2、部署一个动态库文件容器作为数据卷,失败。
八、项目生成的镜像与容器目前是一对一的,转为一对多
1、生成一个主镜像,以dockerfile的方式来创建生成,注意dockerfile这里面不要写EXPOSE映射端口了,不然会造成多端口绑定。
2、以这个主镜像,按照不同的启动命令来生成多个镜像,变动命令只需要更改容器名称、映射端口、jar包路径名称即可,注意,jar包是挂载的本地数据卷的路径。
docker run -d -v C:/test:C:/test -p 8030:8030 --name 容器名称 镜像名称 java -Djava.awt.headless=true -Djna.debug_load=true -Dfile.encoding=utf-8 -jar ./SimNodes/sim-display-server-1.0-SNAPSHOT.jar
九、dockerfile生成多个镜像,有缓存cache,可以加快生成
1、在先前进行重复生成镜像时,上传复制文件会有缓存,仅仅第一次生成镜像的时候比较慢,后面上传重复资源镜像的时候就非常快速了。
更多推荐
所有评论(0)