教你docker镜像的创建超详细!

一.Docker镜像简介

Docker的镜像概念类似于虚拟机里的镜像,是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了Mysql或用户需要的其它应用程序。

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统被称为UnionFS。镜像可以基于Dockerfile构建,Dockerfile是一个描述文件,里面包含若干条命令,每条命令都会对基础文件系统创建新的层次结构。

Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。

二.Docker镜像的分层

 

 

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。分层时有文件更新直接替换,基础镜像一样时直接拿过来复用。

  • Dockerfile中的每个指令都会创建一个新的镜像层
  • 镜像层将被缓存和复用
  • 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效
  • 某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效
  • 镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件
     

优点:

最大的一个好处就是 - 共享资源

 比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,

同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

三.Docker镜像的创建方法

  • 基于已有镜像创建
  • 基于本地模板创建
  • 基于Dockerfile创建

基于已有镜像创建

将容器里面运行的程序及运行环境打包生成新的镜像


docker commit [选项]容器ID/名称仓库名称:[标签]
●-m 说明信息
●-a  作者信息
●-p  生成过程中停止容器的运行

基于本地模板创建  

 

  • 通过导入操作系统模板文件生成新的镜像
  • 使用wget命令导入为本地镜像

wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz 


导入成功后可查看本地镜像信息


docker images | grep new

基于Dockerfile创建

Dockerfile是由一组指令组成的文件

Dockerfile结构四部分

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时执行指令

Dockerfile每行支持一条指令,每条指令可以携带多个参数,支持使用以#开头的注释

Dockerfile操作指令
 

指令含义
FROM镜像指定新镜像所基于的镜像,第一条指令必须为FROM指令 ,
每创建一个镜像就需要一 条FROM指令。
MAINTAINER名字说明新镜像的维护人信息
 
