1. 是什么

Docker 是一种轻量级的虚拟化技术,同时是一个开源的应用容器运行环境搭建平台,可以让开发者以便捷方式打包应用到一个可移植的容器中,然后安装至任何运行 Linux 或 Windows 等系统的服务器上。相较于传统虚拟机,Docker 容器提供轻量化的虚拟化方式、安装便捷、启停速度快。
Docker 是基于 Go 语言实现的云开源项目。
Docker 的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的 APP(可以是一个 WEB 应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”。

image.png

2. 运行原理 (解决问题)

2.1. 大型项目众多应用组件间依赖和配置不兼容

image-20210731142219735
Docker 为了解决依赖的兼容问题的,采用了两个手段:

- 将应用的 Libs(函数库)、Deps(依赖)、配置与应用一起打包,形成可移植镜像
- 将每个应用放到一个隔离 容器 去运行,使用沙箱机制进行隔离,避免互相干扰

这样打包好的应用包中,既包含应用本身,也保护应用所需要的 Libs、Deps,无需再操作系统上安装这些,自然就不存在不同应用之间的兼容问题了。

虽然解决了不同应用的兼容问题,但是开发、测试等环境会存在差异,操作系统版本也会有差异,怎么解决这些问题呢?

2.2. 应用部署环境及系统存在差异

2.2.1. 系统应用与系统交互逻辑

要解决不同操作系统环境差异问题,必须先了解操作系统结构。以一个 Ubuntu 操作系统为例,结构如下:
image-20210731143401460

从下往上依次来看,结构包括:

  • 计算机硬件:例如 CPU、内存、磁盘等
  • 系统内核:所有 Linux 发行版的内核都是 Linux,例如 CentOS、Ubuntu、Fedora 等。内核可以与计算机硬件交互,对外提供 内核指令,用于操作计算机硬件。
  • 系统应用:操作系统本身提供的应用、函数库。这些函数库是对内核指令的封装,使用更加方便。

应用与计算机交互的流程如下:

1)应用调用操作系统应用(函数库),实现各种功能
2)系统函数库是对内核指令集的封装,会调用内核指令
3)内核指令操作计算机硬件

2.2.2. Docker 如何解决不同系统环境的问题

  • Docker 将用户程序与所需要调用的系统 (比如 Ubuntu) 函数库一起打包
  • Docker 运行到不同操作系统时,直接基于打包的函数库,借助于操作系统的 Linux 内核来运行
    image-20210731144820638

2.3. 优点

Docker 是一个快速交付应用、运行应用的技术,具备下列优势:

  • 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意 Linux 操作系统
  • 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
  • 启动、移除都可以通过一行命令完成,方便快捷

3. 与虚拟机区别

3.1. 优势分析

image.png

image.png

3.1.1. 资源占用小

由于容器不需要进行硬件虚拟,也不需要运行完整操作系统等额外的资源开销,使得 Docker 对系统资源的利用率更高,无论是应用执行速度还是文件存储速度,都要比传统虚拟机技术更高效,内存消 耗更少 。

3.1.2. 启动速度快

传统的虚拟机技术启动应用服务往往需要较长时间,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级,甚至毫秒级的启动时间,大大的节约了开发,测试,部署的时间。

3.1.3. 迁移更轻松

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易, Docker 可以在很多平台上运行,无论是物理机,虚拟机,公有云,私有云,它们的运行结果是一致的,因此用户可以很轻易的将一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行这类的问题。

3.1.4. 维护和拓展更轻松

docker 使用的分层存储和镜像技术,让应用重复部分的复用更容易,也让应用的维护更新更简单,基于基础镜像进一步扩展镜像也变得十分简单。另外,docker 团队和各个开源项目团队一起维护了一大批高质量的官网镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大降低了应用服务的镜像制作成本。

3.1.5. 运行环境一致

开发过程中一个常见的问题是环境一致性问题,由于开发环境,测试环境,生产环境不一致,导致有些 bug 并未在开发过程中被发现,而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。

3.1.6. 持续交付和部署

使用 Docker 可以通过定制应用镜像来实现持续集成,持续交付,部署。开发人员可以 通过 Dockerfile 来进行镜像构建, 并结合持续集成系统进行集成测试,而运维人员则可以在生产环境中快速部署该镜像, 甚至结合持续部署系统进行自动部署

3.2. 优势原因

image.png

4. 镜像和容器

4.1. 镜像和容器

镜像(Image):Docker 将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
容器(Container):镜像中的应用程序运行后形成的 [进程]就是 容器,只是 Docker 会给容器进程做隔离,对外不可见。

一切应用最终都是代码组成,都是硬盘中的一个个的字节形成的 文件。只有运行时,才会加载到内存,形成进程。
镜像,就是把一个应用在硬盘上的文件、及其运行环境、部分系统函数库文件一起打包形成的文件包。这个文件包是只读的。
容器 呢,就是将这些文件中编写的程序、函数加载到内存中运行,形成进程,只不过要隔离起来。因此一个镜像可以启动多次,形成多个容器进程。

image-20210731153059464

4.2. 虚悬镜像

仓库名、标签都是 none 的镜像,俗称虚悬镜像 dangling image

4.2.1. 产生原因

构建或者删除镜像时出错导致

4.2.2. 如何处理

查看: docker image ls -f dangling=true
删除: docker image prune
image.png

5. 数据卷

image.png

6. Dockerfile

%%
▶4.🏡⭐️◼️【🌈费曼无敌🌈⭐️♨️⭐️】◼️⭐️-point-20230318-2215%%
❕ ^dnlslf

6.1. 镜像结构

镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。
image-20210731175806273

简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。

我们要构建镜像,其实就是实现上述打包的过程。

6.2. Dockerfile 命令

构建自定义的镜像时,并不需要一个个文件去拷贝,打包。

我们只需要告诉 Docker,我们的镜像的组成,需要哪些 BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来 Docker 会帮助我们构建镜像。

而描述上述信息的文件就是 Dockerfile 文件。

Dockerfile 就是一个文本文件,其中包含一个个的 **指令 (Instruction)**,用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层 Layer。

6.3. 继承分层

image.png

image.png

image.png

6.4. ENTRYPOINT 与 CMD

https://blog.csdn.net/u010900754/article/details/78526443
https://cloud.tencent.com/developer/article/1906538
%%
▶1.🏡⭐️◼️【🌈费曼无敌🌈⭐️第一步⭐️】◼️⭐️-point-20230416-1721%%
❕ ^hhynot

6.4.1. CMD 可以被覆盖的来历

The main purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well.

意思是,cmd 给出的是一个容器的默认的可执行体。也就是容器启动以后,默认的执行的命令。重点就是这个“默认”。意味着,如果 docker run 没有指定任何的执行命令或者 dockerfile 里面也没有 entrypoint,那么,就会使用 cmd 指定的默认的执行命令执行。同时也从侧面说明了 entrypoint 的含义,它才是真正的容器启动以后要执行命令。
所以这句话就给出了 cmd 命令的一个角色定位,它主要作用是默认的容器启动执行命令。(注意不是“全部”作用)
这也是为什么大多数网上博客论坛说的“cmd 会被覆盖”,其实为什么会覆盖?因为 cmd 的角色定位就是默认,如果你不额外指定,那么就执行 cmd 的命令,否则呢?只要你指定了,那么就不会执行 cmd,也就是 cmd 会被覆盖。

6.4.2. 最佳实践

一般使用 entrypoint 的中括号形式作为 docker 容器启动以后的默认执行命令,里面放的是不变的部分,可变部分比如命令参数可以使用 cmd 的形式提供默认版本,也就是 run 里面没有任何参数时使用的默认参数。如果我们想用默认参数,就直接 run,否则想用其他参数,就 run 里面加参数。

7. 实战经验

8. 参考与感谢

8.1. 黑马

8.1.1. 视频

https://www.bilibili.com/video/BV1LQ4y127n4?p=57&spm_id_from=pageDriver&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

8.1.2. 资料

[[Docker实用篇]]

1
/Users/taylor/Nutstore Files/Obsidian_data/pages/002-schdule/001-Arch/001-Subject/005-分布式专题/微服务开发框架SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式微服务全技术栈课程/day03-Docker/讲义

8.2. 尚硅谷 - 周阳

8.2.1. 视频

https://www.bilibili.com/video/BV1gr4y1U7CY?p=8&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

8.2.2. 资料

1
/Users/taylor/Nutstore Files/Obsidian_data/pages/002-schdule/001-Arch/001-Subject/005-分布式专题/Docker2022-周阳脑图笔记