先回顾几个场景
- 为学习Linux安装虚拟机,安装软件出现兼容性问题,拍错半天,最后又推到重做费时费力?
- 安装MySQL&Redis这种组件,跟着教程一步步走,出错调试搞半天,最后导致系统崩溃,重装操作系统
- 项目在自己的电脑上正常启动,想部署或者分享给同事,发现又启动不了
Docker作用
- 更快更安全的构建应用程序,核心可重复构建
配置镜像可以用阿里云的

然后管理控制台->镜像工具
Docker与传统虚拟机区别
物理服务器
自带 cpu、 内存等硬件和操作系统,根据一些教程视频,是可以做成服务器的。像这样一台看得见摸得着的机器,其实就是云厂商页面里提到的物理服务器 或物理机 。不同厂商叫法不同,有的厂商叫它独立服务器。
问题又来了,云厂商的物理服务器一般都是核数较高,很多时候我们根本不需要这么高配的机器。怎么办呢?这一点云厂商当然也考虑到了。
vps和ecs
云厂商一般会将一台物理服务器分割成多个虚拟机 。它跟我们在 windows用 VMware 建的虚拟机其实是一回事。每个虚拟机都拥有独立的操作系统、资源(比如 CPU、内存、存储空间)和公网 IP 地址。然后对外出售,这样的虚拟机就是所谓的 VPS(Virtual Private Server,虚拟专用服务器)。

但传统 VPS 有个缺点,不支持用户自主升降级,它的资源是预先分配的,不易动态调整。举个例子,假设你买了 1c1g 的服务器,想在页面上点点两下升级成 2c2g,这在传统 VPS 里是不支持的。如果给 VPS 加入自主升降级的功能,那它就成了 ECS(Elastic Compute Service,弹性计算服务)

用户可以根据需要随时调整 CPU、内存、磁盘和带宽,主打一个弹性。我们可以利用 ecs 学习 linux 命令,部署个人博客,做私人云盘存储,甚至可以将自己做的游戏部署到 ecs 上邀请朋友来玩。

Docker容器
买了 ecs 后,我们一般会开始部署自己的软件应用。机器少的时候手动部署问题不大,机器多了后各种问题就来了,其中最明显的就是,ecs 之间,如果底层操作系统 不同,比如有些是 ubuntu,有些是 centos,部署应用的时候就会有各种环境问题。
如果能让软件带着操作系统环境一起去部署就好了,最简单的方案是将软件和操作系统一起打包成虚拟机部署在 ecs 中。但这样就成了在 ECS(也就是虚拟机)中再运行一个完整的虚拟机,太重了。有解法吗?

有。既然多加一个操作系统太重,那我就只打包软件和系统依赖库加配置就好了。然后将这部分系统文件挂到 ecs 的操作系统下,利用一个叫 Namespace 的能力让它看起来就像是一个独立操作系统一样。再利用一个叫 Cgroup 的能力限制它能使用的计算资源。这就省掉了一层笨重的操作系统,同时还让软件轻松跑在各类操作系统上。这就是我们常说的 Docker 容器技术。

总的来说就是,物理服务器上跑 ecs,ecs 跑 Docker 容器。多个 Docker 容器共享一个 ecs 实例 操作系统内核。

现在我们再回过头来看这句话,Docker 本质上就是一个将程序和环境打包并运行的工具软件。具体点来说就是,它通过 Dockerfile 描述环境和应用程序的依赖关系, docker build 构建镜像, docker pull/push 跟 Docker Registry 交互实现存储和分发镜像,docker run 命令基于镜像启动容器,基于容器技术运行程序和它对应的环境,从而解决环境依赖导致的各种问题。
Docker浅析
要是你想将自己写的代码部署到各个不同操作系统的服务器上,那依赖的软件和配置就特别多,需要针对每个环境单独写一套部署脚本。
那么问题就来了,有没有更好的解决方案?
当然有,没有什么是加一层中间层不能解决的,如果有,那就再加一层 ,这次我们要加的中间层是 Docker容器。