CMD[”要运行的程序",”参数1,
“参数2 "]
指令启动容器时要运行的命令或者脚本,Dockerfile只能有 -条CMD命令,如果指定多条则只能最后一条被执行
EXPOSE端口号指定新镜像加载到Docker时要开启的端口
ENV环境变量变量值设置一个环境变量的值,会被后面的RUN使用
ADD源文件/目录目标文件/目录将源文件复制到目标文件,源文件要与Dockerfile位于相同 目录中,或者是一个URL
COPY源文件/目录目标文件/目录将本地主机上的文件/目录复制到目标地点,源文件/目录要 与Dockerfile在相同的目录中
VOLUME[“目录"]在容器中创建一个挂载点
USER用户名/UID指定运行容器时的用户
WORKDIR路径为后续的RUN、CMD、ENTRYPOINT指定工作目录
ONBUILD命令指定所生成的镜像作为一个基础镜像时所要运行的命令
HEALTHCHECK健康检查
RUN命令在所基于的镜像上执行命令,并提交到新的镜像中

四.案例

1.基于已有镜像创建

[root@localhost ~]# docker create -it centos:7 /bin/bash
9ab4a4428d6b5124f414c19a0e6a5f547e513c2e4d48174f95f07a0ffe0ae771
[root@localhost ~]# docker ps -a ##查看容器
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                         PORTS               NAMES
9ab4a4428d6b        centos:7            "/bin/bash"         6 seconds ago       Created  
[root@localhost ~]# docker commit -m "new" -a "moont" 9ab4a4428d6b moont:new
sha256:d1dedd58021ececfff93b16e2d6d68c337ce0f0dbc54a6d7fb3a797736368e4b
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
moont               new                 d1dedd58021e        33 seconds ago      204MB
nginx               moon                3a23aa75b84b        22 hours ago        131MB
tomcat              latest              e0bd8b34b4ea        7 days ago          649MB
centos              7                   8652b9f0cb4c        12 days ago         204MB

注:推荐先停止容器再进行创建

[root@localhost ~]# docker commit -m "new" -a "moont1" -p 9ab4a4428d6b moont1:new

基于本地模板创建

[root@localhost ~]# cat debian-7.0-x86-minimal.tar.gz | docker import - tes:jac
sha256:73c00fb16e312cf973e4815390081fb74d12ba6fbe8b55bc67eed0d3cb22c33b
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tes                 jac                 73c00fb16e31        18 seconds ago      215MB

基于Dockerfile创建

[root@localhost ~]# mkdir apache
[root@localhost ~]# cd apache/
[root@localhost apache]# vim Dockerfile

FROM centos:7           ##基于的基础镜像
MAINTAINER This is my home  ## 维护镜像的用户信息
RUN yum -y update       ##更新yum
RUN yum -y install httpd  ##安装apache
EXPOSE 80               ##开启80端口
ADD index.html /var/www/html/index.html ##复制网站首页文件
ADD run.sh /run.sh      ##将执行的脚步复制到镜像中
RUN chmod 755 /run.sh   ##给脚本运行权限
CMD ["/run.sh"]         ##启动容器时执行脚本

[root@localhost apache]# vim run.sh

#!/bin/bash
rm -rf /run/httpd/*
exec /usr/sbin/apachectl -D FOREGROUND

[root@localhost apache]# docker build -t httpd:centos .  ##生成镜像
[root@localhost apache]# docker run -d -p 1216:80 httpd:centos  ##新镜像运行容器
a7fb96c19a1b4aead2b57e85ea18e279ef61f0de2574f6e31ec6c302f2016f61
[root@localhost apache]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS                  NAMES
a7fb96c19a1b        httpd:centos        "/run.sh"           57 seconds ago      Up 56 seconds            0.0.0.0:1216->80/tcp   hungry_villani

测试

私有仓库

 

私有仓库优点

  • 节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可;
  • 提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。

搭建私有仓库

[root@localhost apache]# docker pull registry ##下载registry
[root@localhost apache]# vim /etc/docker/daemon.json 

{
  "insecure-registries": ["192.168.100.13:5000"],
  "registry-mirrors": ["https://wy3fhvf9.mirror.aliyuncs.com"]
}

[root@localhost apache]# systemctl restart docker.service  ##重启docker服务
[root@localhost apache]# docker create -it registry /bin/bash ##创建容器

启动私有仓库服务

[root@localhost apache]# docker run -d -p 5000:5000 registry
65b1c4d2f54e380477d609ed116700ecd9510eb1f003ad938ae2caf805da6621
[root@localhost apache]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS                    NAMES
65b1c4d2f54e        registry            "/entrypoint.sh /etc…"   3 seconds ago       Up 2 seconds                  0.0.0.0:5000->5000/tcp   fervent_khayyam

将宿主机的/data/registry自动创建挂载容器中的/tmp/registry

[root@localhost apache]# docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry
ef1d5b36337a511de8a2cdd85aa03b0bbfff52c8a1047958e544a086ee67d55b
[root@localhost apache]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS                   NAMES
ef1d5b36337a        registry            "/entrypoint.sh /etc…"   10 seconds ago      Up 9 seconds                  0.0.0.0:500->5000/tcp   nice_yalow

更改标记为192.168.100.13:5000/abc

[root@localhost ~]# docker tag tes:jac 192.168.100.13:5000/abc
[root@localhost ~]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
192.168.100.13:5000/abc   latest              73c00fb16e31        2 hours ago         215MB

上传镜像至私有仓库

[root@localhost ~]# docker push 192.168.100.13:5000/abc
The push refers to repository [192.168.100.13:5000/abc]
3a1d67a7fe13: Pushed 
latest: digest: sha256:84ae9235ab88049a0de4a1cc8ade7af198c16acf031048d9f33278d1627bd84d size: 528
[root@localhost ~]# curl -XGET http://192.168.100.13:5000/v2/_catalog
{"repositories":["abc"]}

私有仓库下载镜像

[root@localhost ~]# docker pull 192.168.100.13:5000/abc
Using default tag: latest
latest: Pulling from abc
Digest: sha256:84ae9235ab88049a0de4a1cc8ade7af198c16acf031048d9f33278d1627bd84d
Status: Image is up to date for 192.168.100.13:5000/abc:latest
192.168.100.13:5000/abc:latest

 创建数据卷

[root@localhost ~]# docker run -v /var/www:/data1 --name web1 -it centos:7 /bin/bash
[root@75aa9eafde42 /]# ll
total 12
-rw-r--r--.   1 root root 12114 Nov 13 01:55 anaconda-post.log
lrwxrwxrwx.   1 root root     7 Nov 13 01:53 bin -> usr/bin
drwxr-xr-x.   2 root root     6 Nov 26 09:27 data1  ##数据卷

测试

[root@75aa9eafde42 /]# cd /data1/
[root@75aa9eafde42 data1]# touch once  ##数据卷下创建文件
[root@75aa9eafde42 data1]# ll
total 0
-rw-r--r--. 1 root root 0 Nov 26 09:29 once

[root@localhost ~]# ll /var/www/    ##宿主机上查看已同步
总用量 0
-rw-r--r--. 1 root root 0 11月 26 17:29 once

数据卷容器

使用背景

生产环境中使用Docker的过程中,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作。

容器中管理数据主要有两种方式:

  1. 数据卷(Data Volumes):容器内数据直接映射到本地主机环境;如何在容器内创建数据卷,并且把本地的目录或文件挂载到容器内的数据卷中。
  2. 数据卷容器(Data Volume Containers):使用特定容器维护数据卷。如何使用数据卷容器在容器和主机、容器和容器之间共享数据,并实现数据的备份和恢复。

案例实操

运行容器boss并建立俩个数据卷

[root@localhost ~]# docker run --name boss -v /data1 -v /data2 -it centos:7 /bin/bash

数据卷下创建俩个文件测试

[root@8fa060d8b40a /]# touch /data1/gg          
[root@8fa060d8b40a /]# touch /data2/gg

运行容器xiye并挂载boss数据卷

[root@localhost ~]# docker run -it --volumes-from boss --name xiye centos:7 /bin/bash
[root@63eee77e18b0 /]# ll /data1  ##发现文件已经同步
total 0
-rw-r--r--. 1 root root 0 Nov 26 09:37 gg
[root@63eee77e18b0 /]# ll /data2
total 0
-rw-r--r--. 1 root root 0 Nov 26 09:37 gg

容器互联

[root@localhost ~]# docker run -itd -P --name boss1 centos:7 /bin/bash   ##创建并运行容器boss1

[root@localhost ~]# docker run -itd -P --name boss2 --link boss1:boss1 centos:7 /bin/bash  ##创建容器boss2运行 进行link关联

测试

[root@localhost ~]# docker exec -it f079b9213db2  /bin/bash ##进入boss2
[root@f079b9213db2 /]# ping boss1
PING boss1 (172.17.0.3) 56(84) bytes of data.
64 bytes from boss1 (172.17.0.3): icmp_seq=1 ttl=64 time=0.105 ms
64 bytes from boss1 (172.17.0.3): icmp_seq=2 ttl=64 time=0.066 ms
^C

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Moon-01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值