两个关键词带你了解容器技术的实现

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 两个关键词带你了解容器技术的实现

本篇文章参考:

1、深入剖析 Kubernetes (geekbang.org)

2、Docker基础技术:Linux Namespace(下) | 酷 壳 - CoolShell

通过前面的文章,我们可以得出以下几点事实:

  • 容器技术的兴起源于 Paas 技术的普及
  • Docker 公司发布的 Docker 项目具有里程碑式的意义
  • Docker 项目通过容器镜像,解决了应用打包这个根本性难题

但是一个关键性问题还没有搞清楚——容器,到底是怎么一回事?

接下来我将通过两个关键词,给大家揭开容器技术的神秘面纱

关键词1:隔离

前面的文章提到过,容器其实是一种”沙盒“技术

”沙盒“就像是一个集装箱一样,把你的应用”装起来“,这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去,这不就是 PaaS 最理想的状态嘛

Docker 公司的标志,是一头鲸鱼上背着集装箱,那一个个集装箱,代表着一个个容器
image-20221026152735931.png
应用之间互不干扰,说起来简单,但要用技术手段去实现他们,可能大多数人就无从下手了

我们知道,程序其实就是存储在磁盘上的一个个二进制文件,一旦被加载到内存中交给 CPU 去执行,就成了一个个进程

总的来说,程序是存储在磁盘上的二进制文件、是静态的,而进程就是程序的运行时,是动态的

容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造一个”边界“,将进程隔离起来

那么怎么才能将进程隔离起来呢?答案是——Namespace 技术

Namesapce 技术通过修改进程视图来实现进程间的隔离

举个例子:

在我的 Linux 操作系统上有 Docker 项目正在运行,我的操作系统环境是 CentOS 7

我们先以终端形式启动一个容器,并在容器里执行 /bin/bash

docker exec -it myApp /bin/sh/

这样,我的 CentOS 7 就变成了一个宿主机,而这个我启动的容器,就在宿主机上面运行着

我们在容器里执行 ps 命令

PID  USER   TIME COMMAND
1    root   0:00 /bin/sh
10   root   0:00 ps

我们可以看到,容器里只有两个进程在运行,一个是最开始执行的 /bin/bash (PID=1),另一个是刚刚执行的 ps

可以看到,容器里面的进程被 Docker 隔离在了一个跟宿主机完全不同的世界当中

究竟是怎么做到的呢?

一般情况下每当我们在宿主机上运行一个 /bin/bash 程序,操作系统都会为其分配一个 PID(例如 PID=100),PID 是进程的唯一标识。(PS:PID为1则意味着这个进程是第一个进程,是后面所有进程的爹)
image-20221027141146521.png
当我们通过 Docker 把这个 /bin/bash 程序(假设 PID =100)运行在一个容器当中的时候,Docker就会给这个 /bin/bash 施加一个“障眼法”——让它看不到前面 99 个进程,让它误以为自己就是第一个进程(即 PID=1)

这种技术,就是 Linux 里面的 Namespace 机制

这种机制,其实就是对被隔离应用的进程空间做了手脚,使得这些进程只能看到重新计算过的进程编号,比如 PID=1。可实际上,他们在宿主机的操作系统真实的进程空间里,还是原来的第 100 号进程

而每个 Namespace 里的应用进程,都会认为自己是当前容器里的第 1 号进程,它们既看不到宿主机里真正的进程空间,也看不到其他 PID Namespace 里的具体情况

除了我们介绍的 PID Namespace ,Linux 操作系统还提供了 Mount 、UTS、IPC、Network和User 这些 Namespace,用来对各种不同的进程上下文进行“障眼法”

比如,Mount Namespace,用于让被隔离进程只看到当前 Namespace 里的挂载点信息;Network Namespace,用于让被隔离进程看到当前 Namespace 里的网络设备和配置

以上这些,便是 Linux 容器技术最基本的实现原理之一

总结:

  • Docker 容器这个听起来很深奥的概念,其实就是在创建容器进程时,指定了这个进程所需要启用的一组 Namespace 参数,这样容器就只能“看到”当前 Namespace 所限定的资源、文件、设备、状态或者配置,而对于宿主机以及其他不相关的程序,它就完全看不到了
  • 容器其实就是一种特殊的进程,将这些进程通过 Namespace 机制进行隔离,就仿佛运行在一个个“容器/沙盒”里面,与世隔绝

关键词2:限制

我们知道,Linux 通过 Namespace 机制将容器进程隔离起来,让它们只能再他们的空间里运行

但对于宿主机来说,这些被“隔离”的进程(容器)跟其他进程并没有太大的区别

