持续集成--使用dockerfile构建docker镜像
来源:互联网 发布:读单词软件 日语 编辑:程序博客网 时间:2024/06/07 22:10
一、使用dockerfile构建docker镜像优势
1、简化了镜像的构建过程
2、便于版本控制
二、Dockerfile基本结构
1、基础镜像信息
2、维护者信息
3、镜像操作指令
4、容器启动时执行指令
三、Dockerfile常用指令
1、FROM
获取基础镜像
格式:FROM <image>或FROM <image>:<tag>
例子:FROM docker私服/decision/java:8
注意:
♦ 当不写tag时,相当于拉取的镜像的最新版本(latest版本)
♦ 先从本地查找,本地没有则从docker hub上拉取
♦ 必须是非注释命令的第一个命令
♦ 可以在dockerfile中出现多次
2、MAINTAINER
镜像制作者
格式:MAINTAINER <name>
例子:MAINTAINER XXXXX <XXXXX@XXX.com>
3、RUN
构建指令,可以运行任何被基础镜像支持的命令。
格式:RUN <command> 或 RUN ["executable", "param1", "param2"]
例子:RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
注意:
♦ 每条RUN指令将在当前镜像基础上执行指定命令,并commit为新的镜像,后续的RUN都是在该层镜像上执行的。
♦ RUN产生的缓存在下一次构建时是不会失效的,可通过docker build --no-cache解决
♦ 将长的或复杂的RUN语句用反斜杠\分割成多行
♦ 使用缓存
♦ 不使用缓存
♦ 使用缓存与不使用缓存时间对比
4、CMD
启动容器时提供一个默认的命令执行选项。如果用户启动容器时指定了运行的命令,则覆盖CMD指定的命令。
格式:CMD ["executable","param1","param2"] 或 CMD ["param1","param2"] 或 CMD command param1 param2
例子:
注意:
♦ CMD命令只有一个,如果有多个则最后一条生效
♦ CMD只在启动容器时执行,build时不执行,而RUN只是在build时执行,后续启动容器时与RUN无关
5、EXPOSE
Docker服务端容器对外映射的本地端口,需要在docker run的时候使用-p或者-P选项生效
格式:EXPOSE <port> [<port>...]
例子:EXPOSE 8080
6、ENV
设置环境变量
格式:ENV <key> <value> 或 ENV <key>=<value>
例子:ENV v1="zhangsan" v2="lisi"
ENV v1 zhangsan
ENV v2 lisi
注意:
♦ 该环境变量不能被CMD命令使用
♦ 设置了后,后续的RUN命令都可以使用,当运行生成的镜像时这些环境变量已然有效,如果需要在运行时更改这些环境变量,可以在运行docker run时添加-e <key>=<value>参数来修改
7、ADD
复制本地主机文件、目录或者远程文件URLS并添加到容器指定路径中
格式:ADD <src>... <dest>
例子:ADD run.sh /test
ADD http://example.com/foobar /
注意:
♦ <dest>路径必须是绝对路径,如果路径不存在,会自动创建对应目录
♦ <src>路径必须是Dockerfile所在路径的相对路径
♦ 如果<src>路径是一个目录,则只会拷贝该目录下的内容,目录本身不会拷贝
♦ ADD只有在build镜像的时候运行一次,后面运行container的时候不会再重新加载,也就是你不能在运行时通过这种方式向容器中传送文件
♦ 支持自动解压tar文件,会先将tar文件解压,然后将解压后的文件COPY到<dest>目录下
8、COPY
复制文件或者目录并且添加到容器指定路径中
格式:COPY <src>... <dest>
例子:ADD run.sh /test
注意:
♦ 用法同ADD,唯一不同的是不能指定远程文件URLS
♦ 不支持tar文件的自动解压
9、ENTRYPOINT
容器启动后执行的命令
格式:ENTRYPOINT command param1 param2 或 ENTRYPOINT ["executable", "param1", "param2"]
例子:ENTRYPOINT java -Dspring.profiles.active="config,$env" -Dserver.port=${PORT0} -server -Xmx2g -Xms2g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Xss2048k -XX:+DisableExplicitGC -XX:+UseG1GC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -jar /XXXX-server-$env.jar
注意:
♦ 配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖,而CMD是可以被覆盖的。如果需要覆盖,则可以使用docker run --entrypoint选项
♦ 每个dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效。
10、VOLUME
持久化数据或共享容器间数据
格式:VOLUME ["/data"]
例子:docker run -d -P 3306:3306 --name test -v 宿主机数据目录:容器中数据目录
注意:
♦ 可通过docker run 挂载,也可在dockerfile中挂载
♦ 可指定共享文件的镜像来源 --volume-form
11、USER
指定运行容器时的用户名或UID,后续的RUN、CMD、 ENTRYPOINT也会使用指定用户
格式:USER <user>[:<group>] 或 USER <UID>[:<GID>]
注意:默认为root用户
12、WORKDIR
为后续的RUN、CMD、 ENTRYPOINT指令配置工作目录。
格式:WORKDIR /path/to/workdir
例子:
WORKDIR /aWORKDIR bWORKDIR cRUN pwd
输出:/a/b/c
注意:
♦ 可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于命令指之前指定的路径。
13、ONBUILD
配置当所创建的镜像作为其他新创建镜像的基础镜像时,所执行的操作命令。
格式:ONBUILD [INSTRUCTION]
例子:
[...]ONBUILD ADD . /app/srcONBUILD RUN /usr/local/bin/python-build --dir /app/src[...]
注意:
♦ 该指令后的命令在使用当前dockerfile创建的镜像A里不执行
♦ 该指令在基于镜像A创建的镜像B运行时才会执行
♦ ONBUILD中定义的指令会在用于生成B镜像的Dockerfile文件的FROM指令之后被执行,可以用来执行一些因为环境而变化的操作,使镜像更加通用。
♦ 如果ONBUILD中的任何一个指令执行失败,则会使FROM指令中断并导致整个BUILD失败。
四、根据Dockerfile创建镜像
1、构建镜像
docker build -t imagename --file dockerfile ./
注意:
运行docker build时,整个构建过程如下:
♦ 读取按照赵顺序ckerfile文件发送到docker daemon
♦ 读取当前目录的所有文件(context),发送到docker daemon
♦ 对dockerfile进行解析,处理成命令加上对应参数结构
♦ 按照顺序循环遍历所有命令,对每个命令调用对应的处理函数进行处理
♦ 每个命令(除了FROM)都会在一个容器执行,执行结果会生成一个新的镜像,为最后生成的镜像打上标签
2、登录docker私服
docker login -u username -p password -e email docker私服地址
3、将镜像推到私服
docker push imagename
4、删除本地镜像
docker rmi imagename
5、运行镜像
docker run -d -p 3306:3306 <image>:<tag>
6、进入镜像
docker exec -it <containerid> /bin/bash
五、编写dockerfile的最佳实践
1、使用统一的基础镜像
2、动静分离。经常变化的内容和基本不会变化的内容分开,把不怎么变化的内容放在下层,创建出来不同基础镜像供上层使用。例如可以创建各种语言的基础镜像,在每个基础镜像的基础上继续构建应用级别的镜像。
3、最小原则。只安装必须的东西,因为镜像扩展容易,并且容器运行会很快
4、一个原则:每个镜像只有一个功能。
不要在容器里运行 多个不同功能的进程,每个镜像中只安装一个应用的软件包和文件,需要交互的程序通过容器之间的网络进行交流。这样可以保证模块化,不同的应用可以分开维护和升级,也能减小单个镜像的大小。
5、使用更少的层:尽量把相关内容放到同一个层,使用换行符进行分割, 这样可以进一步减小镜像大小,并且方便查看镜像历史。
6、不要在Dockerfile中单独修改文件的权限。
因为docker镜像是分层的,任何修改都会新增一个层,修改文件或者目录权限也是如此,如果有一个命令单独修改大文件或者目录的权限,会把这些文件复制一份,这样很容易导致镜像很大。
解决方案:
1)添加到Dockerfile之前就把文件的权限和用户设置好
2)容器启动脚本(entrypoint)做这些修改,或者拷贝文件和修改权限放在一起做(这样最终也只是增加一层)
7、利用cache来加快构建速度
如果Docker发现某个层已经存在了,它会直接使用已经存在的层,而不会重新运行一次。
8、版本控制和自动构建
最好把dockerfile和赌赢的应用代码一起放到版本控制中,然后能够自动构建镜像。这样的好处是可以追踪各个版本镜像的内容,方便了解不同镜像的区别,对于调试和回滚都有好处。
另外,如果运行镜像的参数或者环境变量很多,也要有对应的文档给予说明,并且文档要随着dockerfile变化而更新,这样任何人都能参考文档更容易的使用镜像,而不是下载了镜像不知道怎么用。
9、使用.dockerignore文件
在大部分情况下,最好的做法是将每一个Dockerfile文件放到一个空的文件夹里。接着把构建dockerfile所需的文件都添加到这个文件下。为了提高构建效率,可以在这个文件下添加一个.dockerignore文件来排除那些没用的文件和文件夹。
六、实际应用
1、以Python为开发语言的项目部署
dockerfile如下:
jenkins pipeline如下:
2、部署tomcat应用
步骤一:创建Dockerfile,index.jsp
Dockerfile:
index.jsp:
步骤二:通过Dockerfile创建tomcat镜像
docker build -t tomcat ./
步骤三:运行镜像
docker images
docker run -it -P tomcat:latest
步骤四:访问index.jsp
docker ps
http://ip:32778/index.jsp
- 持续集成--使用dockerfile构建docker镜像
- Docker-- 如何使用Dockerfile构建镜像
- 如何使用Dockerfile构建Docker镜像
- Docker-Dockerfile构建镜像
- docker 镜像构建Dockerfile
- Docker镜像构建-Dockerfile
- Docker--docker使用及自定义Dockerfile构建镜像
- 持续集成:docker下使用jenkins容器构建docker镜像
- Docker学习6 - 使用Dockerfile构建镜像
- docker学习笔记4.1-使用Dockerfile文件构建镜像
- docker学习笔记(六)使用Dockerfile构建镜像
- Docker系列~使用Dockerfile构建镜像(三)
- docker筑基篇-04-使用Dockerfile构建自己的镜像
- Docker使用Dockerfile构建微服务发现镜像实例
- Docker学习笔记-- 如何使用Dockerfile构建镜像
- DockerFile方式构建docker镜像
- 使用Dockerfile构建镜像
- 使用Dockerfile创建docker镜像
- AngularJS的增删改查+路由
- 德雷福斯模型
- 通过Spring Session实现新一代的Session管理
- 打开项目报[无法加载或初始化请求的服务提供程序]错误
- 负载均衡的基本算法
- 持续集成--使用dockerfile构建docker镜像
- 23种设计模式(14):解释器模式
- 运动相机检测无人机-- Detecting Flying Objects using a Single Moving Camera
- 多条目练习
- E40关闭硬件报警,即操作系统右下角的声音已经关了,但是有时候(如从睡眠恢复)也还是会有声音,很烦,怎么关闭
- java.lang.NoClassDefFoundError: javax/xml/rpc/Service
- iOS 之适配字体的几中方法
- xbanner无限轮播
- 生成正数的指定位数随机数