本次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、在先前进行重复生成镜像时,上传复制文件会有缓存,仅仅第一次生成镜像的时候比较慢,后面上传重复资源镜像的时候就非常快速了。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