跳至主要內容

容器化技术

码匠君SASSpring Authorization ServerDante Cloud微服务领域驱动DDDSpring BootSpring CloudSpring SecuritySpring Cloud AlibabaSpring Cloud TencentOAuth2.1NacosSkywalkingSentinelSeata大约 6 分钟

容器化技术

Docker 能解决什么问题?

Docker Logo
Docker Logo

Docker 是一个容器化工具,那么什么是容器呢,Docker 和容器有什么关系,Docker 又能解决什么问题呢?

麻烦的环境配置

软件开发最大的麻烦事之一就是环境配置,在开发之前我们需要准备各种运行环境,IDE,辅助工具。就像我们要使用电脑前,先要安装操作系统一样。

而一个可用软件的交付过程通常包含两个部分 - 开发和维护。不幸的是,我们很难保证软件开发测试和运行维护阶段的软件能运行在一模一样的环境下。开发常说:"It works on my machine",很多时候我们都要花大量的时间去配置环境和教别人配置环境。

现在的应用程序

applications.jpg
applications.jpg

以前的应用程序:

  • 几乎都是单块应用: 大系统, 多模块
  • 紧耦合: 内部调用
  • 不常变更: 需求稳定(改动成本高)

如今的应用程序:

  • 解耦: 微服务/异步
  • 经常变更: 快速迭代
  • 动态创建和部署: 服务化

新架构的挑战

  • 多样化的技术栈
  • 需要动态创建机器
  • 很多活动组件
  • 运维人员需要管理复杂的架构

复杂的架构

在新的应用程序架构下,我们部署应用的成本大大增加。不但要搭建不同语言,不同技术栈适配的运行环境,还要部署到多个服务器主机上;并且这些主机还可能来自不同地方(公/私有云主机,物理主机)。

统一的管理

其实在软件开发的过程中我们就思考过类似的问题 - 如何统一的管理我们的代码包。例如,Maven,Gradle,NPM,我们使用一个相同的格式(规范)将我们的代码划分成模块,并使用一套工具去管理他们。在此之后我们不需要重复的 copy 代码,复制文件,只需要声明式的引入我们需要的代码包就可以了。

当然,我们希望我们的应用部署也能如此简单。

“容器”

good-container.png
good-container.png
app-container.png
app-container.png

“容器”是一个黑盒,对于它的使用者来说:

  • 无需关心里面有什么:只关注“容器”能做什么
  • 有一套工具来管理黑盒:打包,运输,运行
  • 减少了部署单元的数量,从而减少了花销:多个工具聚集在一个“容器”内
  • 更容易管理多个环境:以“容器”为单位进行部署和管理

虚拟化技术

(1) 虚拟机:精心配置的虚拟机也是满足我们(基本)要求的容器,我们能够通过虚拟机镜像来打包我们的应用。但是,庞大的操作系统占用了大量的系统资源,使运行成本大大上升。

vm.png
vm.png

虚拟机

  • 应用
    • 运行环境(Java/数据库/libs...)
    • 客户机操作系统(Guest Operating System)
    • 虚拟机管理系统(Hypervisor)
    • 操作系统级:MacOS(HyperKit),Windows 的 Hyper-V
    • 应用软件级:VirtualBox,VMWare Workstation
  • 主操作系统(Host Operating System)
  • 硬件(Infrastructure)/云主机

(2) 容器:(作为进程)共用内核并提供额外的隔离手段,避免虚拟的操作系统占用。

container.png
container.png

容器

  • 应用
  • 运行环境(Java/数据库/libs...)
  • Docker 守护进程(Docker Daemon): 类似虚拟机管理系统
  • 主操作系统(Host Operating System)
  • 硬件(Infrastructure)/云主机

容器技术

容器技术已经发展了一段时间了, 例如, LXC, BSD Jails, Solaris Zones...

history.png
history.png

容器技术特点

  • 看起来像虚拟机
    • 可以 SSH 到容器
    • 具有 root 的访问权限
    • 可以安装包
    • 可以 mount 文件系统
    • 拥有自己的 eth0 接口
    • 可以修改 iptables 规则和 routing table
  • 共享宿主机的内核
  • 隔离 cgroups (memory, cpu, blkio)
  • 拥有进程空间 (pid, mnt, net, ipc, uts)
    • pid - 隔离进程 PID
    • mnt - 允许创建不同的文件系统层级
    • net - 隔离网络控制,iptables,防火墙,路由
    • ipc - 定义内部进程交流的范围
    • uts - 允许修改 hostname
      :::

容器技术的局限

  • 容器没有标准的格式
  • 所以容器是不可移植的
  • 没有标准的工具,所以比如要自己管理网络
  • 没有可重用的模块和 API

Docker

what-is-docker.png
what-is-docker.png
  • 使容器变得更容易使用
  • 容器镜像的商品化
  • 可插拔的模块易于吸引供应商加入
  • 适当的 API 可用来创建高层次抽象的工具
  • 和微服务诞生在同一个时代

Docker 架构

docker-architecture.png
docker-architecture.png
  • Docker Client:接收命令和 Docker Host 进行交互的客户端
  • Docker Host:运行 Docker 服务的主机
    • Docker Daemon:守护进程,用于管理所有镜像和容器
    • Docker Images/Containers:镜像和容器实例
  • Registry(Hub):镜像仓库
docker-architecture2.png
docker-architecture2.png

Docker 底层实现

docker-tech.png
docker-tech.png

底层实现原理详解见open in new window

Docker 核心技术

core-tech.png
core-tech.png
  • Namespace 命名空间
    Linux 的命名空间机制提供了以下七种不同的命名空间,包括 CLONE_NEWCGROUP,CLONE_NEWIPC,CLONE_NEWNET,CLONE_NEWNS,CLONE_NEWPID,CLONE_NEWUSER,CLONE_NEWUTS,通过这七个选项我们能在创建新的进程时设置新进程应该在哪些资源上与宿主机器进行隔离。因此容器只能感知内部的进程,而对宿主机和其他容器一无所知。
  • CGroups (Control Groups)
    Linux 的 CGroup 能够为一组进程分配资源,也就是我们在上面提到的 CPU,内存,网络带宽等资源.
  • UnionFS
    union-fs.png

Docker 中的每一个镜像都是由一系列的只读层组成的,Dockerfile 中的每一个命令都会在已有的只读层上创建一个新的层。通过 docker run 命令可以在镜像的最上层添加一个可写的层 - 容器层,所有对于运行时容器的修改其实都是对这个容器读写层的修改。

容器和镜像的区别就在于,所有的镜像都是只读的,而每一个容器其实等于镜像加上一个可读写的层,也就是同一个镜像可以对应多个容器。同时已构建的每一层镜像也可以作为其他镜像的基础层进行共用。

Docker VS VM

docker-vs-vm.png
docker-vs-vm.png