资讯专栏INFORMATION COLUMN

Linux运维:docker(2)-镜像与容器

wuyumin / 1986人阅读

摘要:用于系统引导的文件系统,包括和容器启动完成后会被卸载以节约内存资源位于之上,表现为容器的根文件系统镜像原理镜像的文件系统被设计为分层存储的架构。分层存储的特征使得镜像的复用,定制变得更加容易。

docker镜像概述

操作系统分为内核kernel和用户空间。对于Linux而言,内核(bootfs)启动后会挂载root文件系统为其提供用户空间支持。而docker镜像,就相当于是一个root文件系统(rootfs)。

bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节约内存资源

rootfs:位于bootfs之上,表现为docker容器的根文件系统

镜像原理

镜像的root文件系统被设计为分层存储的架构。镜像在构建时,会一层一层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只会发生在自己这一层。

分层存储的特征使得镜像的复用,定制变得更加容易。可以使用构建好的镜像作为基础层,再进一步的添加新的层,以定制自己所需的内容,构建新的镜像。
简单来说,镜像是:

文件和metedata的集合(rootfs)

镜像是分层存储的,并且每一层都可以添加改变删除文件,成为一个新的镜像

不同镜像可以共享相同的layer(层)

镜像本身是read-only的

镜像获取

镜像的获取方式:

从镜像仓库(registry)获取

通过commit命令将容器保存为镜像

通过Dockerfile定制容器(推荐使用)

通过rootfs压缩包导入

docker save和docker load命令

镜像管理

从Registry拉取镜像
在docker hub上有大量高质量的镜像可以使用,从镜像仓库拉取镜像的命令格式是:

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

镜像的名称格式

Docker镜像仓库地址:<域名/IP>[:端口号],默认地址是docker hub

仓库名:<用户名>/<软件名>,对于docker hub,如果不给出用户名,默认是library,也就是官方镜像

标签:标签一般是镜像的版本信息,不指定标签默认是latest

例如:docker pull centos

$ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a02a4930cb5d: Pull complete 
Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
Status: Downloaded newer image for centos:latest

这条命令没有给出镜像仓库地址,默认从Docker Hub上获取。而镜像名称是centos,因此会获取官方镜像library/centos中标签为latest的镜像

配置镜像加速器
因为docker hub地址是在国外,从国内拉取镜像仓库中的镜像会比较慢,此时可以配置镜像加速器。
目前Docker官方和国内的云服务商都有提供国内加速服务。

Docker官方提供的中国加速器

阿里云加速器

配置阿里云加速器为例:
环境说明

系统环境:centos7

docker版本:Docker version 18.03.0-ce

创建目录文件

$ mkdir -p /etc/docker
$ vim /etc/docker/daemon.json

添加配置内容,配置内容在阿里云容器镜像服务中可以获取,每个阿里云账号都有自己的镜像加速器。

{
  "registry-mirrors": ["https://这里的配置每个人都有.mirror.aliyuncs.com"]
}

然后就是重新加载文件和重启docker,就可以了

$ systemctl daemon-reload
$ systemctl restart docker

列出镜像
列出本地镜像的命令是:

$ docker image ls

或者

$ docker images

删除镜像
删除本地镜像的命令:

$ docker image rm [选项] <镜像1> [<镜像2> ...]

镜像可以是镜像短ID,长ID,镜像名或者镜像摘要。
下面看$ docker images列出的镜像信息。

$ docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
centos                       latest              1e1148e4cc2c        2 months ago        202MB
busybox                      latest              59788edf1f3e        4 months ago        1.15MB
django-compose_web           latest              cfd70f0cb009        5 months ago        969MB
postgres                     latest              ac25c2bac3c4        5 months ago        228MB
my-compose_web               latest              4867e7c35cc9        5 months ago        86.5MB

其中REPOSITORY+TAG称为镜像名,IMAGE ID是镜像ID,取前几位就是镜像短ID。
比如用镜像名删除centos镜像:

$ docker image rm centos:latest
Untagged: centos:latest
Untagged: centos@sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
Deleted: sha256:1e1148e4cc2c148c6890a18e3b2d2dde41a6745ceb4e5fe94a923d811bf82ddb
Deleted: sha256:071d8bd765171080d01682844524be57ac9883e53079b6ac66707e192ea25956

使用镜像短ID删除镜像:

$ docker image rm 59788ed
Untagged: busybox:latest
Untagged: busybox@sha256:2a03a6059f21e150ae84b0973863609494aad70f0a80eaeb64bffffd8d92465812
Deleted: sha256:59788edf1f3e78cd0ebe6ce1446e9d10788225db3dedcfd1a59f764bad2b2690
Deleted: sha256:8a788232037eaf17794408ff3df6b922a1aedf9ef8de36afdae3ed0b0381907b