基础镜像
既然上面提到环境不同,会导致程序运行结果不同,那么我们首先要做的最重要的事情,就是统一环境 。而环境中,最最重要的就是操作系统 。比如 centos 还是 ubuntu,我们得选一个,让所有程序都跑在同一个操作系统上。并且我们知道操作系统分为用户空间和内核空间,应用程序运行在用户空间。因此,我们可以阉割操作系统,只需要利用操作系统的用户空间部分,就能构建出应用所需的环境。
其次就是统一程序语言 依赖,比如要跑 python 应用,你得装个 python 解释器,要跑个 java 应用,得装个 JVM。选中一个基础操作系统和语言后,我们将它们对应的文件系统,依赖库,配置等放一起打包成一个类似压缩包的文件,这就是所谓的基础镜像(Base Image)。

Dockerfile
有了基础镜像之后还不够,我们经常还需要安装一些依赖,比如yum install gcc,甚至还要创建一些文件夹。最后才是运行我们的目标应用程序 。我们知道 linux 中,所有工作都可以通过命令行 完成,所以我们可以将要做的事情以命令行的形式一行行列出来。就像一份 todo list。意思是要求在基础镜像的基础上按着 todo list 挨个执行命令。这份 todo list 长下面这样。

具体含义是,基于一个装了 python3.9 解释器的操作系统(基础镜像),再执行 pip install 等命令安装其他依赖,从而构建出一个适合程序运行的环境,最后用 python app.py 运行我们的目标应用程序。像这样一份列清楚了,从操作系统到应用服务启动,需要做哪些事情的清单文件(todo list),就是所谓的 Dockerfile。
容器镜像
注意 Dockerfile 只是描述了要做哪些事情,并没有真正开始做。当我们用命令行执行 docker build 的时候,Docker 软件就会按着 Dockerfile 的说明,一行行构建环境+应用程序。最终将这个环境+程序,打包成一个类似"压缩包"的东西,我们叫它容器镜像(container image)。

只要将容器镜像传到任意一台服务器上,对这个"压缩包"执行"解压缩",我们就能同时运行环境和程序。太完美了!但是现在还有个问题,怎么将容器镜像传到那么多服务器上呢?
Registry
参考 github 代码仓库 的做法,我们通常会使用 git push 将代码传到 github,有需要的人自己通过 git pull 的方式将代码从 github 拉到自己的机器上。
那 Docker 也一样,弄一个镜像仓库,通过 docker push 将镜像推到仓库,有需要的时候再通过 docker pull 将镜像拉到机器上。这个负责管理镜像仓库推拉能力的服务,就叫 Docker Registry。
基于 Docker Registry 的能力,我们可以搭建各种官方或私人镜像仓库,比如官方的叫DockerHub,非官方的有清华大学的 Tuna 等等,一般公司内部也会有自己的镜像仓库。

容器
现在,我们解决了服务器间传输容器镜像 的问题。我们可以跑到目的服务器上,执行 docker pull 拿到容器镜像。然后执行 docker run 命令,将这个类似"压缩包"的容器镜像给"解压缩",获得一个独立的环境和应用程序 并运行起来。这样一个独立的环境和应用程序,就是所谓的容器(container)。我们可以在一个操作系统上同时跑多个容器。且这些容器之间都是互相独立,互相隔离的。

架构原理
现在,我们回到日常使用场景中,聊聊 Docker 的架构原理。它是经典的 Client/Server架构。Client 对应 Docker-cli, Server 对应 Docker daemon。我们在命令行里敲 Docker 命令,使用的就是 Docker-cli.

Docker-cli 会解析我们输入的 cmd 命令,然后调用 Docker daemon 守护进程提供的 RESTful API,守护进程收到命令后,会根据指令创建和管理各个容器。
再具体点,Docker Daemon 内部分为 Docker Server、Engine 两层。Docker Server 本质上就是个 HTTP 服务,负责对外提供操作容器和镜像的 api 接口,接收到 API 请求后,会分发任务给 Engine 层,Engine 层负责创建 Job,由 Job 实际执行各种工作。

注意:本笔记仅为自己网上查找资料学习的学习笔记,无任何商业用途,侵权即删。相关学习视频docker容器和传统虚拟机有什么区别?_哔哩哔哩_bilibili