【Docker】基础篇

系列综述:
💞目的:本系列是个人整理为了云计算学习的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于–Docker视频教程从入门到进阶,docker视频教程详解–进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞关注一下呗,谢谢🎈🎄🌷!!!

请先收藏!!!,后续继续完善和扩充👍(●’◡’●)


文章目录

    • 一、Docker简介
      • Docker综述
    • 二、Docker镜像
      • 镜像概述
      • 镜像分层
      • ImageID和镜像摘要
    • 三、Docker引擎
      • 概述
      • 容器
      • 容器操作指令
    • 四、Dockerfile
      • 简介
      • 指令详解
    • 五、数据持久化
      • 简介
      • 数据卷相关命令
    • 六、Docker网络通信
      • 简介
      • CNM
      • Docker网络相关指令
    • 参考博客


😊点此到文末惊喜↩︎


一、Docker简介

Docker综述

  1. DevOps的核心理念/目标/作用
    • 整合开发和运维团队间的协作关系,提高软件交付速度、质量和稳定性
    • 流程主要包含开发code、构建build、测试test、发布release、部署deploy、维护operator、监控monitor、迭代plan
      在这里插入图片描述
  2. Docker发展历程
    • 首发版本(2013年)
      • 依赖于第三方工具LXC(Linux Containers)作为其容器管理的基础,可能被禁止使用且无法跨平台
      • Docker Daemon设计复杂庞大,出现问题难以维护和更新
    • Docker 0.9版本(约2014年)
      • 采用自研的Libcontainer工具,直接利用Linux内核的特性(如cgroups和namespaces)来管理容器,提高了效率和跨平台能力
    • Docker 1.1及OCI规范(2016年)
      • 将容器运行时代码从Docker Daemon中分离出来,形成了符合Docker运行时规范Open Container Initiative (OCI)的Runc项目,负责实际的容器创建和管理任务。
      • Containerd作为中间层,进一步管理镜像生命周期和容器运行,加强了Docker的底层架构。
  3. 虚拟化技术Hypervisor
    • 原理:通过抽象化硬件资源,使得每个虚拟机都相信自己独占了一套完整的硬件,从而能够在单一物理主机上运行多个独立的操作系统实例。
    • 分类
      • Type-1 Hypervisor(裸金属虚拟化):直接安装并运行在物理硬件上,支持完整的硬件虚拟化
      • Type-2 Hypervisor:运行在标准操作系统之上,作为一个应用程序。
    • 常见实例
      • KVM (Kernel-based Virtual Machine):集成在Linux内核中的Type 1 Hypervisor,支持完整的硬件虚拟化
      • Xen:是一个较早的开源Hypervisor,支持多种操作系统
      • Hyper-V:Windows上的Type 1 Hypervisor,提供安全高效的虚拟化服务
  4. Docker底层支持技术
    • Linux Namespace(命名空间):容器隔离的基础,包括User,Mnt,Network,UTS,IPC,Pid
    • Linux CGroups(控制组):cgroups 容器资源统计和隔离, 主要是cpu,device,memory等
    • unionFS( 联合文件系统):aufs/overlayfs,是镜像分层实现的基础
  5. Docker的三要素
    • Image(镜像):应用程序+依赖环境
    • Container(容器):镜像+可写层+运行资源(命名空间等)
    • Repository(仓库):多架构多版本镜像的存储中心

二、Docker镜像

镜像概述

  1. 定义:由应用程序及其依赖环境构成的一个静态只读的模板文件,该文件是一堆静态只读数据层的统一视角,基于统一文件系统技术隐藏了多层 (这个定义需要进行统一的处理)
    在这里插入图片描述
  2. 作用(每一个都可以进行原理的拓展)
    • 只读保证可重复:Docker镜像是包含应用程序及其依赖环境的只读文件,所以开发和测试团队可以通过同一个镜像构建相同的程序执行实例
    • 分层保证可拓展:Docker镜像由多个只读镜像层堆叠而成,除基础镜像层外,每个镜像新层基于一条dockerfile指令(如RUN, COPY, ADD等)进行增量构建
    • 跨平台支持保证可移植:Docker在不同计算机架构(例如x86、ARM等)提供了相应的镜像和运行时环境
    • 分层存储保证快速部署:Docker镜像由多个只读层堆叠组成,只读有利于镜像层的复用分层有利于不同镜像间的共享,从而实现存储优化,提高缓存命中率
    • 内核机制保证隔离性:Docker使用Linux内核的cgroup和namespace机制,实现了容器宿主机其他容器间的隔离
    • 容器编排工具保证可伸缩性:Docker Swarm和Kubernetes等容器编排工具提供了自动化容器部署、伸缩和管理的功能,从而实现负载均衡和自动扩缩容
  3. 镜像仓库类型
    • 官方仓库(Docker Official Image):由Docker官方团队维护和管理,具有高可靠性和稳定性,对个人用户有一定的速率限制
    • 已验证仓库(Verified Publisher):由Docker官方认证的大型组织,镜像质量有一定的保证
    • 赞助仓库(Sponsred OSS):由Docker公司赞助开发的镜像仓库,质量有保证
    • 无认证仓库(无标识):使用时确实需要仔细评估来源和维护记录,以确保安全性和可靠性
  4. Docker镜像仓库标签
    • 镜像中心Registry:存放着很多由官方、其他机构或个人创建的Docker仓库
    • 仓库 Repository:Docker镜像仓库保存相关的一组镜像,这组镜像都与镜像仓库名称相同
    • 标签Tag:通过:即可唯一定位一个宿主机上的具体镜像

镜像分层

  1. 镜像分层构成
    • 基础层/顶层(Base Layer):处于镜像的最底层,基本是一个完整的rootfs,包含操作系统运行时所需的基本组件,通常是各种Linux系统镜像,如Ubuntu、CentOS等
    • 构建层 / 中间层(Build Layers):基于相邻的镜像下层,每次执行Dockerfile中的指令(如RUN, COPY, ADD等)都会创建一个新的只读镜像层,每个层只存储了与父层不同的增量变化,从而实现存储优化
    • 可写层 / 容器层(Writable Layer):处于容器的最顶层,Docker通过联合文件系统(UnionFS)实现在只读层中进行读操作在可写层中执行写操作,从而实现统一视角下容器可读可写的文件系统
    • 核心:Docker镜像由一些松耦合的只读镜像层组成,DockerDaemon负责堆叠这些镜像层,并将它们关联为一个统一的整体, 即对外表现出的是一个独立的对象,镜像在被拉取时,按照自底向上顺序加载
      在这里插入图片描述
  2. 每个镜像层的组成
    • 层叠的文件系统(Layered File System):在Dockerfile中每执行一个指令(如RUN、COPY、ADD等),都会创建一个包含该指令产生的对父层增量修改部分的新的文件系统,主要包含文件和目录等内容。
    • 元数据(Metadata):是一个JSON文件,主要包含容器运行时的配置信息,如环境变量、工作目录、入口命令等。
    • 父层指针(Parent Layer Pointer):除了最底层外,每个层都有一个父层指针,指向其相邻下层,从而方便共享相同的底层镜像。
    • ImageID:Docker镜像在宿主机的唯一标识符,基于镜像层内容及构建历史计算而来,确保了内容的唯一性和完整性
  3. 镜像分层的优点
    • 只读保护:镜像的所有分层是只读的,通过创建新层实现增量修改,保障镜像分层数据的完整性
    • 节省存储空间:每个镜像分层只记录增量变化,而不是镜像下层的完整副本
    • 高效共享与增量更新:多个镜像可以共享相同的底层镜像层,当拉取或更新镜像时,若本地已缓存则可直接使用,若本地未缓存可只拉取有变化的层,从而加快了镜像的构建和部署,降低了网络资源的占用。
    • 灵活构建:基于Dockerfile指令序列创建新层的机制,有利于构建和优化镜像
    • 统一视图:基于联合文件系统实现多层镜像的统一处理,从而对外表现出统一的可读可写
  4. linux中文件系统的启动流程(整理镜像的文件系统层面的改进)
    • bootfs:系统加电后,从磁盘第一个扇区读取MBR,MBR加载bootloader,再由bootloader加载内核并转移控制器kernel。
    • rootfs:linux的基础文件系统,系统所需的目录结构、工具和库文件,并负责挂载其他文件系统,为用户提供操作系统的功能和接口。
      在这里插入图片描述
  5. Docker如何对文件进行增删改查
    • ?写时复制/增量修改(Copy-On-Write,简称COW):当修改共享数据时,先复制将要修改的部分,然后在该副本上进行修改。
    • 联合文件系统(UnionFS):通过上层文件系统覆盖下层相同路径文件的机制,实现了多层镜像的顺序叠加。结合写时复制(Copy-On-Write, COW)策略,基于只读镜像层可写层创建副本进行增量修改,从而将所有镜像层合并为一个统一高效的文件系统
    • 增加:只在容器最上层的可写层进行增加操作,不影响其他镜像层
    • 删除:采用软删除(逻辑上标记已删除),可以快速删除和还原
    • 修改:自顶向下查找,找到后先复制到容器层,然后直接修改容器层的文件
    • 查找:命中内存的缓存则直接使用,若没有命中则自顶向下查找到后加载到内存后访问

ImageID和镜像摘要

  1. ImageID的计算
    • 基础层镜像的diffID与chainID是一致的
    • 构建层的ImageID由文件系统的增量变更layer.tar文件哈希计算得到的diffID+父层的chainID 再进行哈希得到。
  2. ImageID(镜像ID)和Digest(镜像摘要)的区别
    • ImageID(镜像ID)
      • 本地唯一标识符:基于镜像配置和历史记录哈希计算得到的本地唯一标识符,通常是一个长的哈希值。这个ID用于在宿主机上唯一地引用和管理镜像。
      • 构建和拉取时生成:每次构建或从远程仓库拉取镜像时,都会生成一个新的Image ID,即使镜像的内容没有变化
    • Digest(镜像摘要)
      • 内容验证:基于镜像内容通过哈希算法(SHA256)计算得出的全球唯一标识符
      • 分布式一致性:与Image ID不同,内容一致的镜像不同宿主机上的digest是相同的,可用于保证分发和部署镜像的内容完整性
      • 基于内容的区分:可以区分相同:的不同镜像,避免标签重定向无法获取指定版本镜像的问题
  3. 如何基于Digest保证镜像分发的内容一致性
    • 在镜像压缩后立即计算散列值,然后将该值与压缩镜像一同发送,接收方计算压缩后镜像的分发散列值与传输的分发散列值进行比较,若相同则传输证明无误。
  4. Docker镜像的唯一标识与缓存机制
    • 唯一标识:通过计算镜像的文件系统内容和JSON配置文件的SHA256哈希值来生成唯一的Digest(摘要),这个Digest作为镜像的全局唯一标识符(通常称为镜像ID)。这意味着,即使镜像从不同的源头获取,只要其内容和配置完全相同,就会获得相同的镜像ID,从而支持镜像的识别和共享。
    • 映像缓存:Docker使用镜像ID来进行镜像层的缓存和共享。如果已有一个具有相同镜像ID的镜像层存在于本地,Docker会重用该层,减少镜像的下载和存储空间。

