Docker镜像与容器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

Docker 包括三个基本概念

镜像(Image):Docker 镜像,就相当于是一个 root 文件系统。提供容器运行时所需的程序、库、资源、配置等文件,以及在运行时准备的一些配置参数。镜像 不包含 任何动态数据。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等
仓库(Repository):Docker Registry是可以在其它服务器上使用这个镜像的服务,一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。

一、Docker镜像

1.获取镜像

从 Docker 镜像仓库获取镜像的命令是 docker pull。其命令格式为:

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

在这里插入图片描述

2.列出镜像

列出已经下载下来的镜像,可以使用 docker image ls 命令
在这里插入图片描述

3.删除本地镜像

如果要删除本地的镜像,可以使用 docker image rm 命令,其格式为:

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

在这里插入图片描述也可以用镜像名,也就是 <仓库名>:<标签>,来删除镜像。
当然,更精确的是使用 镜像摘要 删除镜像。

$ docker image ls --digests
REPOSITORY                  TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
node                        slim                sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228   6e0c4c8e3913        3 weeks ago         214 MB

$ docker image rm node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228
Untagged: node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228

4. Dockerfile构建镜像

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

还以之前定制 nginx 镜像为例,这次我们使用 Dockerfile 来定制。

在一个空白目录中,建立一个文本文件,并命名为 Dockerfile:

$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile

其内容为:

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

4.1FROM 指定基础镜像

所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 nginx 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 FROM 就是指定 基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。
Docker 还存在一个特殊的镜像,名为 scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。

FROM scratch

4.2RUN 执行命令

RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:
1.shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。

RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

2.exec 格式:RUN [“可执行文件”, “参数1”, “参数2”],这更像是函数调用中的格式。

4.3构建镜像

在 Dockerfile 文件所在目录执行:

$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM nginx
 ---> e43d811ce2f4
Step 2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Running in 9cdc27646c7b
 ---> 44aa4490ce2c
Removing intermediate container 9cdc27646c7b
Successfully built 44aa4490ce2c

在这里插入图片描述

这里我们使用了 docker build 命令进行镜像构建。其格式为:

docker build [选项] <上下文路径/URL/->

在这里我们指定了最终镜像的名称 -t nginx:v3,构建成功后,我们可以像之前运行 nginx:v2 那样来运行这个镜像,其结果会和 nginx:v2 一样。

4.4镜像构建上下文(Context)

docker build 命令最后有一个 .。. 表示当前目录

5.跨平台构建镜像

首先确认内核开启了binfmt_misc,为了方便,可以使用qemu-user-static提供的基于docker的一键解决方案:
注册qemu解释器

docker run --rm --privileged multiarch/qemu-user-static:register --reset

在这里插入图片描述

之后就可以构建 aarch64的镜像了。 构建Docker镜像的方法是使用 Dockerfile,Dockerfile是一个文本文件,其中包含很多条指令,每一条指令构建一层,多层构成一个完整的Docker镜像。

FROM arm64v8/ubuntu:16.04

MAINTAINER qiaoshi qiaoshi003@ke.com

