Docker 是什么? Docker 和 k8s 之间是什么关系?

作为一个程序员,如果你想安装一个vim 编辑下文本,在不同环境里你得执行不同的命令。在Ubuntu,你需要执行 apt-get install vim ,在centos里,你需要执行 yum install vim 。

安装一个命令行工具尚且如此,要是你想将自己写的代码部署到各个不同操作系统的服务器上,那依赖的软件和配置就更多了,需要针对每个环境单独写一套部署脚本。

那么问题就来了,有没有更好的解决方案?
当然有,没有什么是加一层中间层不能解决的,如果有,那就再加一层,这次我们要加的中间层是Docker
在这里插入图片描述

此处把Docker称之为中间层有些不合理,准确来说是 Docker容器
在这里插入图片描述

Docker 是什么?

我们经常能听到程序员说"这个程序在我的环境里明明是好的啊,怎么到你这儿就不行了?“,注意这里的关键词,程序环境。程序是跑在操作系统上的,而操作系统上又装了各种不同版本的依赖和配置,这些被程序所依赖的信息,我们统称为"环境”。
在这里插入图片描述
程序依赖环境,环境不同,程序就可能跑不起来。如果我们能将环境和程序一起打包,给到对方运行,那么问题不就解决了吗。Docker就是这样一款可以将程序和环境打包并运行的工具软件。

基础镜像是什么

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

Dockerfile是什么

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

# 指定基础镜像
FROM python:3.9

# 设置工作目录
WORKDIR /app

# 复制依赖文件到容器中
COPY requirements.txt .

RUN yum install gcc
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 将当前目录下的所有文件复制到容器的 /app 目录下
COPY . /app

# 设置容器启动时执行的命令
CMD ["python", "app.py"]

具体含义是,基于一个装了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和虚拟机的关系

这个容器是不是很像我们用VMware或kvm整出来的传统虚拟机?但不同的是,传统虚拟机自带一个完整操作系统,而容器本身不带完整操作系统,容器的基础镜像实际上只包含了操作系统的核心依赖库和配置文件等必要组件。它利用一个叫Namespace的能力让它看起来就像是一个独立操作系统一样,再利用一个叫Cgroup的能力限制它能使用的计算资源。
在这里插入图片描述

所以说,容器本质上只是个独立运行环境的特殊进程,底层用的其实是宿主机的操作系统内核
在这里插入图片描述

Docker的架构原理

现在我们回到日常使用场景中,聊聊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命令会执行不同类型的Job任务。

docker build

如果你执行的是docker bulid命令,Job则会根据Dockerfile指令一层一层的构建容器镜像文件。
在这里插入图片描述

docker pull/push

如果你执行的是docker pull 或 push 之类的镜像推拉操作,Job则会跟外部的 Docker Registry交互,将镜像上传或下载。
在这里插入图片描述

docker run

如果你执行的是 docker run 命令,Job就会基于镜像文件调用 containerd组件,驱使runC组件创建和运行容器。
在这里插入图片描述

Docker到底是什么?

现在我们再回过头来看这句话,Docker本质上就是一个将程序和环境打包并运行的工具软件。具体点来说就是,它通过Dockerfile描述环境和应用程序的依赖关系,docker build构建镜像,docker pull/push跟Docker Registry交互实现存储和分发镜像,docker run命令基于镜像启动容器,基于容器技术运行程序和它对应的环境,从而解决环境依赖导致的各种问题。
在这里插入图片描述
到这里,我们就了解了Docker的架构和基本运行原理了。接下来,我们再来聊聊跟Docker相关的几个周边。

Docker Compose是什么?

我们现在知道了Docker 容器本身只是一个特殊进程,但如果我想要部署多个容器,且对这些容器的顺序有一定要求呢?比如一个博客系统,当前是先启动数据库,再启动身份验证服务,最后才能启动博客web服务。按理说挨个执行docker run命令当然是没问题的,但有没有更优雅的解决方案?有。我们可以通过一个YAML文件写清楚要部署的容器有那些,部署顺序是怎么样的,以及这些容器占用的cpu和内存等信息。

version: "3.8"

services:
  A:
    image: "some-image-for-a"
    deploy:
      resources:
        limits:
          cpus: "0.50" # 限制 CPU 使用率为 50%
          memory: 256M # 限制内存使用量为 256MB

  B:
    image: "some-image-for-b"
    depends_on:
      - A

  C:
    image: "some-image-for-c"
    depends_on:
      - B

然后,通过一行Docker-compose up命令,开始解析YAML文件,将容器们一键按顺序部署,就完成一整套服务的部署。这其实就是Docker Compose干的事情。
在这里插入图片描述

Docker Swarm是什么?

Docker解决的是一个容器的部署。Docker Compose解决的是多个容器组成的一整套服务的部署。那 Docker Swarm就更高维度了,它解决的其实是这一整套服务在多台服务器上的集群部署问题。比如在A服务器坏了,就将服务在B服务器上重新部署一套,实现迁移,还能根据需要对服务做扩缩容。
在这里插入图片描述

Docker 和 k8s 的关系是什么?

还记得之前的文章里提到的k8s吗?它会在多台Node服务器上调度Pod,进行部署和扩缩容。
在这里插入图片描述
每个Pod内部可以含有多个container,每个container本质上就是一个服务进程。
在这里插入图片描述
是不是感觉k8s跟Docker Swarm做的事情很像?没错,其实Docker Swarm是k8s的竞品,既然是竞品,那它们做的事情其实区别就不大了。现在回过头来看Docker容器和k8s之间的关系,思路就清晰了。Docker部署的容器,其实就是k8s调度的Pod里的container,它们都叫容器,其实是一回事。只不过k8s除了支持Docker的容器外,还支持别人家的容器。Docker Compose基于多个container创建的一整套服务,其实就是k8s里的pod。而Docker Swarm做的事情和k8s一样,本质上就是在调度pod。回过头来看下k8s的官方定义,叫容器编排引擎,将它理解为,以API编程的方式管理安排各个容器的引擎,是不是就特别精辟。
在这里插入图片描述

现在,我们再回过头来看一下Docker的图标,是一个个集装箱,放在一艘船上,这一个个集装箱指的就是互相隔离的容器,而k8s的图标,则是一共轮船上的方向盘,意思是k8s控制着轮船的航向,其实指的就是调度容器。
在这里插入图片描述

总结

  • Docker 本质上就是一个将程序和环境打包并运行的工具软件,而 Docker 容器本质上只是个自带独立运行环境的特殊进程,底层用的其实是宿主机的操作系统内核。

  • Docker 软件 通过 Dockerfile 描述环境和应用程序的依赖关系, docker build 构建镜像, docker pull/push 跟 Docker Registry 交互实现存储和分发镜像,docker run 命令基于镜像启动容器,基于容器技术运行程序和它对应的环境,从而解决环境依赖导致的各种问题。

  • Docker 解决的是一个容器的部署问题,Docker Compose 解决的是多个容器组成的一套服务的部署问题,Docker Swarm 解决的是多个容器组成的一套服务在多台服务器上的部署问题,k8s 则是 Docker Swarm 的竞品,在更高维度上兼容了 Docker 容器,实现了容器编排调度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值