三、Docker引擎

概述

  1. 现代Docker引擎的核心组件
    • Docker Client(客户端):用户与Docker引擎交互的指令工具,通过向Docker daemon发送指令控制和管理容器、镜像、网络和存储卷等资源。
    • Docker daemon(守护进程):Dockerd是Docker的后台守护进程。
      • 承上:Dockerd监听来自客户端的RESTful API请求并执行
      • 启下:Dockerd通过gRPC协议与Containerd通信,执行容器和镜像的管理任务。
    • Containerd:提供模块化且符合CRI标准(可与k8s直接交互)的容器生命周期全面的管理能力
    • Runc:遵循OCI(开放容器倡议)标准的容器运行时工具,直接与系统内核交互,只专注于容器执行
    • Shim(垫片):是一个辅助进程,用于实现容器进程和守护进程的解耦,确保容器进程和守护进程的稳定性以及独立性在这里插入图片描述
  2. 容器的创建流程
    • Docker Client将命令通过TCP协议发送给Docker Daemon
    • Docker Daemon通过gRPC接口与Containerd通信,发送创建容器的请求。
    • Containerd 会fork一个子进程Shim,Shim再fork一个子进程来执行Runc,进行实际的容器创建
    • 容器创建完成后,Runc进程退出并将控制权交给对应的Shim,从而实现daemon和Container的解耦合
      在这里插入图片描述

