上篇文章引入了Docker的基本原理和操做,本节文章主要介绍如何制做Docker镜像和发布。java
Docker镜像的本质是一系列文件的集合,这些文件依次叠加,造成了最后的镜像文件,相似于下图所示的结构,linux
从底层往上,依次是文件系统层,操做系统层,专有镜像层,读写层。nginx
启动文件层:Docker启动时的用到的文件系统,启动完成后会自动脱离,用户不会与这一层直接打交道。docker
操做系统层:这一层主要是操做系统相关的一些文件,根据发行版本的不一样,可能有CentsOS、Ubuntu等等。文件包含dev,/proc,/bin,/etc 等目录, 是一个最小化的操做系统,不少工具都没有提供,包括vi、wget、curl等。注意这一层不包含linux内核,只是可在任何知足要求的linux内核上运行。shell
专有镜像层:通常各大软件都会基于上面两层制做专有的镜像,好比nginx、tomcat等,都有专门的官方镜像,能够直接在docker hub上下载。ubuntu
读写层:这是咱们制做本身的镜像时须要操做的层,是一个动态的运行环境,在后续镜像制做中的好比ENV, Volume,cmd等操做最终落实到此运行环境中。centos
制做镜像的实质就是修改读写层。当须要修改镜像内的某个文件时,只对处于最上方的读写层进行了变更,不复写下层已有文件系统的内容,已有文件在只读层中的原始版本仍然存在,但会被读写层中的新版本文件所隐藏,当 docker commit 这个修改过的容器文件系统为一个新的镜像时,保存的内容仅为最上层读写文件系统中被更新过的文件。tomcat
能够经过history命令查看镜像层,bash
制做镜像有两种通用的方法,第一种是直接经过配置好的Container来生成镜像;另一种是经过Dockerfile的方式,基于已有的镜像来生成新的镜像,这种方法更为经常使用。网络
这里以制做nginx的镜像为例,介绍整个制做流程。
1)下载基础镜像,这里以Ubuntu做为基础镜像。因为本地没有镜像能够先利用docker search
获取官方镜像的名称,而后docker pull
将镜像下载到本地。
2)以交互方式启动镜像,方便在容器中安装软件。-it
表示交互方式,/bin/bash
为指定启动的终端。下图能够看到已经成功进入到容器内部了。
docker run -it ubuntu:latest /bin/bash
复制代码
3)如今按照Nginx正常的安装流程安装便可,因为Ubuntu镜像只是一个最小化的系统,可能你须要经过apt-get install
来安装一些须要的软件。
4)退出容器,使用commit指令生成新的镜像。
注意退出容器的时候,也有两种方法,一般直接exit就能够,可是这样容器也会关闭。若是不想关闭容器,只是退出终端,可使用Ctrl+P+Q快捷键,此时退出后,容器依然在后台运行。
直接运行docker commit
同时指定容器id或者name,以及镜像名就能够了,新的镜像制做完成了。
docker commit e0c618df0979 ubuntu-nginx
复制代码
接下来能够经过正常的方式启动镜像了。
上面介绍了手动进入容器内部,制做Docker镜像的方式,通常比较繁琐。一般咱们会使用Dockerfile的方式制做镜像,这种方式下咱们须要编写Dockerfile文件。
Dockerfile是一个文本格式的配置文件,用户可使用Dockerfile快速建立自定义镜像。
下面是一个简单的Dockerfile文件,先将编译生成的jar文件复制到容器,而后声明容器暴露的端口,最后指定在启动容器时须要运行的指令。
FROM openjdk:8
ADD ["target/bazaar-1.0.0.jar", "bazaar.jar"]
EXPOSE 1234
ENTRYPOINT ["java", "-jar", "/bazaar.jar"]
复制代码
Dockerfile中经常使用的指令集有:
比较复杂的是CMD与ENTRYPOINT的对比,二者均可以运行指令,可是稍有不一样。
(1) CMD单独使用
FROM debian:wheezy
CMD ["/bin/ping", "localhost"]
复制代码
启动后不指定任何参数,将会ping localhost,
$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms
复制代码
可是若是启动容器的同时带有新的指令,则原有的CMD会被新的指令覆盖,
docker run -it test bash
root@e8bb7249b843:/#
复制代码
(2)CMD和ENTRYPOINT同时使用
CMD一般用做传递参数给ENTRYPOINT,以下例子所示:
FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]
复制代码
直接运行镜像并不指定任何参数,将会一直ping localhost
$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms
复制代码
若是直接运行的同时,指定一个参数,将会ping对应的参数,此时CMD被覆盖。
$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms
复制代码
若是你想要制做的容器更加通用一些,能够在Dockerfile中使用
CMD ["/path/dedicated_command"]
,这样你能够在运行容器的同时,根据需求来覆盖已有的指令。
上面介绍了Dockerfile中经常使用的指令,通常咱们写好Dockerfile以后,直接进入到Dockerfile所在的目录,运行docker build便可,Docker会根据Dockerfile中指定的步骤来生成咱们的镜像。
$ docker build -t your_image_name .
复制代码
以上就是制做镜像的全部流程,接下来介绍镜像的发布。
镜像发布有两种选择,能够直接push到官方的docker hub,你只须要注册一个docker帐号便可;也能够本身在本地建立私有仓库,将镜像push这里。
打开 hub.docker.com/ 注册好帐户后,记住好本身的帐户名,待会须要将本地的镜像打tag带上用户名,而后进行push。
首先使用以下的指令就给本地镜像打tag,
docker tag myImage:v1 your_user_name/myImage:v1
复制代码
接下来直接push就行,会自动push到官方仓库,注意可能会须要docker login
一下,这里直接输入用户名密码便可。
docker push your_user_name/myImage:v1
复制代码
这样官方仓库就有你的Image了, 之后直接docker pull就好了。
(1) 首先下载registry镜像:docker pull registry.
(2) 接着在5000端口启动,docker run -d --name reg -p 5000:5000 registry.
(3) 配置http传输,私服默认只能使用https,须要配置开放http.
以centos上的配置为例,
注意图中的ip根据实际registry的ip来进行设置,能够经过docker inspect reg来找到。
配置完毕重启下docker服务
systemctl daemon-reload
systemctl restart docker
复制代码
以上就完成了私有仓库的建立。
接下来直接push Image到仓库便可,流程和push到官方仓库相似,只是打tag的用户名改为私有仓库的地址。
(1)打tag
docker tag hello-world http://192.168.244.7:5000/hello-world
复制代码
(2)push镜像
docker push 192.168.244.7:5000/hello-world
复制代码
(3)查询镜像:
(4)查询镜像版本:
以上就是镜像制做和发布的所有内容,下节会介绍实际部署中,docker-compose的使用以及docker的网络通讯。
参考连接: