接下来,我们要利用Docker部署一个应用程序

我们拿一个Java应用程序为例

我们将SpringBooot打包为一个jar包,并上传到服务器上,打包为一个Docker镜像,并运行起来

我们编写一个SpringBoot,尝试连接Redis进行一些操作

首先就需要我们启动一个Redis

首先是拉取一个Redis的镜像

docker pull redis

拉取完成之后,对于Redis的启动

,需要考虑Redis的持久化问题

图片

上面文字中说明了,我们可以利用-v 进行挂载,讲宿主机上的目录和镜像中的 /data进行映射就可以进行显示

所以我们的启动时候可以加入-v

docker run -d –name myredis -v  /redisdata:/data

而且如果我们想要使用自定义的配置文件,需要考虑两个方面

分别是启动命令 以及 配置文件的挂在

$ docker run -v /myredis/conf:/usr/local/etc/redis –name myredis redis redis-server /usr/local/etc/redis/redis.conf

上面是官方给出的配置文件使用方式

redis redis-server /usr/local/etc/redis/redis.conf即为启动命令

我们可以利用-v挂载一个文件,并在启动命令中指定

我们先创建一个redis.conf

然后-v中进行挂载

-v /data/redis.conf:/etc/redis/redis.conf

然后在启动中制定

redis redis-server /etc/redis/redis.conf

docker run -d –name myredis -v  /redisdata:/data -v /data/redis.conf:/etc/redis/redis.conf -p 6379:6379 redis:latest  redis-server /etc/redis/redis.conf

使用如上命令,我们启动了一个redis

然后我们启动一个相关的Java应用,并将Java应用进行打包部署

关于Java代码的书写就先跳过不表

假设我们已经有了一个Jar包

我们需要将这个Jar包转换为对应的镜像,这就需要一个新的概念,DockerFile

我们将对应的DockerFile进行书写,并利用Docker进行打包,那么我们就讲解如何书写DockerFile

首先是DockerFile的基础层

因为我们需要一个运行环境,对于Java,我们需要使用一个JDK运行环境

于是我们从DockerHub查找对应的JDK运行环境

对应的JDK环境为openjdk:8-jdk-slim

故首先在DockerFile的第一行书写上

FROM openjdk:8-jdk-slim

然后我们讲这个jar包拷贝到这个容器环境中

使用的命令是

