使用Docker镜像

什么是Docker镜像

Docker镜像是由文件系统叠加而成,最底层是一个引导文件系统,即bootfs,第二层是root文件系统rootfs,它在bootfs上面,rootfs可以是一种操作系统,比如:ubuntu文件系统。

Docker会利用联合加载技术在rootfs上加载更多的只读文件系统。

联合加载技术(union mount)指的是一次同时加载多个文件系统,联合加载会将各层文件系统叠加到一起,这样最终的文件系统会包含所有底层的文件和目录。

Docker将这样的文件系统称之为镜像,一个镜像可以放到另一个镜像顶部,位于底部的镜像成为父镜像。最后从一个镜像启动容器的时候,Docker会在该镜像的最顶层加载一个读写文件系统,而我们进行的读写操作都是在这个读写层中执行的。

这里有些像反双亲委派的类加载器结构。

如果修改一个文件,文件首先重读写层下面的只读层复制到该读写层。注意该文件的只读版本依旧存在,但是已经被读写层中的文件副本所隐藏,这种机制称之为写时复制(copy on write)。

列出镜像

通过使用sudo docker images可以查看当前机器上已经获取的镜像列表。

$ sudo docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
weipeng2k/daemon_echo   latest              544097392791        2 weeks ago         508 MB
weipeng2k/ubuntu        16.04               412f213bef98        2 weeks ago         117 MB
ubuntu                  16.04               f7b3f317ec73        3 weeks ago         117 MB
ubuntu                  latest              f7b3f317ec73        3 weeks ago         117 MB
hello-world             latest              48b5124b2768        4 months ago        1.84 kB

可以看到该命令返回了当前机器上的镜像列表,第一列是仓库名,紧接着的是标签名以及镜像ID。

本地的镜像都保存在宿主机的/var/lib/docker/image/aufs目录下,可以看到有对应的文件以json格式存储了镜像以及其相关信息。

{"Repositories":{"hello-world":{"hello-world:latest":"sha256:48b5124b2768d2b917edcb640435044a97967015485e812545546cbed5cf0233","hello-world@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12
a1ac8d7":"sha256:48b5124b2768d2b917edcb640435044a97967015485e812545546cbed5cf0233"},"ubuntu":{"ubuntu:16.04":"sha256:f7b3f317ec734a73deca91b34c2b1e3dd7454650da9c8ef3047d29a873865178","ubuntu:latest":"sha2
56:f7b3f317ec734a73deca91b34c2b1e3dd7454650da9c8ef3047d29a873865178","ubuntu@sha256:f3a61450ae43896c4332bda5e78b453f4a93179045f20c8181043b26b5e79028":"sha256:f7b3f317ec734a73deca91b34c2b1e3dd7454650da9c8e
f3047d29a873865178"},"weipeng2k/daemon_echo":{"weipeng2k/daemon_echo:latest":"sha256:544097392791b51128724cd0dc317ee50c144981e1119248db4164c338e19f33"},"weipeng2k/ubuntu":{"weipeng2k/ubuntu:16.04":"sha256
:412f213bef98c936a72e702a8b9802cda72634347d09b0652e1a8a9886998ce1"}}}

在早期版本是/var/lib/docker

当执行sudo docker pull ${image_name}时,可以将镜像下载到本地,而在下载之前,镜像是保存在仓库中的。可以将仓库想象为类似maven或者git的仓库,它包括镜像、层以及镜像的元数据都存储在其中。

DockerHub中有两种类型仓库:用户仓库和顶层仓库,比如:ubuntu就是属于顶层仓库的,它只有仓库名部分,由专业相关团队维护。而用户仓库是用户自己创建的,就是由username/repository构成,比如:weipeng2k/ubuntu,这个就是用户weipeng2k下的ubuntu仓库。

在了解了仓库概念之后,可以想象,在运行sudo docker run ${image_name}时,就会查看当前本地是否存在${image_name},如果没有,将会从Registry下载。

查找镜像

很多基础设施都已经进行了镜像化,比如:memcached。我们怎么能够发现已经有的镜像呢?或者识别出哪些镜像是官方顶层仓库维护的呢?

可以访问hub.docker.com,进行搜索,或者运行sudo docker search ${key_words}搜索镜像。

$ sudo docker search memcached
NAME                            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
memcached                       Free & open source, high-performance, dist...   749       [OK]       
sylvainlasnier/memcached        Memcached docker images based on Ubuntu 14...   28                   [OK]
bitnami/memcached               Bitnami Memcached Docker Image                  6                    [OK]
frodenas/memcached              A Docker Image for Memcached                    5                    [OK]
eeacms/memcached                                                                4                    [OK]
webhippie/memcached             Docker images for memcached                     2                    [OK]
phpdockerio/memcached           PHPDocker.io memcached image                    1                    [OK]
getupcloud/memcached            Memcached is an in-memory key-value store....   1                    [OK]
tenstartups/memcached           A minimal memcached docker image based on ...   1                    [OK]

构建镜像

一般来说,我们不是真正的创建一个镜像,都是基于一个已有的基础镜像进行构建新的镜像。

使用sudo docker push ${image_name}可以将镜像推送到DockerHub

前提是使用sudo docker login进行登录DockerHub,可以现在DockerHub注册用户

$ sudo docker push weipeng2k/ubuntu
[sudo] password for weipeng2k:
The push refers to a repository [docker.io/weipeng2k/ubuntu]
3a111ef82522: Retrying in 1 second
73e5d2de6e3e: Pushing [==================================================>] 3.072 kB
08f405d988e4: Pushed
511ddc11cf68: Pushed
a1a54d352248: Mounted from library/ubuntu
9d3227c1793b: Mounted from library/ubuntu

上面就是将本地构建的使用中国软件源的ubuntu:16.04推送到DockerHub。

通过sudo docker commit ${container_id} ${image_name},完成镜像的构建,但是这种方式不推荐,Docker推荐使用Dockerfile来完成构建镜像。

新建一个目录static_web,在目录中,新建一个文件Dockerfile,这个目录就是当前的构建目录。

FROM weipeng2k/ubuntu:16.04
MAINTAINER weipeng2k "[email protected]"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hi, I am in Docker!' > /var/www/html/index.html

EXPOSE 80

上面每条指令都会新建一个镜像层并对镜像进行提交,Docker对这些执行的运作流程基本如下:

Docker针对每个命令都会执行上述流程,Docker首先会从镜像运行一个容器,然后执行一个命令,再进行提交为一个镜像层。

每个Dockerfile的第一条指令都是FROMFROM指定一个存在的镜像,后续指令都基于该镜像进行,这个镜像成为基础镜像。

RUN指令会在当前镜像运行的容器中,运行指定的命令,默认情况下RUN指令会在shell中使用 /bin/sh -c 来执行。

EXPOSE指令会设定容器内的程序将会使用容器的指定端口。

构建镜像很简单,在构建目录,执行sudo docker build -t="weipeng2k/static_web" .,该命令将会在当前目录下找寻Dockerfile文件,并开始构建镜像。

results matching ""

    No results matching ""