可以看到busybox这个镜像已经被删除。

也可以类似管道一样,结合其他命令的结果来删除镜像,比如docker image ls -q,先看看这个命令的执行结果。

$ docker image ls -q python
449d3495be0e
825141134528
825141134528
40792d8a2d6d

这个命令执行返回本地镜像中所有python镜像的镜像ID,有了ID就可以结合docker image rm来删除了。

docker image rm $(docker image ls -q)

这条命令对想要成批删除镜像很有帮助。
给镜像打标签
给镜像打标签的命令是docker tag 原镜像 新镜像名:标签,注意,打标签会新生成一个镜像,而且这个新的镜像ID和原镜像一样。
注意:镜像的唯一标识是其ID和摘要,一个镜像可以有多个标签。当删除镜像的时候,实际上是删除某个标签的镜像。

$ docker tag busybox busybox:version1
$ docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
busybox                      latest              d8233ab899d4        12 days ago         1.2MB
busybox                      version1            d8233ab899d4        12 days ago         1.2MB

启动镜像为容器
启动镜像为容器的命令,列举常用的一条命令:
docker run -itd (镜像名/ID/镜像摘要)

$ docker run -itd busybox
aa6ef78ae7b93704cbf9f99e184c2e2cb53924d693ca67c370fa74f52ff38d15

上面示例启动了busybox镜像为容器,不添加标签说明默认启动busybox:latest
选项说明:

-i表示让容器的标准输入打开,

-t表示分配一个伪终端,

-d表示后台启动。

要把-i -t -d 放到镜像名字前面。
查看运行状态的容器
查看容器运行状态使用docker ps只能查看运行中的容器,-a选项查看全部容器,包括未运行的容器。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
aa6ef78ae7b9        busybox             "sh"                     23 minutes ago      Up 23 minutes                              thirsty_brattain
ee0034f44bc6        wordpress:latest    "docker-entrypoint.s…"   5 months ago        Up About an hour    0.0.0.0:8000->80/tcp   wordpress-compose_wordpress_1
cbcb7baa5b2f        mysql:5.7           "docker-entrypoint.s…"   5 months ago        Up About an hour    3306/tcp, 33060/tcp    wordpress-compose_db_1

$ docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                      PORTS                     NAMES
aa6ef78ae7b9        busybox              "sh"                     23 minutes ago      Up 23 minutes                                         thirsty_brattain
341ea8ff6424        django-compose_web   "python3 manage.py r…"   5 months ago        Exited (137) 5 months ago                             django-compose_web_1
bffde084f040        django-compose_web   "django-admin.py sta…"   5 months ago        Exited (0) 5 months ago                               django-compose_web_run_1
0f68cb4ccae0        postgres             "docker-entrypoint.s…"   5 months ago        Exited (0) 5 months ago                               django-compose_db_1
ee0034f44bc6        wordpress:latest     "docker-entrypoint.s…"   5 months ago        Up About an hour            0.0.0.0:8000->80/tcp      wordpress-compose_wordpress_1
使用commit构建镜像

镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础。

镜像是多层存储,每一层是在前一层的基础上进行的修改;
而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储
层。
因此,在运行的容器对容器进行添加修改操作,也就是修改容器的存储层,docker提供了commit命令可以将容器存储层保存下来称为镜像。用例子看一下吧:
首先启动一个nginx镜像:

docker run --name webser -d -p 9000:80 nginx

这条命令会启动一个nginx镜像并命名为webser,把本地的9000端口映射到容器内的80端口,这样可以用浏览器去访问。

现在对这个webserver的默认界面进行修改。
进入容器,进行修改

$ docker exec -it webser bash
root@432bcf4daf84:/# echo "

Hello, Docker!

" > /usr/share/nginx/html/index.html root@432bcf4daf84:/# exit

重新访问可以看到改变。

我们修改了这个容器的存储层,接下来就可以使用commit命令来保存为镜像了。
docker commit的命令格式是:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
将上面修改的nginx容器保存提交为镜像:

$ docker commit -a "mori" -m "修改了默认网页" webser nginx:v2
sha256:25d8d84191b7e2ecbfb3c387797c47c1fa631386c418f63b78ab88067f62e365

-a也就是author,上面-a也可以改成--author,指定作者信息
-m是--message,可以改成--message ,说明
webser是容器名称,也可以是容器id,容器id通过docker ps查看
nginx:v2就是保存的镜像名称。

$ docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
nginx                        v2                  25d8d84191b7        6 minutes ago       109MB

可以看到镜像已经保存在本地了。接下来停止刚刚启动的nginx容器

$ docker stop webser

再启动新保存的镜像nginx:v2

$ docker run --name webser2 -d -p 9000:80 nginx:v2

浏览器访问,结果不是nginx默认网页,而是修改后的界面。

注意:docker commit虽然可以很好理解镜像的构成,但是尽量不要用,虽然上面只是简单修改了网页文件,但是使用docker diff webser 可以发现有很多文件被改动或者添加,这会使镜像变得臃肿。

通过压缩包导入创建镜像

首先去下载一个压缩包
http://openvz.org/Download/te... //下载速度不快,我下载了一个centos6的模板

下载完导入该镜像的命令为:

$ cat centos-6-x86-minimal.tar.gz|docker import - centos6

docker images查看导入的镜像

把现有镜像,导出为一个文件:

$ docker save -o moli_nginx.tar nginx 

我们还可以用该文件恢复本地镜像:

$ docker load --input  moli_nginx.tar  #或者
$ docker load <  moli_nginx.tar

镜像构建之Dockerfile

Dockerfile是什么?
Dockerfile是用来构建docker镜像的镜像文件,是由一系列命令和参数构成的脚本。
构建步骤

手动编写一个Dockerfile文件(这个文件最好创建在一个空白目录下),必须符合Dockerfile文件规范

有了这个文件后,使用docker build命令生成一个自定义的镜像

然后就docker run

这个Dockerfile文件长什么样?
以centos为例,文件内容如下:

FROM scratch
ADD centos-7-docker.tar.xz /

LABEL org.label-schema.schema-version="1.0" 
    org.label-schema.name="CentOS Base Image" 
    org.label-schema.vendor="CentOS" 
    org.label-schema.license="GPLv2" 
    org.label-schema.build-date="20181205"

CMD ["/bin/bash"]

所谓定制镜像,也就是在一定镜像的基础上,而FROM指令的作用就是指定基础镜像。基础镜像是必须指定的,而且必须是Dockerfile文件的第一条指定。关于其他指令见下面。

Dockerfile文件中常见的指令

指令 说明
FROM 指定基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露的端口
WORKDIR 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点
ENV 用来在构建镜像过程中设置环境变量,这个变量可以被后续的RUN命令,WORKDIR命令使用
ADD 将宿主机目录下的文件拷贝进镜像并且ADD命令会自动处理URL和解压tar压缩包
COPY 类似ADD命令,拷贝目录文件到镜像中
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD 指定一个容器启动时要运行的命令,Dockerfile中可以有多个CMD,但只有最后一个生效,CMD会被docker run之后的参数替换掉
ENTRYPOINT 和CMD类似,都是指定一个容器启动时要运行的命令,不过他不会被替换,而是追加
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/27716.html

相关文章

  • 容器化-Docker介绍

    摘要:容器作为一类操作系统层面的虚拟化技术,其目标是在单一主机交付多套隔离性环境,容器共享同一套主机操作系统内核。与其它容器平台不同,引入了一整套与容器管理相关的生态系统。每个容器都是相互隔离的保证安全的平台。 导读:本文章对Docker技术进行了介绍,阐述了Docker的技术发展历程、容器与虚拟机的差异、Docker原理、特点、Docker三组件和Docker带来的影响,为我们进一步理解D...

    李增田 评论0 收藏0
  • 技术选型之Docker容器引擎

    摘要:是系统提供的容器化技术,简称,它结合和技术为用户提供了更易用的接口来实现容器化。公司结合和以下列出的技术实现了容器引擎,相比于,具备更加全面的资源控制能力,是一种应用级别的容器引擎。 showImg(https://segmentfault.com/img/bVbtPbG?w=749&h=192); 题外话   最近对Docker和Kubernetes进行了一番学习,前两天做了一次技术...

    monw3c 评论0 收藏0
  • 【 全干货 】5 分钟带你看懂 Docker

    摘要:本文从定义,作用,技术架构,安装和使用等全方位带你看懂。如图中左边红框中和右边的红框中都唯一表示为同一个镜像。最后,于开发者而言提供了一种开发环境的管理办法,与测试人员而言保证了环境的同步,于运维人员提供了可移植的标准化部署流程。 作者丨唐文广:腾讯工程师,负责无线研发部地图测试。 导语:Docker,近两年才流行起来的超轻量级虚拟机,它可以让你轻松完成持续集成、自动交付、自动部署...

    Edison 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<