Docker镜像除了是Docker的核心技术以外也是应用发布的标准格式。一个完整的Docker镜像能够支撑一个Docker容器的运行,在Docker的整个使用过程当中,进入一个已经定型的容器以后,就能够在容器中进行操做,最多见的就是在容器中安装应用服务,若是要把已经 安装的服务进行迁移,就须要把环境以及搭建的服务生成新的镜像。html
建立镜像的方法有三种:web
使用docker commit命令,把一个容器里面运行的程序以及该程序的运行环境打包起来生成新对的镜像。docker
命令格式:docker commit [选项] 容器 ID/ 名称 仓库名称 :[标签]apache
经常使用选项:json
-a :做者信息
-m :说明信息
-p :生成过程当中中止容器的运行vim
[root@localhost ~]# docker ps -a #查看容器的ID CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 06bbfa9e79b8 11426a19f1a2 "/bin/bash" 7 seconds ago Created nostalgic_boyd [root@localhost ~]# docker commit -m "new" -a "daoke" 06bbfa9e79b8 daoke:test #建立新的镜像 sha256:eb0c9295c27a4efc020bc7985476b45a9d2e2cb6d80f4f9d8cdd4d9bcc87b4e1 [root@localhost ~]# docker images #查看镜像的信息 REPOSITORY TAG IMAGE ID CREATED SIZE daoke test eb0c9295c27a 15 seconds ago 178 MB docker.io/httpd latest 11426a19f1a2 12 days ago 178 MB
经过导入操做系统模板文件能够生成镜像,模板能够从OPENVZ开源项目下载,下载地址为http://openvz.org/Download/template/precreatedcentos
使用docker导入命令将下载的debian模板压缩包导入为本地镜像缓存
[root@localhost ~]# wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz [root@localhost ~]# cat debian-7.0-x86-minimal.tar.gz | docker import - daoke:new sha256:528e1b210e8477dafaeb6d76dd7551c8b9906230d2ddaea4d149d6868964cec6 [root@localhost ~]# docker images | grep new #查看新建的镜像信息 daoke new 528e1b210e84 5 minutes ago 215 MB
除了手动删除Docker镜像以外,还可使用Dockerfile自动生成镜像。Dockerfile是由一组指令组成的文件,其中每条指令对应Linux中的一条命令,Docker程序将读取Dockerfile中的指令生成指定镜像。安全
Dockerfile结构大体分为四个部分:基础镜像信息、维护者信息、镜像操做指令和容器启动时执行指令。Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#”号开头的注释。bash
编写Dockerfile的格式要求:
1.创建工做目录
[root@localhost ~]# mkdir apache [root@localhost ~]# cd apache/
2.建立并编写Dockerfile文件
[root@localhost apache]# vim Dockerfile #基于的基础镜像 FROM centos #维护镜像的用户信息 MAINTAINER The porject <cloud-ops@centos.org> #镜像操做指令安装apache软件 RUN yum -y update RUN yum -y install httpd #开启 80 端口 EXPOSE 80 #复制网站首页文件 ADD index.html /var/www/html/index.html #将执行脚本复制到镜像中 ADD run.sh /run.sh RUN chmod 755 /run.sh #启动容器时执行脚本 CMD ["/run.sh"]
3.编写执行脚本
[root@localhost apache]# vim run.sh #!/bin/bash rm -rf /run/httpd/* #清理httpd的缓存 exec /usr/sbin/apachectl -D FOREGROUND #启动apache服务
4.建立测试页面
[root@localhost apache]# echo "web test" > index.html [root@localhost apache]# ls Dockerfile index.html run.sh
5.使用Dockerfile生成镜像
经常使用选项:
-t :指定镜像的标签信息
[root@localhost apache]# docker build -t httpd:centos .
6.使用新的镜像运行容器
将新生成的镜像加载到容器中运行
[root@localhost apache]# docker run -d -p 1216:80 httpd:centos
其中-p选项实现从本地端口1216(自定义)到容器中80端口的映射
[root@localhost ~]# docker run -d -p 1216:80 httpd:centos 773fca3991ff3364783ba6ea58080d50729277bea8a4db024d8797243d80e212
访问容器中的apache服务,如图所示:
7.将镜像上传到仓库中
仓库分为:公有仓库和私有仓库。使用公有仓库下载镜像是不须要注册的较为方便,可是上传就行则须要注册,下载地址是https://hub.docker.com 。使用私有仓库须要在构建私有仓库的服务器上下载registry镜像。
1)下载registry镜像
[root@localhost ~]# docker pull registry 如下是显示下载完成信息 latest: Pulling from docker.io/library/registry 4064ffdc82fe: Pull complete c12c92d1c5a2: Pull complete 4fbc9b6835cc: Pull complete 765973b0f65f: Pull complete 3968771a7c3a: Pull complete Digest: sha256:51bb55f23ef7e25ac9b8313b139a8dd45baa832943c8ad8f7da2ddad6355b3c8 Status: Downloaded newer image for docker.io/registry:latest
2)在/etc/docker目录下建立一个json文件,不然在往自定义的私有仓库中上传镜像是会报错。
[root@localhost ~]# vim /etc/docker/daemon.json { "insecure-registries":["192.168.126.141:5000"]} [root@localhost ~]# systemctl restart docker.service [root@localhost ~]# docker create -it registry /bin/bash #建立容器 0835c45afb5e33135362242347356b65f572198a773e2a3d60f81d938d8b301f root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0835c45afb5e registry "/entrypoint.sh /b..." 8 seconds ago Created upbeat_elion 773fca3991ff httpd:centos "/run.sh" 8 minutes ago Exited (137) About a minute ago pedantic_pasteur 511e945fc770 11426a19f1a2 "/bin/bash" 16 minutes ago Exited (0) About a minute ago ecstatic_hamilton [root@localhost ~]# docker start 0835c45afb5e #开启容器 0835c45afb5e
3)使用下载好的registry镜像启动一个容器,默认状况下仓库存放于容器内的/tmp/registry目录下,使用-v选项能够将本地目录挂载到容器内的/tmp/registry下 使用,这样就不怕容器被删除后镜像也会随之丢失。
[root@localhost ~]# docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry
4)使用docker tag命令将要上传的镜像标记为
[root@localhost ~]# docker tag docker.io/httpd 192.168.126.141:5000/httpd
5)用docker push上传标记的镜像
[root@localhost ~]# docker push 192.168.126.141:5000/httpd The push refers to a repository [192.168.126.141:5000/httpd] 28eaf9ee6b41: Pushed dcaeabd68175: Pushed 94519f51ae61: Pushed 74e07a1c6b07: Pushed 611673f0c323: Pushed f6ff89d562dc: Pushed dd1eb1fd7e08: Pushed latest: digest: sha256:a2eeb4eece5b956cbd6fae9ec2d5f9fd083a197ae6f1ed68ccb01bb034893c65 size: 1780
6)获取私有仓库列表
[root@localhost ~]# curl -XGET http://192.168.126.141:5000/v2/_catalog {"repositories":["httpd"]}
管理Docker容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器(Data volumes Containers)。
数据卷是一个供容器使用的特殊目录,位于容器中,可将宿主机的目录挂载到数据卷上,对数据卷的修改操做马上可见,而且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。
1.建立数据卷
在docker run 命令中使用-v 选项能够在容器内建立数据卷。屡次使用-v能够建立多个数据卷。使用--name选项能够给容器建立一个友好的自定义名称。
1)使用httpd:centos镜像建立一个名为web1的容器,并将宿主机的/var/www目录挂载到容器的/data1目录上,如:
[root@localhost ~]# docker run -v /var/www:/data1 --name web1 -it centos /bin/bash [root@7b584c5f1d20 /]# ls anaconda-post.log bin data1 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
2)在宿主机本地/var/www目录中建立一个文件,进入运行的容器中。在相应的挂载目录下能够看到刚才在宿主机上建立的文件,实现了从宿主机到容器的数据迁移。
[root@localhost ~]# cd /var/www/ [root@localhost www]# ls [root@localhost www]# touch test123 [root@localhost www]# ls test123 [root@localhost www]# docker start 7b584c5f1d20 #启动容器 [root@localhost www]# docker exec -it web1 /bin/bash [root@7b584c5f1d20 /]# cd data1/ [root@7b584c5f1d20 data1]# ls test123
同理在容器数据卷中建立的数据在宿主机相应的挂载目录中也能够访问。
数据卷容器就是一个普通的容器,专门提供数据卷给其余容器挂载使用。
1.建立一个新的数据卷容器为web100,其中所建立的数据卷分别挂载到了/data1与/data2目录上。
[root@localhost www]# docker run --name web100 -v /data1 -v /data2 -it centos /bin/bash [root@ab7632329eee /]# ls anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
2.使用--volumes-from 来挂载web100容器中的数据卷到新的容器,新的容器名为db1。
[root@localhost www]# docker run --name db1 --volumes-from web100 -it centos /bin/bash [root@eb56026f763c /]# ls anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
3.在db1容器数据卷/data2目录中建立一个文件file。在web100容器中的/data2目录中能够查看到文件file。
[root@eb56026f763c /]# cd data2 [root@eb56026f763c data2]# ls [root@eb56026f763c data2]# touch file [root@localhost www]# docker start ab7632329eee #启动web100容器 ab7632329eee [root@localhost www]# docker exec -it ab7632329eee /bin/bash #进入容器 [root@ab7632329eee /]# ls data2/ #数据迁移成功 file
Docker提供了映射容器端口到宿主机和容器互联机制来为容器提供网络服务。
在启动容器的时候,若是不指定对应的端口,在容器外将没法经过网络来访问容器内的服务。Docker提供端口映射机制来将容器内的服务提供给外部网络访问,实质上就是将宿主机的端口映射到容器中,使得外部网络访问主机的端口即可访问容器内的服务。
1.实现端口映射,须要在运行docker run命令时使用-P(大写)选项实现随机映射,Docker会随机映射一个端口范围在49000~49900的端口到容器内部开放的网络端口。
[root@localhost ~]# docker run -d -P httpd:centos 4749e5d0ac4b7b42f74e27e0aebf611ce11fb1f92248751c8e66349f7ada4019
2.查看本机的32768端口是否被映射到了容器中的80端口。
[root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4749e5d0ac4b httpd:centos "/run.sh" 16 seconds ago Up 14 seconds 0.0.0.0:32768->80/tcp romantic_mcclintock
3.还能够在运行docker run命令时使用-p(小写)选项指定要映射的端口,例如:
[root@localhost ~]# docker run -d -p 49280:80 httpd:centos [root@localhost ~]# docker ps -a #端口映射成功 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 17251b86a2b0 httpd:centos "/run.sh" 3 seconds ago Up 1 second 0.0.0.0:49280->80/tcp keen_rosalind
容器互联就是经过容器的名称在容器间创建一条专门的网络通讯隧道从而实现容器的互联。
注意:若是已经命名了一个相同的容器,当要再次使用这个名称时,须要使用docker rm命令删除以前建立的同名容器。
1.建立源容器
使用docker run命令创建容器,使用--name指定容器的名称为web1。
[root@localhost ~]# docker run -P --name web1 -it httpd:centos /bin/bash [root@localhost ~]# docker start ec056f796f5c #开启容器web1 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ec056f796f5c httpd:centos "/bin/bash" 8 minutes ago Up 5 minutes 0.0.0.0:32771->80/tcp web1 .....//省略
2.建立接收容器
使用docker run命令创建容器,使用--name指定容器的名称为web2,使用--link指定链接容器以实现容器互联。
[root@localhost ~]# docker run -P --name web2 --link web1:web1 -it httpd:centos /bin/bash [root@localhost ~]# docker start 853da4a8f368 #开启容器web2 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 853da4a8f368 httpd:centos "/bin/bash" 6 minutes ago Up 3 minutes 0.0.0.0:32774->80/tcp web2 .....//省略
3.测试容器互联
进入容器web2中,使用ping命令查看容器web2是否能互相连通。
[root@localhost ~]# docker exec -it 853da4a8f368 /bin/bash [root@853da4a8f368 /]# ping web1 PING web1 (172.17.0.3) 56(84) bytes of data. 64 bytes from web1 (172.17.0.3): icmp_seq=1 ttl=64 time=0.282 ms 64 bytes from web1 (172.17.0.3): icmp_seq=2 ttl=64 time=0.118 ms 64 bytes from web1 (172.17.0.3): icmp_seq=3 ttl=64 time=0.121 ms 64 bytes from web1 (172.17.0.3): icmp_seq=4 ttl=64 time=0.118 ms ^C --- web1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 0.118/0.159/0.282/0.072 ms
此时/能够看到容器web2与容器web1已经创建互联关系。Docker在两个互联的容器之间建立了一条安全隧道,并且不用映射它们的端口到宿主机上,从而避免暴露端口给外部网络。