我们站在宿主机的角度上来看,这些被“隔离”的进程(容器)本质上跟其他进程没有什么区别,这些容器使用的是同一个宿主机的操作系统内核

这就会导致一个问题——隔离得不彻底

尽管你在容器里通过 Mount Namespace 单独挂载其他不同版本的操作系统,比如 CentOS 或 Ubuntu,但这并不能改变容器共享宿主机内核的事实

这表明你想在 Windows 宿主机上运行 Linux 容器,或者在低版本的 Linux 宿主机上运行高版本的 Linux 容器,都是行不通的

其次,还会导致另一个问题——在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,最典型的例子就是:时间

如果你在容器里修改了时间,那么整个宿主机的时间都会被修改。所以说,在容器里部署应用的时候,“什么能做,什么不能做”是需要考虑的一个问题

所以说,我们除了对容器要进行“隔离”,我们还需要对容器进行“限制”

我们接着引用上面的例子,虽然容器里的 1 号进程在“障眼法”的干扰下只能看到容器里的情况,但是在宿主机上,它是 100 号进程,它去宿主机上的其他进程之间是平等的竞争关系

即虽然 100 号进程被隔离起来,但是它能够使用到的资源(CPU、内存等)是可以随时被宿主机上的其他进程(或者其他容器)占用的,当然,这个 100 号进程自己也可能把所有资源吃光

Linux Cgroups 就是 Linux 内核中用来为进程设置资源限制的一个重要功能

  • Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等
  • 此外,Cgroups 还能够对进程进行优先级设置、审计,以及将进程挂起和恢复等操作

想了解更多关于 Linux Cgroups 的知识 ,请翻阅下面的文档:

Linux资源管理之cgroups简介 - 美团技术团队 (meituan.com)

总结:

  • 一个正在运行的 Docker 容器,其实就是一个启用了多个 Linux Namespace 的应用进程,而这个进程能够使用的资源量,则受 Cgroups 配置的限制
  • 容器是一个“单进程”模型。这就意味着,在一个容器中,你没办法同时运行两个不同的应用,除非你能事先找到一个公共的 PID=1 的程序来充当两个不同应用的父进程,这也是为什么很多人都会用 systemd 或者 supervisord 这样的软件来代替应用本身作为容器的启动进程
相关文章
|
27天前
|
Kubernetes Cloud Native 微服务
探索云原生技术:容器化与微服务架构的融合之旅
本文将带领读者深入了解云原生技术的核心概念,特别是容器化和微服务架构如何相辅相成,共同构建现代软件系统。我们将通过实际代码示例,探讨如何在云平台上部署和管理微服务,以及如何使用容器编排工具来自动化这一过程。文章旨在为开发者和技术决策者提供实用的指导,帮助他们在云原生时代中更好地设计、部署和维护应用。
|
10天前
|
Unix Linux Docker
CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局
操作系统是计算机系统的核心软件,管理和控制硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。Linux作为开源、跨平台的操作系统,具有高度可定制性、稳定性和安全性,广泛应用于服务器、云计算、物联网等领域。其发展得益于庞大的社区支持,多种发行版如Ubuntu、Debian、Fedora等满足不同需求。
37 4
|
1月前
|
开发框架 安全 开发者
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。本文探讨了 Docker 在多平台应用构建与部署中的作用,包括环境一致性、依赖管理、快速构建等优势,以及部署流程和注意事项,展示了 Docker 如何简化开发与部署过程,提高效率和可移植性。
65 4
|
1月前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
74 3
|
2月前
|
持续交付 开发者 Docker
探索容器化技术Docker及其在现代软件开发中的应用
探索容器化技术Docker及其在现代软件开发中的应用
|
2月前
|
运维 Kubernetes Docker
深入理解容器化技术:Docker与Kubernetes的协同工作
深入理解容器化技术:Docker与Kubernetes的协同工作
53 1
|
2月前
|
运维 Kubernetes Docker
深入理解容器化技术及其在微服务架构中的应用
深入理解容器化技术及其在微服务架构中的应用
65 1
|
2月前
|
安全 持续交付 Docker
深入理解并实践容器化技术——Docker 深度解析
深入理解并实践容器化技术——Docker 深度解析
66 2
|
2月前
|
持续交付 开发者 Docker
探索容器化技术Docker及其在现代软件开发中的应用
探索容器化技术Docker及其在现代软件开发中的应用
|
2月前
|
Cloud Native 云计算 Docker
云原生技术的崛起:从容器化到微服务架构
云原生技术的崛起:从容器化到微服务架构