1. 镜像的创建
由容器提交镜像
docker 镜像与容器,使用联合文件技术管理文件。镜像与容器由一层层的layer 文件组装而成。
a、当用镜像模板创建容器时,是直接在镜像的文件层级上,加一层容器读写层
b、反过来,如果想要创建一个新的镜像,直接把容器对应的所有文件层,转为只读层
即可。commit 命令可达到这个效果:
示例
1.创建一个tomcat 容器
向窝其中加入一个war 包:
测试ok
2.要复用这个容器,使用commit 建一个新镜像
查看镜像
使用新的镜像,创建容器
测试容器
2. dockerfile 方式创建容器
虽然使用容器,可以转换成镜像,但不是常规手段。一情况下,我们使用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,请手动安装,脚本如下:
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 镜像得到容器服务了
仓库使用
docker 官方仓库
注册
https://hub.docker.com
自由注册,邮件激活即可使用
命令使用
Docker pull/search/login/push/tag
tag [镜像名:版本] [仓库]/[镜像名:版本]:标记本地镜像,将其归入某一仓库
Push [仓库]/[镜像名:版本]: 推送镜像到仓库–需要登陆
Search [镜像名]:在仓库中查询镜像– 无法查询到tag 版本
Pull [镜像名:版本]: 下载镜像到本地
Login:登陆仓库
1、命令登陆dockerhub
2、再使用tag 命令标记一个镜像,指定自己的仓库
3、使用push 命令推送此镜像到仓库里
4、打开查询自己仓库的镜像
私有仓库
搭建
下载registry 镜像:docker pull registry
-----可配置加速器加速下载
启动
docker run -d --name reg -p 5000:5000 registry
然后可以通过restful 接口查看仓库中的镜像(当前仓库是空的)
配置http 传输
私服默认只能使用https,需要配置开放http
配置完毕重启下docker 服务
systemctl daemon-reload
systemctl restart docker
私服仓库推送镜像
docker tag hello-world 192.168.244.7:5000/hello-world
docker push 192.168.244.7:5000/hello-world
查询镜像:http://192.168.244.5:5000/v2/_catalog
查询hello 版本: http://192.168.244.5:5000/v2/hello/tags/list