zoukankan      html  css  js  c++  java
  • docker镜像管理基础

    镜像的概念

    镜像可以理解为应用程序的集装箱,而docker用来装卸集装箱。

    docker镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动容器。

    docker镜像采用分层构建机制,最底层为bootfs,其上为rootfs

    • bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节约内存资源
    • rootfs:位于bootfs之上,表现为docker容器的根文件系统
      • 传统模式中,系统启动之时,内核挂载rootfs会首先将其挂载为“只读”模式,完整性自检完成后将其重新挂载为读写模式
      • docker中,rootfs由内核挂载为“只读”模式,而后通过“联合挂载”技术额外挂载一个“可写”层

    注意:当删除容器时,这个容器自有的“可写”层会一起被删除

    docker镜像层

    位于下层的镜像称为父镜像(parrent image),最底层的称为基础镜像(base image);
    最上层为“可读写”层,其下的均为“只读”层。

    docker存储驱动

    docker提供了多种存储驱动来实现不同的方式存储镜像,下面是常用的几种存储驱动:

    • AUFS
    • OverlayFS
    • Devicemapper
    • Btrfs
    • VFS

    AUFS

    AUFS(AnotherUnionFS)是一种Union FS,是文件级的存储驱动。AUFS是一个能透明覆盖一个或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在可写层。在Docker中,底下的只读层就是image,可写层就是Container。

    AUFS文件系统据说有3W行代码,而ext4文件系统却只有4000-5000行左右代码,这些代码是要被整合进内核的,后来AUFS申请要被合并进内核代码的时候,linuz觉得它这代码太过臃肿,于是拒绝了。因此AUFS这个文件系统一直以来就不是linux内核中自有的文件系统,想用AUFS这个文件系统的话,必须自己向内核打补丁并去编译使用它,但redhat系列的操作系统一向以稳定著称,不会干这种出格的事,所以在redhat系列操作系统中使用AUFS并无可能。而ubuntu上的docker默认使用的就是AUFS。

    OverlayFS

    Overlay是Linux内核3.18后支持的,也是一种Union FS,和AUFS的多层不同的是Overlay只有两层:一个upper文件系统和一个lower文件系统,分别代表Docker的镜像层和容器层。当需要修改一个文件时,使用CoW将文件从只读的lower复制到可写的upper进行修改,结果也保存在upper层。在Docker中,底下的只读层就是image,可写层就是Container。目前最新的OverlayFS为Overlay2。

    AUFS和Overlay都是联合文件系统,但AUFS有多层,而Overlay只有两层,所以在做写时复制操作时,如果文件比较大且存在比较低的层,则AUSF会慢一些。而且Overlay并入了linux kernel mainline,AUFS没有。目前AUFS已基本被淘汰。

    DeviceMapper

    Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并没有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。

    OverlayFS是文件级存储,Device mapper是块级存储,当文件特别大而修改的内容很小,Overlay不管修改的内容大小都会复制整个文件,对大文件进行修改显然要比小文件要消耗更多的时间,而块级无论是大文件还是小文件都只复制需要修改的块,并不是整个文件,在这种场景下,显然device mapper要快一些。因为块级的是直接访问逻辑盘,适合IO密集的场景。而对于程序内部复杂,大并发但少IO的场景,Overlay的性能相对要强一些。

    docker registry

    启动容器时,docker daemon会试图从本地获取相关的镜像,本地镜像不存在时,其将从Registry中下载该镜像并保存到本地。

    Registry用于保存docker镜像,包括镜像的层次结构和元数据。用户可以自建Registry,亦可使用官方的Docker Hub。

    docker registry的分类:

    • Sponsor Registry:第三方的Registry,供客户和Docker社区使用
    • Mirror Registry:第三方的Registry,只让客户使用
    • Vendor Registry:由发布docker镜像的供应商提供的registry
    • Private Registry:通过设有防火墙和额外的安全层的私有实体提供的registry

    docker registry的组成:

    • Repository
      • 由某特定的docker镜像的所有迭代版本组成的镜像仓库
      • 一个Registry中可以存在多个Repository
        • Repository可分为“顶层仓库”和“用户仓库”
        • 用户仓库名称格式为“用户名/仓库名”
      • 每个仓库可包含多个Tag(标签),每个标签对应一个镜像
    • Index
      • 维护用户帐户、镜像的检验以及公共命名空间的信息
      • 相当于为Registry提供了一个完成用户认证等功能的检索接口

    Docker Registry中的镜像通常由开发人员制作,而后推送至“公共”或“私有”Registry上保存,供其他人员使用,例如“部署”到生产环境。

    docker镜像的制作

    多数情况下,我们做镜像是基于别人已存在的某个基础镜像来实现的,我们把它称为base image。比如一个纯净版的最小化的centos、ubuntu或debian。

    那么这个最小化的centos镜像从何而来呢?其实这个基础镜像一般是由Docker Hub的相关维护人员,也就是Docker官方手动制作的。这个基础镜像的制作对于Docker官方的专业人员来说是非常容易的,但对于终端用户来说就不是那么容易制作的了。

    Docker Hub(docker中心)

    Docker Hub是一个基于云的注册服务,它允许您链接到代码库、构建镜像并测试它们、存储手动推送的镜像,以及链接到Docker cloud,以便您可以将镜像部署到主机。

    它为整个开发管道中的容器镜像发现、分发和更改管理、用户和团队协作以及工作流自动化提供了集中化的资源。

    Docker Hub提供以下主要功能:

    • 镜像仓库(Image Repositories)
      • 从社区和官方图书馆中查找和提取镜像,以及管理、推送和从您可以访问的私人镜像仓库中提取镜像。
    • 自动生成( Automated Builds)
      • 对源代码仓库进行更改时自动创建新镜像。
    • 网页钩子(Webhooks)
      • Webhooks是自动构建的一个特性,它允许您在成功推送到镜像仓库后触发操作。
    • 组织(Organizations)
      • 创建工作组以管理对镜像仓库的访问。
    • GitHub和Bitbucket集成(GitHub and Bitbucket Integration)
      • 将Hub和Docker的镜像添加到当前工作流中。

    docker镜像的获取

    要从远程注册表(如您自己的Docker注册表)获取Docker镜像并将其添加到本地系统,请使用Docker pull命令:

    # docker pull <registry>[:<port>]/[<namespace>/]<name>:<tag>

    是在TCP上提供docker分发服务的主机(默认值:5000)

    一起,并在注册表中标识由控制的特定镜像

    • 有些注册中心还支持raw;对于这些注册中心,raw是可选的
    • 但是,当它被包括在内时,提供的额外层次结构级别可用于区分具有相同属性的镜像

    层次结构的附加层次

    命名域 示例(名称空间/名字)
    组织(organization) redhat/kubernetes, google/kubernetes
    用户(username) Alice/application, bob/application
    角色(role) devel/database, test/database, prod/database

    镜像的生成

    镜像的生成途径:

    • Dockerfile
    • 基于容器制作
    • Docker Hub自动化构建

    基于容器制作镜像

    根据容器的更改创建新镜像

    用法:

    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
    选项 默认值 说明
    —author, -a   作者(例如,“约翰·汉尼拔·史密斯hannibal@a-team.com")
    -c, --change list   对创建的映像应用Dockerfile指令
    -m, --message string   提交消息
    -p, --pause true 提交期间暂停容器

    准备工作:安装启动docker并配置加速器

    • 使用pull命令拉取busybox镜像
    [root@Raygussie ~]# docker pull busybox
    Using default tag: latest
    latest: Pulling from library/busybox
    e5d9363303dd: Pull complete 
    Digest: sha256:c5439d7db88ab5423999530349d327b04279ad3161d7596d2126dfb5b02bfd1f
    Status: Downloaded newer image for busybox:latest
    docker.io/library/busybox:latest
    [root@Raygussie ~]# docker images
    REPOSITORY   TAG          IMAGE ID       CREATED        SIZE
    busybox      latest       b97242f89c8a   6 weeks ago    1.23MB
    httpd        latest       683a7aad17d3   6 weeks ago    138MB
    httpd        2.4-alpine   5d779ff71c18   2 months ago   55.5MB
    • 以busybox镜像创建test容器并以交互模式运行,创建一个网页文件
    [root@Raygussie ~]# docker run -it --name test busybox
    / # ls
    bin   dev   etc   home  proc  root  sys   tmp   usr   var
    / # mkdir /data
    / # echo 'I am Chinese' > /data/index.html
    / # cat /data/index.html
    I am Chinese
    • 创建的时候容器不能终止,使其处于运行状态
    [root@Raygussie ~]# docker commit -a "810454695@qq.com" -p -m "first commit" test
    sha256:6413393c1aa3b056bf7958032f0e962e2a7970a12aeb83ad63bd16e0e0967db5
    [root@Raygussie ~]# docker images
    REPOSITORY   TAG          IMAGE ID       CREATED          SIZE
    <none>       <none>       6413393c1aa3   34 seconds ago   1.23MB
    busybox      latest       b97242f89c8a   6 weeks ago      1.23MB
    • 替换镜像
    [root@Raygussie ~]# docker tag 6413393c1aa3 web:v0.1
    [root@Raygussie ~]# docker images
    REPOSITORY   TAG          IMAGE ID       CREATED         SIZE
    web          v0.1         6413393c1aa3   4 minutes ago   1.23MB
    busybox      latest       b97242f89c8a   6 weeks ago     1.23MB
    • 复制web镜像,修改名称为raygussie,版本为web:v0.2
    [root@Raygussie ~]# docker tag web:v0.1 raygussie/web:v0.2
    [root@Raygussie ~]# docker images
    REPOSITORY      TAG          IMAGE ID       CREATED         SIZE
    web             v0.1         6413393c1aa3   8 minutes ago   1.23MB
    raygussie/web   v0.2         6413393c1aa3   8 minutes ago   1.23MB

    • 设置名字为web,点击Public,然后点击Create

    • 获取代码

    • 登录docker账号
    [root@Raygussie ~]# docker login
    Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
    Username: raygussie
    Password: 
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    • 将镜像上传至网络仓库
    [root@Raygussie ~]# docker push raygussie/web:v0.2
    The push refers to repository [docker.io/raygussie/web]
    36783ff2fa2a: Pushed 
    0064d0478d00: Mounted from library/busybox 
    v0.2: digest: sha256:9847c6928d51b7d243ca15d7902d0822a0d6dbc50fd624569c08c80f1846380c size: 734

    • 删除刚上传的镜像
    [root@Raygussie ~]# docker rmi -f raygussie/web:v0.2
    Untagged: raygussie/web:v0.2
    Untagged: raygussie/web@sha256:9847c6928d51b7d243ca15d7902d0822a0d6dbc50fd624569c08c80f1846380c
    [root@Raygussie ~]# docker images
    REPOSITORY   TAG          IMAGE ID       CREATED          SIZE
    web          v0.1         6413393c1aa3   46 minutes ago   1.23MB
    busybox      latest       b97242f89c8a   6 weeks ago      1.23MB
    httpd        latest       683a7aad17d3   6 weeks ago      138MB
    httpd        2.4-alpine   5d779ff71c18   2 months ago     55.5MB
    • 然后下载网上的镜像
    [root@Raygussie ~]# docker pull raygussie/web:v0.2
    v0.2: Pulling from raygussie/web
    Digest: sha256:9847c6928d51b7d243ca15d7902d0822a0d6dbc50fd624569c08c80f1846380c
    Status: Downloaded newer image for raygussie/web:v0.2
    docker.io/raygussie/web:v0.2
    [root@Raygussie ~]# docker images
    REPOSITORY      TAG          IMAGE ID       CREATED          SIZE
    web             v0.1         6413393c1aa3   50 minutes ago   1.23MB
    raygussie/web   v0.2         6413393c1aa3   50 minutes ago   1.23MB
    busybox         latest       b97242f89c8a   6 weeks ago      1.23MB
    httpd           latest       683a7aad17d3   6 weeks ago      138MB
    httpd           2.4-alpine   5d779ff71c18   2 months ago     55.5MB
    • 验证内容是否一样
    [root@Raygussie ~]# docker run  -it --rm raygussie/web:v0.2
    / # ls
    bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
    / # ls /data
    index.html
    / # cat /data/index.html
    I am Chinese
    / # exit

    由此可见,新生成的镜像中是包含了新增的内容的,但是此时有一个问题,那就是容器默认要启动的进程是什么?在这里,默认情况下是启动的sh进程,但我们是要启动一个http站点,所以我们要在创建镜像时将容器默认启动的进程设为httpd,这样一来我们就可以通过新生成的镜像来快速构建一个简单的http站点了。

    http网站部署

    1.进入容器

    [root@Raygussie ~]# docker run  -it --rm raygussie/web:v0.2
    / # 

    2.启动另一个终端,查看容器ID

    [root@Raygussie ~]# docker ps
    CONTAINER ID   IMAGE                COMMAND   CREATED          STATUS          PORTS     NAMES
    3dcf2b21dadc   raygussie/web:v0.2   "sh"      12 seconds ago   Up 11 seconds             keen_bhabha

    3.生成新的镜像(-a是作者信息,-c为修改默认启动命令,/bin/httpd为启动进程,-f是不让它在后台运行,-c修改默认启动命令,-h指定目录)

    [root@Raygussie ~]# docker commit -a "raygussie 810454695@qq.com" -c 'CMD ["/bin/httpd","-f","-h","/data"]' -p 3dcf2b21dadc raygussie/web:v0.3
    sha256:6a0cd1d41ff0eb30c188c7447d85e7a8de96675451045ac53dccd39213320c71
    [root@Raygussie ~]# docker images
    REPOSITORY      TAG          IMAGE ID       CREATED             SIZE
    raygussie/web   v0.3         6a0cd1d41ff0   14 seconds ago      1.23MB
    web             v0.1         6413393c1aa3   About an hour ago   1.23MB
    raygussie/web   v0.2         6413393c1aa3   About an hour ago   1.23MB
    busybox         latest       b97242f89c8a   6 weeks ago         1.23MB
    httpd           latest       683a7aad17d3   6 weeks ago         138MB
    httpd           2.4-alpine   5d779ff71c18   2 months ago        55.5MB
    [root@Raygussie ~]# 

    4.运行刚才的镜像

    [root@Raygussie ~]# docker run -it --rm raygussie/web:v0.3

    5.再开启一个终端,查看ip地址

    [root@Raygussie ~]# docker ps
    CONTAINER ID   IMAGE                COMMAND                  CREATED              STATUS              PORTS     NAMES
    3599c78b5062   raygussie/web:v0.3   "/bin/httpd -f -h /d…"   About a minute ago   Up About a minute             dreamy_mendeleev
    3dcf2b21dadc   raygussie/web:v0.2   "sh"                     10 minutes ago       Up 10 minutes                 keen_bhabha
    [root@Raygussie ~]# docker inspect 3599c78b5062
    。。。。。。
      "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.3",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:03",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    [root@Raygussie ~]# 

    6.访问ip

    [root@Raygussie ~]# curl 172.17.0.3
    I am Chinese
    [root@Raygussie ~]# 

    镜像的导入与导出

    假如有2台主机,我们在主机1上做了一个镜像,主机2想用这个镜像怎么办呢?

    我们可以在主机1上push镜像到镜像仓库中,然后在主机2上pull把镜像拉下来使用,这种方式就显得比较麻烦,假如我只是测试用的,在一台主机上做好镜像后在另一台主机上跑一下就行了,没必要推到仓库上然后又把它拉到本地来。

    此时我们可以在已有镜像的基础上把镜像打包成一个压缩文件,然后拷贝到另一台主机上将其导入,这就是镜像的导入和导出功能。

    docker中我们使用docker save进行导出,使用docker load进行导入。

    [root@Raygussie ~]# docker images
    REPOSITORY      TAG          IMAGE ID       CREATED             SIZE
    raygussie/web   v0.3         6a0cd1d41ff0   12 minutes ago      1.23MB
    raygussie/web   v0.2         6413393c1aa3   About an hour ago   1.23MB
    web             v0.1         6413393c1aa3   About an hour ago   1.23MB
    busybox         latest       b97242f89c8a   6 weeks ago         1.23MB
    httpd           latest       683a7aad17d3   6 weeks ago         138MB
    httpd           2.4-alpine   5d779ff71c18   2 months ago        55.5MB
    //将镜像保存到web.tar.gz中
    [root@Raygussie ~]# docker save -o  raygussie/web
    [root@Raygussie ~]# ls
    anaconda-ks.cfg  web.tar.gz
    //删除然后恢复归档
    [root@Raygussie ~]# docker rmi raygussie/web:v0.2 raygussie/web:v0.3
    Untagged: raygussie/web:v0.2
    Untagged: raygussie/web@sha256:9847c6928d51b7d243ca15d7902d0822a0d6dbc50fd624569c08c80f1846380c
    Error response from daemon: conflict: unable to remove repository reference "raygussie/web:v0.3" (must force) - container 3599c78b5062 is using its referenced image 6a0cd1d41ff0
    [root@Raygussie ~]# docker minages
    docker: 'minages' is not a docker command.
    See 'docker --help'
    [root@Raygussie ~]# docker images
    REPOSITORY      TAG          IMAGE ID       CREATED             SIZE
    raygussie/web   v0.3         6a0cd1d41ff0   18 minutes ago      1.23MB
    web             v0.1         6413393c1aa3   About an hour ago   1.23MB
    busybox         latest       b97242f89c8a   6 weeks ago         1.23MB
    httpd           latest       683a7aad17d3   6 weeks ago         138MB
    httpd           2.4-alpine   5d779ff71c18   2 months ago        55.5MB
    [root@Raygussie ~]# docker load -i web.tar.gz 
    Loaded image: raygussie/web:v0.2
    Loaded image: raygussie/web:v0.3
    [root@Raygussie ~]# docker images
    REPOSITORY      TAG          IMAGE ID       CREATED             SIZE
    raygussie/web   v0.3         6a0cd1d41ff0   19 minutes ago      1.23MB
    web             v0.1         6413393c1aa3   About an hour ago   1.23MB
    raygussie/web   v0.2         6413393c1aa3   About an hour ago   1.23MB
    busybox         latest       b97242f89c8a   6 weeks ago         1.23MB
    httpd           latest       683a7aad17d3   6 weeks ago         138MB
    httpd           2.4-alpine   5d779ff71c18   2 months ago        55.5MB
  • 相关阅读:
    HDU 5642 King's Order 动态规划
    HDU 5640 King's Cake GCD
    HDU 5641 King's Phone 模拟
    HDU 5299 Circles Game 博弈论 暴力
    HDU 5294 Tricks Device 网络流 最短路
    HDU 5289 Assignment rmq
    HDU 5288 OO’s Sequence 水题
    星际争霸 虚空之遗 人族5BB 操作流程
    Codeforces Beta Round #3 D. Least Cost Bracket Sequence 优先队列
    Codeforces Beta Round #3 C. Tic-tac-toe 模拟题
  • 原文地址:https://www.cnblogs.com/mfdsg/p/14461582.html
Copyright © 2011-2022 走看看