COPY qemu-aarch64-static /usr/bin/qemu-aarch64-static
#执行命令
ADD riemann_cam_rom.tar.gz /usr/local2/ 
RUN cp -nr /usr/local2/usr /  ;\
    cp -nr /usr/local2/bin /bin ;\
    cp -nr /usr/local2/lib /lib ;\
    cp -nr /usr/local2/sbin /sbin ;\
    cp -nr /usr/local2/realsee / ;\
    rm -rf /usr/local2/ \
    && sed -i 's/ports.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
    && sed -i 's/ports.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
    && apt update && apt --no-install-recommends install  git gcc automake  make g++ autoconf dbus curl file pkg-config shellcheck splint cppcheck  libjpeg8 libtiff5 cmake libudev-dev\
        libtiff5-dev libpng-dev  lua-zlib lua-zlib-dev  doxygen openssl libssl-dev valgrind  -y \
    && rm -rf /var/lib/apt/lists/*
#RUN echo "export PATH=/realsee/bin:/realsee/sbin:$PATH" >> /etc/profile
#RUN echo "export LD_LIBRARY_PATH=/realsee/lib" >> /etc/profile
RUN cp -p /lib/lib/libudev.so.1.6.3 /lib/
COPY ["rc.tar.gz","/etc/init.d/"]
COPY sys_web_ls_href /usr/local/bin
COPY indent /usr/bin
COPY docker_start /usr/local/bin
COPY docker_rpkg /usr/local/bin
RUN tar zxvf  /etc/init.d/rc.tar.gz -C /etc/init.d/ && rm /etc/init.d/rc.tar.gz
ADD var.tar.gz /realsee/var/
ADD include.tar.gz /realsee/
ENV PATH=/realsee/bin:/realsee/sbin:$PATH
ENV LD_LIBRARY_PATH=/realsee/lib
ENV PKG_CONFIG=/usr/bin/pkg-config
ENV PKG_CONFIG_PATH=/realsee/lib/pkgconfig/:/usr/lib/aarch64-linux-gnu/pkgconfig
RUN echo ". /etc/init.d/rc.environment " >> /etc/profile && echo "export DESTDIR=/packdir" >> /root/.bashrc && echo "export DESTDIR=/packdir" >> /etc/profile \
     && echo "/realsee/lib" > /etc/ld.so.conf.d/opencv.conf  && ldconfig /etc/ld.so.conf.d  >> /root/.bashrc
RUN mkdir -p /var/run/dbus ; rm -rf /var/run/dbus/pid 
#RUN apt install jq -y
CMD ["sh","-c","source /etc/profile"]

#对外端口
EXPOSE 80

定制镜像,首先要选择一个基础镜像,我们使用Ubuntu官方提供的aarch64的ubuntu镜像进行构建。首先需要通过ADD指令将qemu-aarch64-static二进制文件复制到镜像中,因为本机架构和docker镜像架构不同,如果不使用qemu-aarch64-static动态翻译二进制文件,后面的构建层会遇到指令无法执行的问题。之后在镜像内安装一些测试需要的文件,设置一些环境变量,完成Dockerfile的编写。 然后使用如下命令构建镜像:

docker build -t realsee-camera-riemann:0.test.528 .

将镜像的名字命名为realsee-camera-riemann,版本为0.test.528。
在这里插入图片描述COPY失败,下载 qemu-aarch64-static后,放入arm64v8文件夹
在这里插入图片描述add中应该是还需要一些文件,不知道是啥…

6.镜像存储位置

在操作系统中(Linux),默认情况下 Docker 容器的存放位置在 /var/lib/docker 目录下面,可以通过命令查看

docker info | grep "Docker Root Dir"

在这里插入图片描述
我们使用docker pull 下载的镜像,都会存在这个目录下,当下载的镜像过多,或容器运行过程中产生大量数据导致存储容量不足时,可以修改镜像储存的位置,有以下几种方式修改docker默认储存位置

6.1使用软链接

首先停止docker 进程
然后进行链接

#stop
$ sudo systemctl stop docker
#move
$ mv /var/lib/docker /data/docker
#ln
$ ln -sf /data/docker /var/lib/docker

然后移动整个 /var/lib/docker 目录到空间比较大的目的路径。这时候启动 Docker 时发现存储目录依旧是 /var/lib/docker 目录,但是实际上是存储在数据盘 /data/docker 上了。

6.2指定容器启动参数

6.3System 下创建配置文件

二、Docker容器

容器是 Docker 又一核心概念。简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。

启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(exited)的容器重新启动。

因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。

1.新建并启动容器

所需要的命令主要为 docker run。

例如,下面的命令输出一个 “Hello World”,之后终止容器。

$ docker run ubuntu:18.04 /bin/echo 'Hello world'
Hello world

这跟在本地直接执行 /bin/echo ‘hello world’ 几乎感觉不出任何区别。

下面的命令则启动一个 bash 终端,允许用户进行交互。

$ docker run -t -i ubuntu:18.04 /bin/bash
root@af8bae53bdd3:/#

其中,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。

在交互模式下,用户可以通过所创建的终端来输入命令,例如

root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

检查本地是否存在指定的镜像,不存在就从registry下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个 ip 地址给容器
执行用户指定的应用程序
执行完毕后容器被终止

在这里插入图片描述

2.启动已终止的容器

可以利用 docker container start 命令,直接将一个已经终止(exited)的容器启动运行。

3.停止容器

docker stop可以停止运行的容器。理解:容器在docker host中实际上是一个进程,docker stop命令本质上是向该进程发送一个SIGTERM信号。如果想要快速停止容器,可使用docker kill命令,其作用是向容器进程发送SIGKILL信号。
在这里插入图片描述

4.重启容器

对于已经处于停止状态的容器,可以通过docker start重新启动。

$ docker start bdf593fda8be
bdf593fda8be
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED           STATUS              PORTS               NAMES
bdf593fda8be        ubuntu:15.10        "/bin/bash"         11 minutes ago      Up 2 seconds

5.后台运行容器

如果不使用 -d 参数运行容器。

$ docker run ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
hello world

容器会把输出的结果 (STDOUT) 打印到宿主机上面

如果使用了 -d 参数运行容器。

$ docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a

此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面(输出结果可以用 docker logs 查看)。

注: 容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关,只要命令不结束,容器也就不会退出。上述命令中,while语句不会让bash退出,因此该容器就不会退出。

使用 -d 参数启动后会返回一个唯一的 id,也可以通过 docker container ls 命令来查看容器信息。

$ docker container ls
CONTAINER ID  IMAGE         COMMAND               CREATED        STATUS       PORTS NAMES
77b2dc01fe0f  ubuntu:18.04  /bin/sh -c 'while tr  2 minutes ago  Up 1 minute        agitated_wright

使用-d启动容器后,会回到host终端;此时如果想要获取容器的输出信息,可以通过 docker container logs 命令。

$ docker container logs [container ID or NAMES]
hello world
hello world
hello world
. . .

7.进入容器

在使用 -d 参数时,容器启动后会进入后台,启动完容器之后会停在host端;
某些时候需要进入容器进行操作,包括使用docker attach 命令或 docker exec 命令,推荐大家使用 docker exec 命令

docker attach 命令在这里插入图片描述注意: 如果从这个 stdin 中exit回到host端,会导致容器的停止。

docker exec 命令
docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。

docker exec [OPTIONS] CONTAINER COMMAND [ARG…]
OPTIONS说明:

-d :分离模式: 在后台运行

-i :即使没有附加也保持STDIN 打开

-t :分配一个伪终端

在这里插入图片描述
attach和exec的区别

attach和exec的区别:
(1)attach直接进入容器启动命令的终端,不会启动新的进程;
(2)exec则是在容器中打开新的终端,并且可以启动新的进程;
(3)如果想直接在终端中查看命令的输出,用attach,其他情况使用exec;

8.暂停容器

docker pause :暂停容器中所有的进程。

docker unpause :恢复容器中所有的进程。

9.删除容器

可以使用 docker container rm 来删除一个处于终止状态的容器。例如
在这里插入图片描述

如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。
清理所有处于终止状态的容器

用下面的命令可以清理掉所有处于终止状态的容器。

$ docker container prune

用下面的命令可以批量删除所有已经退出的容器

$ docker rm -v $(docker ps -aq -f status=exited)

10.导出容器

可以使用 docker import 从容器快照文件中再导入为镜像

11.导入容器

可以使用 docker import 从容器快照文件中再导入为镜像

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值