容器

  1. 综述
    • Docker将应用程序及其依赖环境打包成镜像,并基于镜像内容的通过哈希计算得到的Digest(镜像摘要)实现完整性传输
    • Linux Namespace机制实现容器间资源的隔离,而Linux Cgroup机制容器所需资源进行控制和管理
    • Docker基于镜像
    • 写时复制的机制,通过创建只包含变化部分的副本层来实现增量更新存储优化
      在这里插入图片描述
  2. 基本定义
    • 静态容器:
    • 运行时容器:
    • 容器不是运行时镜像,静态容器和运行时容器还有差距
      容器定义:容器(container)的定义和镜像(image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。容器 = 镜像 + 读写层,docker create 命令为指定的镜像(image)添加了一个可读写层,构成了一个新的容器。注意,这个容器并没有运行
      运行容器的定义:可读写的统一文件系统+隔离的进程,Docker start命令为容器文件系统创建了一个进程隔离空间。注意,每一个容器只能够有一个进程隔离空间
      文件系统隔离技术使得Docker成为了一个前途无量的技术。一个容器中的进程可能会对文件进行修改、删除、创建,这些改变都将作用于可读写层(read-write layer)
  3. 容器和虚拟机的区别
    • 隔离性
      • 虚拟机基于硬件虚拟化技术实现操作系统级别的隔离
      • Docker容器共享宿主机操作系统内核,但基于Linux的namespace和cgroups实现了进程级别的隔离
    • 占用资源
      • Docker是进程级别的应用程序,启动迅速,占用资源少,更适合快速部署和扩展。
      • 虚拟机是是一个完整的操作系统,需要占用大量的磁盘、内存和 CPU 资源
    • 适用场景
      • 虚拟机适合需要高度隔离和安全性的应用
      • Docker容器则更侧重于轻量化和快速部署的场景
        在这里插入图片描述

容器操作指令

  1. 创建容器:docker create <image_name>
    • 原理:为指定镜像增加一个可写层,并完成相关资源和环境的配置,但该容器未实际运行。
    • 每一个容器只有一个进程隔离空间,只能运行一个主进程
    • 通常会将指定的命令或默认的入门点(entrypoint)作为该容器的主进程
      在这里插入图片描述
  2. 启动容器:docker start <container_name>
    • 原理:恢复已创建但处于停止状态的容器的运行状态(类似进程上下文恢复)
  3. 运行容器:docker run <image_name>
    • 创建并启动容器,docker run = docker creat + docker start在这里插入图片描述
  4. 列出所有容器(包含非运行态):docker ps –a
  5. 所有镜像顶层(top-level)docker images
    • 仓库名称(Repository):镜像的名称,可以包括仓库和标签,如ubuntu:latest
    • 标签(Tag):镜像的版本标签,如latest,如果没有指定标签,默认显示为
    • 镜像ID(Image ID):镜像的唯一标识符,每个镜像有一个唯一的长ID
    • 创建日期(Created):镜像创建的时间。
    • 大小(Size):镜像的大小,注意显示的大小通常不包括共享层的大小。
  6. 显示本地存储的所有镜像(包括所有镜像分层及没有标记的镜像):docker images -a
  7. 查看指定镜像的构建历史步骤:docker history <image_name>
  8. 停止容器
    • docker stop <container_name>:向容器内的主进程发送SIGTERM信号,给予10秒响应信号,若超时则会自动发送一个SIGKILL信号来强制停止容器
    • docker kill <container_name>:立即向容器内的主进程发送SIGKILL信号,这是一种不可忽略的信号,用于强制终止进程
    • docker pause <container_name>:通过linux cgroup技术进行容器上下文的保持,等待被docker unpause命令恢复
  9. 删除指定容器: docker rm <container_name>
    • 原理:删除可读写层和相关的配置文件
    • 只能删除运行中的容器,如果强制删除使用-f,Docker会先发送SIGKILL信号来停止容器,然后再进行删除(不推荐使用)
  10. 删除指定镜像:docker rmi <image_name/id>
    • 原理:删除镜像最顶层,-f可以删除镜像的中间层
    • 默认无法删除正在被容器使用的镜像,可使用-f强制删除,但是尽量不要使用,以防止意外删除正在使用中的资源。
    • 在执行删除操作之前,使用docker images命令查看镜像列表,可以帮助你确定要删除的镜像ID或确认镜像是否被使用
  11. 创建新镜像:docker commit -a <author_message> -m <submit_information> <container_name>
    • 更改持久化:可以基于运行中的容器生成当前状态容器的镜像
    • 非最佳实践:commit可能将非必要更改包含在其中,而dockerfile具有明确的构建步骤
    • 使用场景:在开发过程中快速测试配置或在没有Dockerfile的情况下快速保存工作状态
  12. docker build -t <container_name>:<tag> \path\dockerfile
    • 通常使用docker build -t <container_name>:<tag> .构建,最后.表示在当前路径构建,直接在当前路径构建可以引用相对路径编写dockerfile,避免绝对路径变更出错
    • 原理:从FROM指令中获取基础镜像,然后重复执行1. run(create和start)2. 修改 3. commit,在每个循环中形成一层新的镜像在这里插入图片描述
  13. 在运行时容器中执行指令:docker exec <container> <command>
    • 只能对正在运行的容器执行docker exec命令。如果容器已停止,需要先启动容器
    • 默认情况下,命令以容器内的root用户执行,但通过-u选项可以指定其他用户,以提高安全性。
    • 示例:进入容器内的交互式终端docker exec -it my_container /bin/bash
  14. 默认返回一个JSON格式的Docker对象详细信息: docker inspect <container_name>
  15. 将镜像保存为一个tar压缩文件: docker save -o <self_name>.tar <image_name1>:<tag> ...
    • 保存的tar文件包含了镜像的所有层,以及相关的元数据
    • 备份:定期备份关键的镜像,以防数据丢失。
    • 迁移:传输镜像tar文件,从而实现应用程序和环境的迁移
  16. 将容器文件系统压缩成tar文件:docker export my_running_container > container_data.tar
    • 仅限文件系统:导出的tar文件是容器统一多层文件系统的最顶层(只有一层),并且不包括其他依赖镜像层及元数据等信息
    • 不包含卷数据:如果容器内部使用了数据卷,这些卷的数据不会被导出,因为它们是独立于容器的。
    • 运行状态:要求容器必须是运行状态或最近停止的状态,才能被导出
  17. 展示指定镜像的创建历史:docker history <image_name>:<tag>
    • 展示镜像的构建过程和每一层的详细信息

四、Dockerfile

简介

  1. 定义:Dockerfile 是用来构建 Docker 镜像的脚本文件。它由一系列的指令组成,这些指令按照顺序逐行执行,通过这些指令可以定义镜像的内容、环境和行为。
  2. 基本指令
    • 基础镜像选取:通过 FROM 指令指定基础镜像,这是构建镜像的起点。
    • 环境配置:使用 RUN 指令执行命令,比如安装软件包,配置环境。
    • 文件复制:利用 COPY 或 ADD 指令将本地文件复制到镜像中,用于构建应用。
    • 命令设置:通过 CMD 或 ENTRYPOINT 指令定义容器启动时运行的默认命令。
    • 环境变量:使用 ENV 指令设置环境变量,供容器内应用使用。
    • 工作目录:用 WORKDIR 指定容器内的默认工作目录。
    • 用户管理:通过 USER 指令切换运行命令的用户。
    • 健康检查:使用 HEALTHCHECK 指令定义容器健康状态的检查方法。
    • 构建缓存:通过合理的指令顺序和多阶段构建策略优化构建过程,减少重复步骤,加快构建速度。
  3. Dockerfile脚本编写原则
    • Dockerfile指令不区分大小写,但是一般约定指令大写,参数小写
    • 以 # 开头的行视为注释,其他位置都视为参数
    • Docker按序执行Dockerfile 中的指令
    • 解析器指令不支持连续相同多条语句
  4. 创建Dockerfile
    • vim Dockerfile:默认文件名字必须为Dockerfile
    • docker tag <old-name> <new-name>:<tag>:镜像tag重命名
    # 用于指定基础镜像,且必须在指令序列中排在第一位,其中若tag省略默认为latest
    FROM <image>:tag 
    # 在构建Docker镜像时指定容器的挂载点
    VOLUME ["/app/data"]
    # 以键值对形式代替MAINTAINER表达文件其他详细信息
    LABEL version="1.0" author="Sen" email="xxx@qq.com"
    # 容器打开后的默认目录,后续的WORKDIR都是基于前面的相对路径
    WORKDIR path# 复制宿主机中的指定文件到容器中的指定目录,相对路径相对于docker build命令所指定的路径,
    # src若指定的压缩文件会自动解压,dest是绝对路径最后必须使用/作为目录结束
    # 将所要拷贝的文件和Dockerfile放到同一个文件夹中,可以避免相对路径错误
    ADD <host-src> <container-dest/> 
    # 变量的定义,在下文中的可以使用$var引用变量的值,也可在docker build中使用`--build-arg var=xxx`进行指定
    ARG var=xxx
    # 指定环境变量,可用于RUN运行
    ENV <key> <value> /  <key>=<value>, <key>=<value> ...
    # 用当前镜像的子镜像构建时会执行的指令
    ONBUILD <commamd>
    # 默认使用的端口号,-p指定的会覆盖该端口号,一般给配置人员看
    EXPOSE <端口号># 无法被docker run后面的命令所覆盖
    ENTRYPOINT ["executable","param1","param2", ...] # 容器启动后要运行的命令,有直接命令和命令-参数形式,会被docker run后面的命令替换
    CMD <command> / ["executable","param1","param2", ...] 
    # CMD和ENTRYPOINT可以连用,ENTRYPOINT后面加指令,CMD后面加命令参数
    
  5. scratch镜像
    • scratch镜像是一个空镜像,作为所有镜像的基础镜像,不能通过pull命令拉取,也不能run,没有tag
    • 不会生成镜像中的文件系统层
    • 作为保留关键字,用户不能使用scratch作为自己的镜像名称。
  6. 悬虚镜像
    • 不如普通镜像有用,没有:标识
    • 删除方式:docker rmi / docker system prune(删除四类) / docker image prune(仅删除一类)
    • 悬虚镜像
  7. 构建新镜像的方式
    • docker build.
    • docker commit.
    • docker import(注意,docker load 并没有构建出新的镜像,其与原镜像是同一个镜像)
    • docker compose
    • docker hub 中完成Automated Builds.
  8. 镜像构建示例
    #  定义基础镜像层为ubuntu:14.04
    FROM ubuntu:14.04
    # 将当前目录下的run.sh文件复制到新构建的镜像的根目录下
    ADD run.sh /
    # 在容器的/data目录下创建一个挂载点,任何写入该路径下的数据都会被保存宿主机目录,从而实现数据持久化
    VOLUME /data
    # 设置容器默认的启动命令为执行根目录下的run.sh脚本
    CMD [“./run.sh”]
    

在这里插入图片描述

指令详解

  1. 构建基本镜像:FROM <image>:<tag>
    • 指定基础镜像:是基础镜像的名称,是版本标签,默认为latest
    • 环境变量支持:可以使用ARG指令预先声明的环境变量
    • 默认行为:如果指定的基础镜像不存在于本地,Docker会尝试从Docker Hub或其他配置的注册表中拉取。
  2. 描述镜像的元数据信息:LEABEL <key>="<value>"
    • 参数信息通常使用键值对形式
    • 提供额外的镜像描述信息,从而便于维护和筛选
    LABEL email="example@example.com" \author="SampleApp" \version="1.2.3" \description="This is a sample Docker image."
    
  3. 指定容器内的计算机目录为匿名数据卷:VOLUME /container/path
    • 在运行容器时使用docker run -v /host/path:/container/path,比较/container/path与Dockerfile中通过VOLUME指定的路径
      • 路径一致:宿主机目录和对应的容器目录会建立直接映射
      • 路径不一致:两者各自独立挂载,VOLUME会创建一个匿名数据卷并挂载到宿主机默认docker管理目录下(通常/var/lib/docker/volumes/)
  4. 设置容器内部工作目录:WORKDIR /work/directory
    • 设置WORKDIR后,Dockerfile中后续的命令都将相对于该路径执行
    • 多次使用WORKDIR,可以基于上次目录继续生成相对目录WORKDIR /app + WORKDIR data = /app/data
  5. 定义参数变量:ARG KEY_NAME=value
    • 变量名一般使用大写和下划线,例如BASE_IMAGE_VERSION
    • 变量的使用需要使用$+变量名
    • ARG多次定义的相同变量名,后面会覆盖前面的值
  6. 用于定义环境变量:ENV VAR_NAME=value
    • 在容器运行时,通过命令docker run -e覆盖dockerfile中的ENV,eg:docker run -e VAR_NAME=value
  7. 将宿主机的源文件或目录内容复制到容器目标路径下:COPY <宿主机的源文件或目录> <容器的目标路径>
    • 若要复制整个目录的内容,只需指定目录名即可,eg:COPY host /docker/directory
    • <宿主机的源文件或目录>:尽量将所要复制的内容放在当前目录下使用相对路径,避免绝对路径的更改
    • <容器的目标路径>:可以是绝对路径(以斜杠/开始)或相对于WORKDIR的相对路径
    • COPY复制文件时会保留源文件的元数据,包括权限、时间戳等
    • 如果目标路径不存在,COPY会自动创建必要的目录结构。
    • 复制多个源文件到单个目标时,目标必须是一个目录
    • 与ADD指令相比,COPY不提供解压文件或从URL下载文件的功能
    • 由于ADD可能会从URL下载文件,这增加了潜在的安全风险,比如下载恶意软件。而COPY仅处理本地文件,避免了网络相关的安全问题,使得构建过程更加安全可靠。
    • 使用COPY时,每次复制的文件内容变化都会导致一个新的镜像层,但不会因为额外的处理(如解压)而引入不可预知的层。这有助于保持镜像的精简和可追踪性。
    • 根据Docker官方文档的推荐,COPY是构建镜像时的首选指令,除非确实需要ADD的特殊功能,这表明在大多数场景下,COPY是更符合最佳实践的选择
  8. 将宿主机的源文件/目录/网络文件拷贝到容器目标路径下:ADD <源文件/目录/网址> <容器的目标路径>
    • 支持拷贝同时解压文件,支持从URL下载,支持通配符匹配。以上均存在安全性或不确定性,所以推荐使用COPY
    • 在使用ADD时,要确保源文件或URL是可靠的,以避免潜在的安全风险。
  9. 用于构建镜像过程中切换指定用户:USER <用户名UID>[:<用户组GID>]
    • 确保应用程序仅拥有执行其任务所需的最小权限,遵循最小权限原则
    • 避免以root用户运行容器,减少潜在的安全风险
    # 创建并切换到用户态进行执行
    FROM ubuntu:latest
    RUN useradd -ms /bin/bash myuser
    USER myuser
    # 创建并切换到指定组的用户进行执行
    FROM python:3.8-slim
    RUN useradd -r -u 1000 -G users appuser
    USER 1000:users
    
  10. 定义容器健康状态的检查配置:HEALTHCHECK <OPTIONS> CMD <command>
FROM nginx:latest
# check_health.py是一个Python脚本,用于检查应用的健康状态
# 每5分钟执行一次健康检查,命令执行时间不超过3s,连续5次执行失败则标记为不健康
HEALTHCHECK --interval=5m \--timeout=3s \--retries=5 \ CMD  /app/check_health.py
  1. 设置容器启动时默认执行的命令:CMD ["executable", "param1", "param..."]
    • 覆盖性:docker run在启动容器时指定命令可以覆盖CMD指定的命令
    • 唯一性:Dockerfile中的多个 CMD 指令,但只有最后一个CMD命令会生效,因为默认行为是唯一的
  2. 设置容器启动时默认执行的命令:ENTRYPOINT ["executable", "param1", "param..."] (最有通用性)
    • 仅可自定义参数:docker run无法覆盖ENTRYPOINT指定的启动命令,只能添加参数。
    • 用户可以通过 docker run --entrypoint 选项来指定新的命令来替代原有的 ENTRYPOINT,但不常用

五、数据持久化

简介

  1. 可写层与容器生命周期绑定,若容器被删除或重启,数据修改将丢失。常见的数据持久化方式
    • 实时同步方式
      • 数据卷(volumes)
      • Bind mounts(绑定挂载)
      • tmpfs(临时文件系统):动态存储在内存上,提供高效的实时同步,但是无法避免系统重启带来的风险
    • 非实时同步方式
      • 定制镜像: 将这个修改过的容器复制生成一个新的镜像,但是无法实现实时同步
  2. 什么是 Docker 数据卷(Docker volumes)?
    • Docker 数据卷是一种持久化数据的机制,它允许在容器和宿主机之间创建一个独立于容器生命周期的存储区域。数据卷是一个特殊的目录,存在于容器内部,但直接映射到宿主机的文件系统上。这样设计的主要目的是为了数据的持久化和共享,确保即使容器被删除或重启,数据仍然存在且可访问
      • 数据持久化:数据卷属于宿主机文件系统,独立于容器,所以容器的删除不会影响数据卷中的数据
      • 即时同步:通过宿主机数据卷(文件/目录)映射到容器挂载点,从而实现目录修改内容的即时同步
      • 共享与重用:多个容器可以挂载同一个数据卷,实现数据共享
      • 镜像解耦:数据卷中的数据不会因为镜像的更新而丢失或被覆盖
  3. 什么是主机目录绑定挂载(bind mounts)?
    • 主机目录绑定(bind mounts)是将宿主机上的一个目录或文件直接映射到容器内的一个路径。这种绑定挂载允许容器直接访问宿主机的文件系统路径,提供了更直接的共享方式。bind mounts的特点包括:
      • 直接宿主机路径:bind mounts可以使用宿主机的绝对路径,访问其目录或文件
      • 非移植性:由于bind mounts依赖于宿主机的特定路径,这可能影响容器的可移植性。
      • bind mounts则更简单直接,适合快速共享或临时数据共享场景。

数据卷相关命令

  1. 数据卷的创建:docker volume create <volume_name>
  2. 数据卷的挂载
    • docker run -it -v </host/path>:</container/path> <image_name>
    • docker run -it -v </host/path>:</container/path>:ro <image_name>:挂载点只读,即容器不可修改
    • 数据卷与挂载点实时共享,与容器是否启动无关
  3. 查看系统中所有的数据卷:docker volume ls
  4. 删除数据卷(不可逆操作):docker volume rm <volume_name>

六、Docker网络通信

简介

  1. docker exec <container-name> ip a:查看容器的ip地址
  2. 同一宿主机的容器间,容器和宿主机间以及容器和宿主机外联的互联网间都可以进行通信
  3. Docker网络的底层原理是Linux的Network Namespace,对Namespace的理解很重要!
  4. Network Namespace是Linux内核提供的功能,用于实现网络虚拟化,它可以创建多个隔离的网络空间。每个网络命名空间都是独立的,具有自己的防火墙、网卡、路由表、邻居表和协议栈。无论是虚拟机还是容器,当它们运行在独立的命名空间时,就像是独立的主机一样,彼此之间的网络环境互不影响。
  5. 两个网络命名空间之间的通信,实质就是两个容器间的通信
  6. 创建虚拟网卡+绑定IP+设置为通信状态+
  7. 创建虚拟网卡+绑定IP+设置为通信状态+
  8. ip link add veth-ns1 type veth peer name veth-ns2: 创建一对相互关联的虚拟网卡
  9. 虚拟网卡绑定网络命名空间
    • ip link set veth-ns1 netns ns1
    • ip link set veth-ns1 netns ns1
  10. ip netns exec ns1 ip a:查看ns1的网卡配置信息
  11. 在命名空间中给虚拟网卡绑定ip地址
    • ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth-ns1
    • ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth-ns2
  12. 启动虚拟网卡
    • ip netns exec ns1 ip link set dev veth-ns1 up
    • ip netns exec ns2 ip link set dev veth-ns2 up

CNM

  1. Docker网络框架由三个主要部分组成:CNM、Libnetwork和Driver组成
  2. 定义:CNM,即Container Network Model,是Docker容器网络的核心设计规范,它定义了一套标准化的框架来管理容器的网络连接。以下是CNM模型的关键要素及其详细说明
    • 沙盒(Sandbox):
      • 沙盒代表一个独立的网络栈,为每个容器提供隔离的网络环境。
      • 它包含一系列网络配置,如以太网接口、端口配置、路由表条目以及DNS设置。
      • Linux Network Namespace是实现沙盒隔离的标准方式,确保每个容器的网络资源独立。
    • 终端(Endpoint):
      • 终端是虚拟的网络接口,负责建立沙盒与特定网络之间的连接。6
      • 每个终端连接到一个特定的网络,是容器与网络交互的接口。
      • 一个终端仅能连接到一个网络,但一个沙盒可以有多个终端,从而连接到不同的网络。
    • 网络(Network):
      • 在CNM模型中,网络是逻辑上的集合,它定义了终端如何交互,可以理解为一组终端共享的通信平面。
      • 实际上,它通常通过软件实现的802.1d网桥来模拟,允许容器间的通信就像它们连接在同一个物理交换机上一样。
      • 网络可以配置特定的IP地址范围、子网、网关等,为连接到该网络的终端提供一致的网络环境。
  3. 一个主机可以有多个网卡,并且每个网卡都可以配备一个IP地址
    在这里插入图片描述
  4. Docker引擎调用API发出请求,然后由Libnetwork做出框架性处理,然后将请求转发给相应的驱动Driver
    在这里插入图片描述
  5. 在Linux主机上,Docker的bridge网络是通过Bridge驱动创建的,它使用了Linux Bridge技术。在创建时会自动创建一个默认的网桥docker0。容器与网桥之间使用veth pair技术进行连接,网桥与外网之间使用网络地址转换NAT技术进行连接,实现将内网地址转换为外网地址的功能。
    在这里插入图片描述

Docker网络相关指令

  1. 创建Docker网络
    • docker network create -d bridge <bridge-name>:默认不指定则网卡类型仍然为bridge
    • docker run --name <container-name> --network <bridge-name> busybox:给网桥添加容器网络接口
    • docker inspect <container-name>:查看容器配置
    • docker exec <container-name> ip a:查看容器的ip地址
    • docker exec <container1> ping <container2>:同一个bridge网络中的可以使用容器名称代替IP地址
    • docker run -d --name <container-name> --network host :指定创建容器为host网络
  2. 容器的网络类型
    • none网络:容器仍然属于一个独立的Namespace,但没有网络接口和IP地址
    • host网络:与宿主机host共用一个Network Namespace,没有独立的IP,与host共用


少年,我观你骨骼清奇,颖悟绝伦,必成人中龙凤。
不如点赞·收藏·关注一波


🚩点此跳转到首行↩︎

参考博客

  1. Docker系列五——Docker容器隔离原理及网络通信
  2. 10张图带你深入理解Docker容器和镜像
  3. Docker——镜像原理之联合文件系统和分层理解
  4. Docker中镜像层的diffID如何计算?
  5. docker imageid 和 digest区别
  6. 联合文件挂载——待参考完善
  7. Docker原理——待参考完善
  8. 什么是容器技术
  9. 数据卷——待参考完善

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/399594.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【云原生】高可用集群KEEPALIVED(理论篇)

一、高可用集群 1.1 集群类型 LB:Load Balance 负载均衡 LVS/HAProxy/nginx(http/upstream, stream/upstream)HA:High Availability 高可用集群数据库、RedisSPoF: Single Point of Failure&#xff0c;解决单点故障HPC: High Performance computing 高性能集群 1.2 系统可用…

车身域测试学习、CANoe工具实操学习、UDS诊断测试、功能安全测试、DTC故障注入测试、DBC数据库、CDD数据库、CAN一致性测试、ECU刷写测试

每日直播时间&#xff1a;&#xff08;直播方式&#xff1a;腾讯会议&#xff09;周一到周五&#xff1a;20&#xff1a;00-23&#xff1a;00周六与周日&#xff1a;9&#xff1a;00-17&#xff1a;00 进腾讯会议学习的&#xff0c;可以关注我并后台留言 直播内容&#xff1a;&…

OKnews加密货币资讯:现货比特币ETF市场动荡,价格大幅下跌

OKnews加密货币资讯网8月13日讯&#xff1a;现货比特币ETF 市场近期的动荡给加密货币行业带来了冲击&#xff0c;导致比特币 (BTC) 未能维持其在关键的60,000美元大关之上的地位。该数字货币在过去24 小时内下跌了 3.65%&#xff0c;跌至58,515 美元。市场波动加剧以及对美国经…

人脸操作:从检测到识别的全景指南

人脸操作&#xff1a;从检测到识别的全景指南 在现代计算机视觉技术中&#xff0c;人脸操作是一个非常重要的领域。人脸操作不仅包括检测图像中的人脸&#xff0c;还涉及到人脸识别、表情分析、面部特征提取等任务。这些技术在各种应用中发挥着关键作用&#xff0c;从社交媒体…

中国科技统计年鉴,数据覆盖1991-2022年多年份

基本信息. 数据名称: 中国科技统计年鉴 数据格式: excel 数据时间: 1991-2022年 数据几何类型: xlsx 数据坐标系: WGS84 数据来源&#xff1a;国家统计局 数据预览&#xff1a; 数据可视化.

(kali关怀版)kali调整字体图标显示大小

字体大小调整(图标字体) 字体在左上角搜apprence 图标大小调整 图标在桌面右键点apprence 任务栏大小调整 任务栏在上面右键&#xff0c;选择panel preference 终端字体大小调整 终端字体用ctrl和加号减号进行缩放 属于是kali关怀版了:) 还可指定锁屏和休眠时间&#…

waveInAddBuffer死锁的大雷解决

项目场景&#xff1a; 从来没有一个bug让我这么抓狂&#xff0c;足足查了3天3夜&#xff0c;官方文档翻了一遍说的基本无用。具体项目就是使用waveIn系列函数获取windows系统麦克风数据&#xff0c;虽然windows上有好几种方法获取麦克风数据&#xff0c;我最终还是选择了它。 …

Springboot整合hutool验证码

在 Spring Boot 中&#xff0c;你可以将 Hutool 生成验证码的功能集成到 RESTful API 接口中。 依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.14</version> <!-- 使用最新版…

pytorch,用lenet5识别cifar10数据集(训练+测试+单张图片识别)

目录 LeNet-5 LeNet-5 结构 CIFAR-10 pytorch实现 lenet模型 训练模型 1.导入数据 2.训练模型 3.测试模型 测试单张图片 代码 运行结果 LeNet-5 LeNet-5 是由 Yann LeCun 等人在 1998 年提出的一种经典卷积神经网络&#xff08;CNN&#xff09;模型&#xff0c;主要…

Solana真假繁荣调查:机器人横行占7成交易,Meme数据下滑严重

随着Solana链上数据全面赶超以太坊&#xff0c;关于Solana将超越以太坊的讨论逐渐升温。然而&#xff0c;与此同时&#xff0c;关于Solana真实繁荣度的争议也引发了广泛关注。本文将深入探讨Solana生态中机器人泛滥、交易量数据虚高、MEV问题、财务亏损问题&#xff0c;以及SOL…

从零搭建xxl-job(四):xxljob进行一些性能优化

之前的代码这部分并没有补充完毕&#xff0c;假如调度中心如果判断有定时任务要执行了&#xff0c;该怎么远程通知给执行定时任务的程序呢&#xff1f;当定时任务要把自己的信息发送给调度中心时&#xff0c;是通过一个RegistryParam对象发送的。该对象内部封装了定时任务相关的…

【C#】explicit、implicit与operator

字面解释 explicit&#xff1a;清楚明白的;易于理解的;(说话)清晰的&#xff0c;明确的;直言的;坦率的;直截了当的;不隐晦的;不含糊的。 implicit&#xff1a;含蓄的;不直接言明的;成为一部分的;内含的;完全的;无疑问的。 operator&#xff1a;操作人员;技工;电话员;接线员;…

HarmonyOS应用开发者高级认证(一)

1、依次点击A、B、C、D四个按钮&#xff0c;其中不会触发UI刷新的是&#xff1a; 答案&#xff1a; Button("C").onClick(() > {this.nameList[0].name "Jim"})分析&#xff1a;直接更新非一级数据不会触发UI刷新 2、如果要实现Row组件内的子元素均匀…

基于JSP的个性化影片推荐系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;JSP 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;MyEclipse、Tomcat、MySQL 系统展示 首页 管理员功能模块 用户功能模块 …

Rancher的RKE和RKE2部署K8s集群kube-proxy开启strictARP

kube-proxy配置strictARPtrue 1、非RKE部署的K8s集群&#xff1a;配置首先&#xff0c;需要为kube-proxy启动strictARP&#xff0c;以便Kubernetes集群中的所有网卡停止响应其他网卡的ARP请求&#xff0c;而由OpenELB来处理ARP请求。 $ kubectl edit configmap kube-proxy -n…

C# 在Word中插入或删除分节符

在Word中&#xff0c;分节符是一种强大的工具&#xff0c;用于将文档分成不同的部分&#xff0c;每个部分可以有独立的页面设置&#xff0c;如页边距、纸张方向、页眉和页脚等。正确使用分节符可以极大地提升文档的组织性和专业性&#xff0c;特别是在长文档中&#xff0c;需要…

【STM32】USART通用同步/异步收发器(串口数据的接收与发送)

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 USART简介 USART时钟使能 USART初始化 串口参数 串口数据时序 USART中断配置 USART使能 数据的接收与发送 Serial.h Serial.c main.c USART简介 USART&#xff08;Universal S…

leedCode - - - 栈和队列

目录 1.有效的括号&#xff08; LeetCode 20 &#xff09; 2.最小栈&#xff08; LeetCode 155 &#xff09; 3.接雨水&#xff08; LeetCode 42 &#xff09; 4.逆波兰表达式求值&#xff08;LeetCode 150&#xff09; 5.柱状图中最大的矩形&#xff08;LeetCode 84&…

计算机毕业设计选题推荐-大学生就业招聘管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

【Redis】Redis 初探:特性、应用场景与高并发架构演进之路

目录 初识 Redis关于 Redis服务端高并发分布式结构演进之路概述常⻅概念基本概念应⽤&#xff08;Application&#xff09;/ 系统&#xff08;System&#xff09;模块&#xff08;Module&#xff09;/ 组件&#xff08;Component&#xff09;分布式&#xff08;Distributed&…