• Docker笔记


    Docker 镜像包含了基础操作系统,以及应用程序运行所需的代码和依赖包

    Docker 镜像可理解为 VM 中的模板,或 OOP 中的 Class

    安装 Docker

    使用 docker version 命令来检测客户端和服务端是否都已经成功运行

    用户可以通过引用镜像的 ID 或名称来使用镜像。
    一个镜像可以根据用户需要设置多个标签。


    查找镜像

    使用 docker search keyword 命令搜索Docker Hub 中的相关仓库

    • --filter
      • is-official=true:只显示官方镜像
      • is-automated=true:只显示自动创建的仓库
    • --limit:默认只显示25行结果,最多100行

    拉取镜像

    使用 docker image pull <repository>:<tag> 命令来拉取镜像(默认拉取标签为 latest 的镜像,但 latest 是一个非强制标签,不保证指向仓库中最新的镜像!)

    • -a:拉取仓库中的全部镜像,此时无需指定 tag

    查看本地镜像

    使用 docker image ls 命令来查看拉取的镜像

    • --digests:用于在本地查看镜像的 SHA256 摘要
    • --filter :用于过滤显示内容
      • dangling=false:指定仅返回非悬虚镜像(false)

        那些没有标签的镜像被称为悬虚镜像,在列表中展示为 <none>:<none>。通常出现这种情况,是因为构建了一个新镜像,然后为该镜像打了一个已经存在的标签。当此情况出现,Docker会构建新的镜像,然后发现已经有镜像包含相同的标签,接着Docker会移除旧镜像上面的标签,将该标签标在新的镜像之上。

      • before=python:3.7-slim:参数为镜像名称或者ID,返回在其之前被创建的全部镜像
      • since:返回在指定镜像之后创建的全部镜
      • reference="*:latest":仅显示标签为latest的镜像
    • --format:通过Go模板对输出内容格式化
      • "{{.Size}}":只返回各镜像的大小属性
      • "{{.Repository}}: {{.Tag}}: {{.Size}}" :只显示仓库、标签和大小信息
    • -q:返回本地拉取的全部镜像的ID列表

    删除镜像

    使用 docker image prune 命令移除全部的悬虚镜像

    • -a:Docker 会额外移除没有被任何容器使用的镜像

    使用 docker image rm ID 命令删除指定镜像

    快速删除镜像的方法:docker image rm $(docker image ls -q) -f

    若被删除的镜像上存在运行状态的容器,那么删除操作不会被允许

    若某个镜像层被多个镜像共享,那只有当全部依赖该镜像层的镜像都被删除后,该镜像层才会被删除。


    一致性检验

    从 Docker 1.10 版本开始,镜像就是一系列松耦合的独立层的集合。

    镜像本身是一个配置对象,其中包含了镜像层的列表以及一些元数据信息。

    镜像层才是实际数据存储的地方(比如文件等,镜像层之间是完全独立的,并没有从属于某个镜像集合的概念)。

    镜像的唯一标识是一个加密ID,其值为配置对象本身的散列值

    每个镜像层也由一个加密ID区分,其值为镜像层本身内容的散列值

    镜像配置对象的散列值和各镜像层内容的散列值作为内容散列(Content Hash),被用于辨别内容修改。
    而为节省网络带宽和存储空间,镜像传输(推送/拉取)时会被压缩,而压缩会导致前后内容散列可能不一致,所以还需要每个镜像层同时包含一个分发散列(Distribution Hash),用于标记压缩版镜像的一致性


    查看镜像分层和配置

    使用 docker image inspect <repository>:<tag> 命令查看镜像分层

    在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合

    多个镜像之间可以并且确实会共享镜像层,这样可以有效节省空间并提升性能


    使用 systemctl is-active dockerservice docker status 检查 Docker daemon 的状态


    启动容器

    使用 docker container run <option> <image>:<tag> <app> 命令从镜像来启动容器

    • --name:给容器命名
    • -it:选项使容器具备交互性并与终端进行连接
    • -d:表示后台模式,告知容器在后台运行
    • -p host-port:container-port:将 Docker 主机端口映射到容器内
    • --restart:重启策略,容器的一种自我修复能力,可以在指定事件或者错误后重启来完成自我修复
      • always:除非容器被明确停止,比如通过docker container stop 命令,否则该策略会一直尝试重启处于停止状态的容器。当 daemon 重启的时候,被明确停止的容器也会被重启
      • unless-stopped:与 always 的最大区别,就是那些指定了 --restart unless-stopped 并处于 Stopped (Exited) 状态的容器,不会在 Docker daemon 重启的时候被重启
      • on-failure:会在退出容器并且返回值不是0的时候,重启容器。就算容器处于 stopped 状态,在 Docker daemon 重启的时候,容器也会被重启

    Docker客户端通过相应 API 调用 Docker daemon,Docker daemon 接收命令后检索 Docker 本地缓存是否有命令所请求的镜像。若本地缓存中无该镜像,则查询在 Docker Hub 中是否存在对应镜像。找到该镜像后,Docker 将镜像拉取到本地,存储在本地缓存当中
    Docker daemon 通过位于 /var/run/docker.sock 的本地 IPC/Unix socket 来实现 Docker 远程 API。
    Docker 默认非 TLS 网络端口为2375,TLS 默认端口为2376

    容器会随着其中运行应用的退出而终止
    容器如果不运行任何进程则无法存在

    在Linux中启动容器的命令如下:

    $ docker container run -it ubuntu:latest /bin/bash
    root@6dc20d508db0:/#
    

    其中 -it 参数告诉 Docker 开启容器的交互模式并将当前 Shell 连接到容器终端,基于 ubuntu:latest 镜像启动容器,并在容器内部运行 Bash Shell 进程


    保持后台运行

    Ctrl-PQ 组合键会断开 Shell 和容器终端之间的链接,并在退出后保持容器在后台处于运行(UP)状态。


    查看容器

    使用 docker container ls 命令列出所有在运行(UP)状态的容器

    • 选项 -a:让 Docker 列出所有容器,甚至包括那些处于停止(Exited)状态的容器

    启动容器中的进程

    使用 docker container exec <options><container-name or container-id> <command/app> 命令在运行状态的容器中启动一个新进程

    • 选项 -it:使容器具备交互性

    停止容器

    使用 docker container stop <container-id or container-name> 命令停止运行中的容器,并将状态置为 Exited(0)

    通过发送 SIGTERM 信号给容器内 PID 为 1 的进程达到目的。如果进程没有在 10s 之内得到清理并停止运行,那么会接着发送 SIGKILL 信号来强制停止该容器


    重启容器

    使用 docker container start <container-id or container-name> 命令重启处于停止(Exited)状态的容器


    删除容器

    使用 docker container rm <container-id or container-name> 命令删除容器

    删除容器的最佳方式还是分两步,先停止容器然后删除。这样可以给容器中运行的应用/进程一个停止运行并清理残留数据的机会

    快速删除容器的方法:docker container rm $(docker container ls -aq) -f


    查看容器配置

    使用 docker container inspect <container-id or container-name> 命令显示容器的配置细节和运行时信息


    容器的生命周期

    创建,运行,根据需要多次停止、启动、暂停以及重启,销毁

    直至明确删除容器前,容器都不会丢弃其中的数据。就算容器被删除了,如果将容器数据存储在卷中,数据也会被保存下来。


    应用的容器化

    将应用整合到容器中并且运行起来的这个过程,称为“容器化”(Containerizing),有时也叫作“Docker化”(Dockerizing)。

    完整的应用容器化过程主要分为以下几个步骤:
    (1)编写应用代码。
    (2)创建一个 Dockerfile,其中包括当前应用的描述、依赖以及该如何运行这个应用。
    (3)对该 Dockerfile 执行 docker image build 命令。
    (4)等待 Docker 将应用程序构建到 Docker 镜像中。
    一旦应用容器化完成(即应用被打包为一个 Docker 镜像),就能以镜像的形式交付并以容器的方式运行了。

    使用 docker image build [选项] <上下文路径/URL/-> 命令基于上下文目录构建镜像

    • 选项 -t:指定 tag
    • 选项 -f:指定 Dockerfile 的路径和名称
    • 选项 --nocache=true 可以强制忽略对缓存的使用
    • 选项 --squash 可以指定构建一个合并的镜像

    在构建 Windows 镜像时,尽量避免使用 MSI 包管理器。因其对空间的利用率不高,会大幅增加镜像的体积。


    Dockerfile

    在 Docker 当中,包含应用文件的目录通常被称为构建上下文(Build Context)。通常将 Dockerfile 放到构建上下文的根目录下

    • Dockerfile 中的注释行以 # 开头。
      除注释之外,每一行都是一条指令(Instruction),格式为 INSTRUCTION argument

    Docker image build 命令会按行解析 Dockerfile 中的指令并顺序执行

    • FROM 指令指定要构建的镜像的基础镜像,通常是 Dockerfile 中的第一条指令

    • LABEL 以键值对的方式为镜像添加自定义元数据

    • RUN 指令在 FROM 指定的基础镜像之上,新建一个镜像层来存储安装内容

      通过使用 && 连接多个命令以及使用反斜杠()换行的方法,将多个命令包含在一个 RUN 指令中

    • COPY 指令将应用相关文件从构建上下文复制到了当前镜像中,并且新建一个镜像层来存储

      • 选项 --from 从之前阶段构建的镜像中仅复制生产环境相关的应用代码,而不复制生产环境不需要的构件
    • WORKDIR 指令为 Dockerfile 中尚未执行的指令设置工作目录。该目录与镜像相关,并且会作为元数据记录到镜像配置中,但不会创建新的镜像层

    • EXPOSE 指令设置向主机暴露的端口号。这个配置信息会作为镜像的元数据被保存下来,并不会产生新的镜像层

    • ENTRYPOINT 指令指定当前镜像的入口程序。ENTRYPOINT 指定的配置信息也是通过镜像元数据的形式保存下来,而不是新增镜像层


    查看执行命令历史

    使用 docker image history <repository>:<tag> 命令查看在构建镜像的过程中都执行了哪些指令


    使用 docker login 命令登录 DockerHub


    为镜像添加标签

    Docker 默认 Registry=docker.io、Tag=latest。但是Docker并没有给Repository提供默认值,而是从被推送镜像中的REPOSITORY属性值获取,当无权限访问该仓库时,需更改所要推送至的仓库名

    使用 docker image tag <current-tag> <new-tag> 命令为指定的镜像添加一个额外的标签,并且不需要覆盖已经存在的标签


    推送Docker镜像

    使用 docker image push <repository>:<tag> 命令推送镜像至 Docker 仓库


    多阶段构建(Multi-Stage Build)

    多阶段构建方式使用一个 Dockerfile,其中包含多个 FROM 指令。每一个 FROM 指令都是一个新的构建阶段(Build Stage),并且可以方便地复制之前阶段的构件。

    每一个 FROM 指令构成一个单独的构建阶段。各个阶段在内部从 0 开始编号。


    利用构建缓存

    第一次构建会拉取基础镜像,并构建镜像层,构建过程需要花费一定时间;第二次构建几乎能够立即完成。这就是因为第一次构建的内容(如镜像层)能够被缓存下来,并被后续的构建过程复用。
    docker image build 命令会从顶层开始解析Dockerfile 中的指令并逐行执行。而对每一条指令,Docker 都会检查缓存中是否已经有与该指令对应的镜像层。如果有,即为缓存命中(Cache Hit),并且会使用这个镜像层;如果没有,则是缓存未命中(Cache Miss),Docker 会基于该指令构建新的镜像层。缓存命中能够显著加快构建过程。

    一旦有指令在缓存中未命中(没有该指令对应的镜像层),则后续的整个构建过程将不再使用缓存。

    尽量将易于发生变化的指令置于Dockerfile文件的后方执行,尽量从缓存中获益。

    Docker 会计算每一个被复制文件的 checksum 值,并与缓存镜像层中同一文件的 checksum 进行对比。如果不匹配,那么就认为缓存无效并构建新的镜像层。

  • 相关阅读:
    linux 制作不用密碼可立即登入的 ssh 用戶
    大部分人都会忽略的Python易错点总结
    Python:有参装饰器与多个装饰器装饰一个函数
    Python面向对象中super用法与MRO机制
    Python实现一个键对应多个值的字典(multidict)
    python中*和**的打包和解包
    面试题:python 中 staticmethod 和 classmethod有什么区别
    Python小练习:StringIO和BytesIO读写操作的小思考
    Python中为什么不能用可变对象作为默认参数的值
    django中csrftoken跨站请求伪造的几种方式
  • 原文地址:https://www.cnblogs.com/4thirteen2one/p/13394864.html
Copyright © 2020-2023  润新知