Docker 创建镜像(二)
今天我们分析doker镜像的创建过程:
镜像的创建
由容器提交镜像
docker 镜像与容器,使用联合文件技术管理文件。 镜像与容器由一层层的 layer 文件组装而成,如下图:
a 、当用镜像模板创建容器时,是直接在镜像的文件层级上,加一层容器读写层
b 、反过来,如果想要创建一个新的镜像,直接把容器对应的所有文件层,转为只读层 即可。commit 命令可达到这个效果:
示例
- 创建一个 tomcat 容器
向窝其中加入一个 war 包:
测试 ok
- 要复用这个容器,使用 commit 建一个新镜像
查看镜像
使用新的镜像,创建容器
测试容器
dockerfile 方式创建容器
虽然使用容器,可以转换成镜像,但不是常规手段。 一情况下,我们使用 dockerfile 方式 最简单的 dockerfile
创建镜像
使用此镜像运行一个容器
dockerfile 指令
FROM :
FROM {base 镜像 } 必须放在 DOckerfile 的第一行,表示从哪个 baseimage 开始构建
MAINTAINER :
可选的,用来标识 image 作者的地方
RUN
RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。 第一层 RUN command1 的执行仅仅是当前进程,一个内存上的变化而已,其结果不会造 成任何文件。 而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能 继承前一层构建过程中的内存变化。 而如果需要将两条命令或者多条命令联合起来执行需要加上&&。 如:cd /usr/local/src && wget xxxxxxx
CMD :
CMD 的作用是作为执行 container 时候的默认行为(容器默认的启动命令) 当运行 container 的时候声明了 command ,则不再用 image 中的 CMD 默认所定义 的命令一个 Dockerfile 中只能有一个有效的 CMD ,当定义多个 CMD 的时候,只有最后一个才会 起作用
EXPOSE
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个 声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助 镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机 端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
entrypoint :
entrypoint 的作用是,把整个 container 变成可执行的文件,且不能够通过替换 CMD 的方 法来改变创建 container 的方式。但是可以通过参数传递的方法影响到 container 内部 每个 Dockerfile 只能够包含一个 entrypoint ,多个 entrypoint 只有最后一个有效 当定义了 entrypoint 以后, CMD 只能够作为参数进行传递
ADD & COPY :
把 host 上的文件或者目录复制到 image 中(能够进行自动解压压缩包)
ENV :
用来设置环境变量,后续的 RUN 可以使用它所创建的环境变量
WORKDIR :
用来指定当前工作目录(或者称为当前目录)
USER :
运行 RUN 指令的用户
VOLUME :
用来创建一个在 image 之外的 mount point
docker 容器的主业
docker 理念里,容器启动时,应当为它指定主业是什么,如 nginx 容器主业就是 nginx 代理服务,tomcat 容器就是 web 服务等等
1 、容器创建时,必须指定主业任务,如不指定,则容器无事可干立即退出。
2 、在 dockerfile 打包镜像时,可以使用 cmd 命令来指定一个默认的主业,如下:
3、既然镜像里是默认主业,即意味着创建容器时,可以覆盖此默认命令,如下
推荐的 ENTRYPOINT 方式
1 、镜像本身应该有稳定的主业,应当指定后即不能更改用途,于是引入 ENTRYPOINT
2 、使用 ENTRYPOINT 字义即容器入口,它不能被 run 中 cmd 覆盖,如下例:
执行: docker build -t nginxx:v3 .
以后使用 nginxx:v3 这个镜像时,只能做 nginx 服务来使用啦
回到我们前面的 tomcat 例子:
创建:
起新容器,查看容器日志
可以看到命令已经更改如果此时,再用 echo 命令去覆盖容器,发现不能成功
echo 命令被当作参数付给 entrypoint 指令
手动打包 springboot 镜像
我们需要对业务项目打包发布,一样需要制作成为业务镜像,供运维使用,下面讲述 springboot 的制作过程:
1 、将 springboot 打好的 jar 包上传
2 、在同级目录下,创建 Dockerfile 文件,内容如下:
3 、 dockerfile 打包业务镜像
4、启动镜像,即得到业务运行
docker run -d -p 8090:8090 —name member member:v1
5 、浏览器打开页面校验: http://192.168.244.7:8090/
maven 源码打包用法
更多的情况,我们是直接在运维环境里,上传源码,直接 maven 打包 jar ,然后再进一 步打包成镜像,与手动打包过程类似 如果环境中没有安装 maven ,请手动安装,脚本如下:
sudo yum install -y yum-utils # yum-config-manager —add-repo http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-ap ache-maven.repo # yum-config-manager —enable epel-apache-maven // 安装 maven # yum install -y apache-maven
1 、上传原码到 docker 环境中(一般是 git/svn 直接拉取源码)
2 、 maven 打包
mvn clean package
生成的 jar 在同级 target 目录下
3 、执行 docker 命令生成镜像 dockerfile 文件内容
命令创建镜像
maven 插件打包
前面打 springboot 包的方式,需要手动上传项目 jar 或者源码到服务器(违和感很强), 这对于开发人员日常发布开发环境项目,极为不便 下面,演示一个 maven 插件: docker-maven-plugin 用法 ,来打通环境。
项目环境配置 maven 插件
在我们的工程 pom 中加入 docker-maven-plugin 插件的配置,如下
现在,我们可以使用 mvn 命令,直接编译项目,打包镜像了 mvn clean package docker:build
至此,我们的服务器环境,已经可以直接运行 docker run 镜像得到容器服务了。
还没有评论,来说两句吧...