• Docker镜像的构建方式


    摘要

    在构建容器化应用时,相当重要的步骤莫过于镜像制作,本文将介绍镜像制作方法以及镜像制作的建议。
    采用docker commit生成的镜像实际上是容器内的文件系统进行修改在进行提交,而运行的容器实际上是在镜像的文件系统顶层添加了一层读写层,所都的修改都是基于这一层,当生成镜像时会将这一层数据保存,所以每次使用commit提交镜像时候都会比原来多一层,这样会使得镜像越来越大并且不易维护。同时,对于镜像使用者来说完全不透明,使用者不清楚该镜像怎么样构建的,是否安全等,这种方式及其不推荐。
    而使用Dockerfile构建镜像,对于使用者来说完全透明,构建镜像的每一个步骤都在Dockerfile文件中描述的清清楚楚,同时当需要对镜像修改时候,只需修改Dockerfile文件中的指令,维护镜像只需要维护一个Dockerfile,这也是镜像构建的最佳方式。当然,要使用Dockerfile就必须明白Dockerfile的语法和各个指令,以下将作详细介绍。

    一、Docker镜像的分层

    镜像

    Dockerfile生成

    每层运行一个容器,运行完成后移除

    CMD[“./run.sh”]

    Json

    VOLUME /date

    Json

    ADD run.sh /

    /run.sh

    FROM centos:7

     

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

    二、Docker镜像的创建

    2.1、Docker镜像

    2.1.1、应用发布的标准格式

    2.1.2、支撑一个Docker容器的运行

    2.2、Docker镜像的创建方法

    2.2.1、基于已有镜像创建

    2.2.2、基于本地模板创建

    2.2.3、基于Dockerfile创建

    2.3、基于已有镜像创建

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

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

    2.3.2、操作步骤

    1 [root@server1 ~]# docker commit -m "new" -a "xu" 1495c44b9eb9 httpd:xin
    2 sha256:9205c504d1886ab44f97ddc54edeef3c38b135d11cf2a8ed63bcb7a7b551a34b
    3 [root@server1 ~]# docker images
    4 REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    5 httpd               xin                 9205c504d188        7 seconds ago  

    2.4、基于本地模板创建

    1 导入本地镜像debian-7.0-x86-minimal.tar.gz
    2 [root@server1 ~]# cat debian-7.0-x86-minimal.tar.gz | docker import - docker:debian
    3 sha256:91d49f99a942cf4737dadc1d4e25e738eeb94e2aa7d10b01e06ceb56b9f4926a
    4 [root@server1 ~]# docker images
    5 REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    6 docker              debian              91d49f99a942        9 seconds ago       215MB

    2.5、基于Dockerfile创建

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

    2.5.2、Dockerfile结构四部分

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

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

    2.5.4、Dockerfile操作指令

    指令

    含义

    FROM 镜像

    指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令

    MAINTAINER 名字

    说明新镜像的维护人信息

    RUN 命令

    在所基于的镜像上执行命令,并提交到新的镜像中

    CMD [“要运行的程序”,“参数”]

    指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能最后一条被执行

    EXPOSE 端口号

    指定新镜像加载到Docker时要开启的端口

    ENV 环境变量 变量值

    设置一个环境变量的值,会被后面的RUN使用

    ADD 源文件/目录 目标文件/目录

    将主机的文件拷贝到容器中,源文件要与Dockerfile位于相同目录中,或者是一个URL,自动进行解压操作,不需要手动解压

    COPY 源文件/目录 目标文件/目录

    将容器中的文件拷贝到容器的其他目录中

    VOLUME [“目录”]

    再容器中创建一个挂载点

    USER 用户名/UID

    指定运行容器时的用户

    WORKDIR 路径

    为后续的RUN、CMD、ENTRYPOINT指定工作目录

    ONBUILD 命令

    指定所生成的镜像作为一个基础镜像时所要运行的命令

    HEALTHCHECK

    健康检查

    2.5.5、Dockerfile创建

     1 [root@server1 httpd]# mkdir httpd
     2 [root@server1 httpd]# cd httpd
     3 [root@server1 httpd]# vim Dockerfile
     4 #基于centos:7的基础镜像
     5 FROM centos:7
     6 #维护镜像的用户信息
     7 MAINTAINER this is project
     8 #镜像操作指令安装apache软件
    10 RUN yum -y install httpd 11 #开启80端口 12 EXPOSE 80 13 #复制网址首页文件 14 ADD index.html /var/www/html/index.html 15 #将执行脚本复制到镜像中 16 ADD run.sh /run.sh 17 RUN chmod 755 /run.sh 18 #启动容器时执行脚本 19 CMD ["/run.sh"]

    2.5.6、制作脚本

    1 [root@server1 httpd]# vim run.sh
    2 #!/bin/bash
    3 rm -rf /run/httpd/*
    4 exec /usr/sbin/apachectl -D FOREGROUND

    2.5.7、制作网页

    1 [root@server1 httpd]# echo '<h1>this is web</h1>' > index.html 
    2 [root@server1 httpd]# ll      #文件要放同一个目录
    3 总用量 12
    4 -rw-r--r--. 1 root root 402 11月 26 15:13 Dockerfile
    5 -rw-r--r--. 1 root root  21 11月 26 15:16 index.html
    6 -rw-r--r--. 1 root root  71 11月 26 15:15 run.sh

     2.5.8、生成镜像

     1 [root@server1 httpd]# docker build -t httpd:centos .
     2 Sending build context to Docker daemon  4.096kB
     3 Step 1/9 : FROM centos:7
     4 7: Pulling from library/centos
     5 2d473b07cdd5: Pull complete 
     6 Digest: sha256:0f4ec88e21daf75124b8a9e5ca03c37a5e937e0e108a255d890492430789b60e
     7 Status: Downloaded newer image for centos:7
     8  ---> 8652b9f0cb4c
     9 Step 2/9 : MAINTAINER this is project
    10  ---> Running in 6ef16daecd7f      #每次执行都会运行一个容器,运行后移除
    11 Removing intermediate container 6ef16daecd7f
    12  ---> a7a48005092b
    13 Step 3/9 : RUN yum -y install update
    14  ---> Running in 7b105c9b4747

    2.5.9、新镜像运行容器

    1 [root@server1 httpd]# docker run -d -p 2222:80 httpd:centos 
    2 d87c48f281e888254d6a74cf781fccf80c18feab78103b2a1d3726fe9bb9aae5
    3 [root@server1 httpd]# docker ps -a 
    4 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                  NAMES
    5 d87c48f281e8        httpd:centos        "/run.sh"                6 seconds ago       Up 5 seconds               0.0.0.0:2222->80/tcp   sleepy_shannon

    2.5.10、测试

    三、私有仓库建立

    3.1、拉取镜像及修改配置文件(端口号:5000)

     1 #拉取镜像
     2 [root@server1 httpd]# docker pull registry
     3 Using default tag: latest
     4 latest: Pulling from library/registry
     5 cbdbe7a5bc2a: Pull complete 
     6 47112e65547d: Pull complete 
     7 46bcb632e506: Pull complete 
     8 c1cc712bcecd: Pull complete 
     9 3db6272dcbfa: Pull complete 
    10 Digest: sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d
    11 Status: Downloaded newer image for registry:latest
    12 docker.io/library/registry:latest
    13 
    14 修改配置文件
    15 [root@server1 httpd]# vim /etc/docker/daemon.json 
    16 {
    17 "insecure-registries": ["20.0.0.10:5000"],       #添加
    18 "registry-mirrors": ["https://lyoy0ey2.mirror.aliyuncs.com"]
    19 }
    20 
    21 重启服务
    22 [root@server1 httpd]# systemctl restart docker.service 

    3.2、创建镜像并查看

    1 [root@server1 httpd]# docker create -it registry /bin/bash
    2 b8fca969d55da2cd78b07750142498eda2ffe25428edbff1aa592fb4f08c20ed
    3 
    4 [root@server1 httpd]# docker ps -a 
    5 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                            PORTS               NAMES
    6 b8fca969d55d        registry            "/entrypoint.sh /bin…"   6 seconds ago       Created                                               fervent_noether
    7 
    8 [root@server1 httpd]# docker start b8fca969d55d 
    9 b8fca969d55d

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

    1 [root@server1 httpd]# docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry
    2 de58e178a3172ecc8c52bcaf4063da21a5eb9a1605180add6a03a8064a257cf5
    3 [root@server1 httpd]# docker tag httpd:centos 20.0.0.10:5000/httpd    #打标签

    3.4、上传并获取

     1 上传
     2 [root@server1 httpd]# docker push 20.0.0.10:5000/httpd
     3 The push refers to repository [20.0.0.10:5000/httpd]
     4 7bf28fb5dbac: Pushed 
     5 35fc0f295312: Pushed 
     6 3069654c482f: Pushed 
     7 5eb6c74f0823: Pushed 
     8 174f56854903: Pushed 
     9 latest: digest: sha256:1782102d1c3c1231cd4c17035381e83dc2844547af30c9067a3f96334d585dba size: 1362
    10 
    11 获取私有仓库列表
    12 [root@server1 httpd]# curl -XGET http://20.0.0.10:5000/v2/_catalog
    13 {"repositories":["httpd"]}    #显示上传成功
    14 
    15 删除centos镜像
    16 [root@server1 registry]# docker rmi 20.0.0.10:5000/httpd:latest 
    17 
    18 测试私有仓库下载
    19 [root@server1 registry]# docker pull 20.0.0.10:5000/httpd
    20 Using default tag: latest
    21 latest: Pulling from httpd
    22 2d473b07cdd5: Already exists 
    23 5e105bbe607b: Pull complete 
    24 0ce1bb40a734: Pull complete 
    25 bf8183ec3c05: Pull complete 
    26 1b093a1fad54: Pull complete 
    27 Digest: sha256:1782102d1c3c1231cd4c17035381e83dc2844547af30c9067a3f96334d585dba
    28 Status: Downloaded newer image for 20.0.0.10:5000/httpd:latest
    29 20.0.0.10:5000/httpd:latest

    四、Docker数据卷管理

    4.1、Docker数据卷

    -v 会自动进行创建目录进行挂载(宿主机与容器之间挂载)

    4.1.1、宿主机目录/var/www挂载容器中的/data1

    1 [root@server1 registry]# docker run -v /var/www:/data1 --name web1 -it centos:7 /bin/bash      #运行完后进入容器
    2 [root@6cfe7d1acca1 /]# cd /data1/
    3 [root@6cfe7d1acca1 data1]# echo 'nihao!' > test.txt

    4.1.2、宿主机查看

    1 [root@server1 www]# cat /var/www/test.txt 
    2 nihao!

    4.2、数据卷容器

    数据卷容器,新容器挂载数据卷容器web100(容器内部挂载)

     1 [root@server1 www]# docker run --name web100 -v /data2 -v /data3 -it centos:7 /bin/bash    #运行后进入容器
     2 
     3 再开一个主机
     4 [root@server1 registry]# docker run -it --volumes-from web100 --name db1 centos:7 /bin/bash
     5 
     6 查看
     7 [root@941d8414bc15 /]# ls
     8 anaconda-post.log  data3  home   media  proc  sbin  tmp
     9 bin                dev    lib    mnt    root  srv   usr
    10 data2              etc    lib64  opt    run   sys   var
    11 
    12 [root@ac1a1deff23d /]# ls
    13 anaconda-post.log  data3  home   media  proc  sbin  tmp
    14 bin                dev    lib    mnt    root  srv   usr
    15 data2              etc    lib64  opt    run   sys   var
    16 
    17 创建文件便查看
    18 [root@ac1a1deff23d /]# cd data2
    19 [root@ac1a1deff23d data2]# touch aa
    20 [root@ac1a1deff23d data2]# ls
    21 aa
    22 [root@ac1a1deff23d data2]# cd /data3
    23 [root@ac1a1deff23d data3]# touch bb
    24 [root@ac1a1deff23d data3]# ls
    25 bb
    26 
    27 [root@941d8414bc15 /]# cd data2
    28 [root@941d8414bc15 data2]# ls
    29 aa
    30 [root@941d8414bc15 data2]# cd /data3
    31 [root@941d8414bc15 data3]# ls
    32 bb

    4.3、端口映射

     1 [root@server1 httpd]# docker run -d -P httpd:centos            #P随机端口号,从32768开始
     2 8d2b86c97ac08628fb197d6fdbdabe883195fe43875f9e71efbca94ac559a0aa
     3 [root@server1 httpd]# docker ps -a
     4 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS                    NAMES
     5 8d2b86c97ac0        httpd:centos        "/run.sh"                5 seconds ago       Up 4 seconds                   0.0.0.0:32768->80/tcp    amazing_northcutt
     6 
     7 [root@server1 httpd]# docker run -d -p 2222:80 httpd:centos    #p指定端口号
     8 cc7230fdf9c3a40b05733f94989740f488aafdcb6648093325f84fb0fe0f460d
     9 [root@server1 httpd]# docker ps -a
    10 CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                         PORTS                    NAMES
    11 cc7230fdf9c3        httpd:centos        "/run.sh"                6 seconds ago        Up 5 seconds                   0.0.0.0:2222->80/tcp     heuristic_newton

    4.4、容器互联

     1 创建并运行容器取名web11,端口号自动映射
     2 [root@server1 httpd]# docker run -dit -P --name web11 centos:7 /bin/bash
     3 5fa7635068c78b7c0fc331398ae5f4e393001c1f5c5f02072d11f3471f07e341
     4 
     5 --name 指定容器名称
     6 
     7 创建并运行容器取名web22
     8 [root@server1 httpd]# docker run -dit -P --name web22 --link web11:web11 centos:7 /bin/bash
     9 b413c6cbf148cb7670084e8e31c24993e61f1cc83efb2eee4a1cd38ee1325ed7
    10 
    11 --link 关联单向连接
    12 
    13 进web22容器ping web11
    14 [root@server1 httpd]# docker ps -a
    15 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                           PORTS                    NAMES
    16 b413c6cbf148        centos:7            "/bin/bash"              3 minutes ago       Up 3 minutes                                              web22
    17 5fa7635068c7        centos:7            "/bin/bash"              4 minutes ago       Up 4 minutes                                              web11
    18 
    19 [root@server1 httpd]# docker exec -it b413c6cbf148 /bin/bash
    20 
    21 [root@b413c6cbf148 /]# ping web11
    22 PING web11 (172.17.0.5) 56(84) bytes of data.
    23 64 bytes from web11 (172.17.0.5): icmp_seq=1 ttl=64 time=0.066 ms
    24 64 bytes from web11 (172.17.0.5): icmp_seq=2 ttl=64 time=0.058 ms
    25 64 bytes from web11 (172.17.0.5): icmp_seq=3 ttl=64 time=0.060 ms
    26 --- web11 ping statistics ---
    27 3 packets transmitted, 3 received, 0% packet loss, time 2000ms
    28 rtt min/avg/max/mdev = 0.058/0.061/0.066/0.007 ms
    29 
    30 安装net工具
    31 [root@b413c6cbf148 /]# yum -y install net-tools
    32 [root@b413c6cbf148 /]# ifconfig     #查询网址信息
    33 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    34         inet 172.17.0.6  netmask 255.255.0.0  broadcast 172.17.255.255     #第一个创建的容器地址是172.17.0.2,以此类推
    35         ether 02:42:ac:11:00:06  txqueuelen 0  (Ethernet)
    36         RX packets 7114  bytes 11320444 (10.7 MiB)
    37         RX errors 0  dropped 0  overruns 0  frame 0
    38         TX packets 3999  bytes 219299 (214.1 KiB)
    39         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    40 
    41 lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
    42         inet 127.0.0.1  netmask 255.0.0.0
    43         loop  txqueuelen 1  (Local Loopback)
    44         RX packets 0  bytes 0 (0.0 B)
    45         RX errors 0  dropped 0  overruns 0  frame 0
    46         TX packets 0  bytes 0 (0.0 B)
    47         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • 相关阅读:
    splinter webdriver API 的基本实现
    201253 线程和进程的区别
    Winform中的默认图片
    [收藏】正确使用SqlConnection对象,兼谈数据库连接池
    手机相关的基础名称
    常见排序
    SIP相关内容
    How to set the WIFI configuration
    本地化的设置和读取
    Serialize And Deserialize Binary Tree
  • 原文地址:https://www.cnblogs.com/xuhao0705/p/14042469.html
Copyright © 2020-2023  润新知