COPY target/*.jar   /app.jar

将当前目录下的target目录下的jar包,拷贝为容器环境中的根目录下的app.jar

之后是设置启动命令

ENTRYPOINT [“java”,”-jar”,”/app.jar”]

每一个空格都用逗号分隔

之后就是docker build

整体命令为

docker build -t java-demo:v1.0 .

最后别忘了这个点,为了表明上下文环境为当前的目录

之后就可以启动这个容器来查看了

docker run -d -p 8080:8080 –name myjava-app java-demo:v1.0

关于镜像的上传和分享其实并不困难了

docker login

然后进行改名

docker tag oldname newname

推送到docker hub

docker push newname

其他的机器就可以

docker pull newname

从而进行使用

关于DocekrFile的具体使用,我们展开说说

首先是关于From指令,是一个必要的指令,指定了基础镜像,推荐是使用

apline或者slim这类的小镜像,比如tomcat

图片

其次是选择的镜像要配合应用的环境,Java应用要使用java基础镜像或者tomcat基础镜像

其次是LABEL

用于给镜像打标签

可以给一个镜像打上多个标签

中间使用空格就可以了

诸如

图片

如果需要换行,直接空格加上反斜杠即可

之后我们讲一下ARG 和 ENV两个参数

ARG会定义一个变量,也可以在构建的时候使用–build-arg进行传递,docker build 会传递给构建器

–build-arg会覆盖DockerFile中的同名参数

不给过ARG只会在构建期有效,运行期无效

而且书写的时候不支持同时指定多个

只能一次指定一个

ARG parma=123456

ARG msg=456789

–build-arg也是

之后是ENV命令

用于声明环境变量

图片

推荐使用KEY=VALUE,不推荐使用 KEY Value这种格式

负责给容器运行的时候使用

docker run –env 可以覆盖这些值

ENV为了给容器运行时使用,可以使用docker inspect image查看

需要注意个问题,关于ENV的持久化问题

如果两个ENV变量

ENV msg=ffff

ENV msg2=$msg

那么如果在启动的时候制定了msg为dddd,那么运行的时候环境变量

msg为dddd,msg2为ffff

这是因为,build的时候ENV会生成层,也就是固化,导致的运行时不改变

之后我们说下Run

Run可以配合上面的ARG

在当前的镜像层顶层执行任何命令,并提交结果,生成新的镜像层

可以使用多个RUN命令,来创建不同的镜像层

常见的方式有两种

RUN command

RUN [“exec”,”param1″]

两种是有一定的区别

RUN /bin/bash -c ‘source $HOME/ .bashrc;echo $HOME’

RUN [“/bin/bash”,”-c”,”echo hello”]

记住如果使用[],是不能输出任何变量信息的,直接使用

RUN command,可以输出变量信息

RUN没有上下文联系

CMD和ENTRYPOINT

都是可以作为容器启动的入口

首先是CMD命令

CMD [“exec”,”param1″,”param2″] exec方式

CMD [“param1″,”param2”] 为ENTRYPOINT提供默认参数

CMD command param1 param2 shell形式

只能有一个CMD命令

DockerFile中只有一个CMD指令,如果列出多个CMD,只有最后一个可以执行

CMD主要目的视为执行的容器提供默认值,这种情况下,还必须要制定ENTRYPOINT指令

ADD和COPY

都是将文件加入到镜像中

不过ADD会将远程地址的文件自动下载到镜像中

而且ADD会将压缩包在镜像中解压出来

如果是远程压缩包,并不会自动解压

别忘了ADD后的镜像内路径,如果想放在某个文件夹下,需要在最后加个/

之后是两个目录相关的命令,分别是WORKDIR和VOLUME

对于WORKDIR,是为之后的指令,诸如RUN CMD ENTRYPOINT COPY ADD指令设置一个上下文目录,如果在容器中不存在这个目录,也会被自动的创建

WORKDIR /app

RUN pwd

发现会是 /app

而且会嵌套使用,比如我们如下的使用

WORKDIR /a

WORKDIR b

WORKDIR c

结果是 /a/b/c

关于Volume

主要是讲容器内的某些文件夹映射到容器的外部

常见的写法

VOLUME [“/var/log/”]

VOLUME /var/log

VOLUME /var/log /var/db

但是需要注意一些坑,如果进行了指定VOLUME,但是启动的时候没有指定-v,那么也会在启动之后,挂载对应的卷到一个宿主机上的地方,这是其一

如果在DockerFile的Volume原语后进行了对容器挂载卷的修改,那么所有的修改都不会生效,这是其二

如果修改了Volume相关挂载卷中的文件了,那么即使之后Commit,也不会保存修改

对于DockerFile中的EXPOSE来说

用于对外暴露端口,但是只是一个声明,建议还是在run的时候配合-p指令

如果声明了一个,是会在启动的时候挂载这些随机的端口,但并没有什么用

书写方式如下

EXPOSE <port>

EXPOSE [80,443]

EXPOSE 80/tcp

EXPOSE 80/udp

最重要的士ENTRYPOINT 和 CMD

一个类似是门一样的角色,门是不会变得 Entrypoint

一个类似是口令一样的角色,口令会是变得 CMD

而且CMD和ENTRYPOINT都是只有一个会生效,定义在最后的才会生效

两个配合使用才是最强

基本配合的图标如下所示

图片

一般我们都是使用[]这种的写法

由CMD负责提供参数,由ENTRYPOINT负责实际的执行

就好比 java -jar xxx.jar param

ENTRYPOINT负责执行javar -jar xxx.jar 后面的param

而且CMD得命令还会被docker run 时候传入的arg覆盖比如下面的操作

图片

docker run xxxx 的话,执行的指令就是echo 111

docker run xxxx arg 就是 echo arg

这就是上面两点的配合使用

还有就是多阶段构建的概念

multi-stage builds

进行多阶段构建,每一次的构建基于前一个阶段构建的成果

我们的使用可以如下

首先第一步,构建一个jar包,我们需要使用maven,进行构建

图片

分别是基于maven 镜像

将目录下的java文件拷贝进镜像中,然后进行maven打包

然后我们基于打包好的镜像,在进行一次打包

将上一阶段的jar包拷贝到新的镜像中

图片

–from指的是根据什么镜像,我们基于了上面的builder镜像

进行了COPY

我们还是指定了openjdk的运行环境

然后进行运行/app下的jar包

对于DockerFile的使用和打包

我们给出以下的建议

选项的基础镜像可以相对小的

然后是合并RUN的指令,将多个RUN命令合成一个RUN命令,少生成一些层

对于RUN过程中产生的临时缓存,可以自行删除

RUN mvn….. && rm -rf xxxx

合理使用 .dockerignoe文件,排除上下文中无需构建的资源

必要刻意使用缓存,如果不需要缓存可以使用–no-cache

发表评论

邮箱地址不会被公开。 必填项已用*标注