容器其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用“装”起来的技术。

这样,应用与应用之间,就因为有了边界而不至于相互干扰;

而被装进集装箱的应用,也可以被方便地搬来搬去,

这不就是 PaaS 最理想的状态嘛。

"程序"被执行起来,它就从磁盘上的二进制文件,变成了计算机内存中的数据、寄存器里的值、堆栈中的指令、被打开的文件,以及各种设备的状态信息的一个集合。

像这样一个程序运行起来后的计算机执行环境的总和,就是:进程

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

对于 Docker 等大多数 Linux 容器来说,Cgroups 技术是用来制造约束的主要手段,而 Namespace 技术则是用来修改进程视图的主要方法

在docker容器中执行ps命令,可以看到我们在 Docker 里最开始执行的 /bin/sh,

就是这个容器内部的第 1 号进程(PID=1),

而这个容器里一共只有两个进程在运行。

这就意味着,前面执行的 /bin/sh,以及我们刚刚执行的 ps,

已经被 Docker 隔离在了一个跟宿主机完全不同的世界当中

在宿主机中执行/bin/sh如下,PID是1536

这种机制,其实就是对被隔离应用的进程空间做了手脚,使得这些进程只能看到重新计算过的进程编号,比如 PID=1。

可实际上,他们在宿主机的操作系统里,还是原来的第 1536号进程。

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

在 Linux 系统中创建进程的系统调用是 clone(),比如:

 int pid = clone(main_function, stack_size, SIGCHLD, NULL);

这个系统调用就会为我们创建一个新的进程,并且返回它的进程号 pid。

当我们用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数,比如

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

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

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

就是 Linux 容器最基本的实现原理了。

所以说,容器,其实是一种特殊的进程而已。

在理解了 Namespace 的工作方式之后,你就会明白,跟真实存在的虚拟机不同,

在使用 Docker 的时候,并没有一个真正的“Docker 容器”运行在宿主机里面。

Docker 项目帮助用户启动的,还是原来的应用进程,

只不过在创建这些进程时,Docker 为它们加上了各种各样的 Namespace 参数。

这些进程就会觉得自己是各自 PID Namespace 里的第 1 号进程,

只能看到各自 Mount Namespace 里挂载的目录和文件,

只能访问到各自 Network Namespace 里的网络设备,

就仿佛运行在一个个“容器”里面。

基于 Linux Namespace 的隔离机制相比于虚拟化技术也有很多不足之处,其中最主要的问题就是:隔离得不彻底

首先,既然容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的就还是同一个宿主机的操作系统内核。

在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,最典型的例子就是:时间。

如果在一个容器中修改了系统时间,那么整个宿主机的时间都会被修改。

Linux Cgroups 就是 Linux 内核中用来为进程设置资源限制的一个重要功能。Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

Cgroups 的每一个子系统都有其独有的资源限制能力,比如:

blkio,为​​​块​​​设​​​备​​​设​​​定​​​I/O 限​​​制,一般用于磁盘等设备;

cpuset,为进程分配单独的 CPU 核和对应的内存节点;

memory,为进程设定内存使用的限制。

Linux Cgroups 的设计还是比较易用的,简单粗暴地理解呢,它就是一个子系统目录加上一组资源限制文件的组合。

而对于 Docker 等 Linux 容器项目来说,它们只需要在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录),然后在启动容器进程之后,把这个进程的 PID 填写到对应控制组的 tasks 文件中就可以了。

而至于在这些控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定了,比如这样一条命令:

$ docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu /bin/bash

在启动这个容器后,我们可以通过看 Cgroups 文件系统下,CPU 子系统中,

“docker”这个控制组里的资源限制文件的内容来确认:

$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_period_us
100000
$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_quota_us
20000

这就意味着这个 Docker 容器,只能使用到 20% 的 CPU 带宽。

容器是一个“单进程”模型

由于一个容器的本质就是一个进程,用户的应用进程实际上就是容器里 PID=1 的进程,也是其他后续创建的所有进程的父进程。

这就意味着,在一个容器中,你没办法同时运行两个不同的应用,除非你能事先找到一个公共的 PID=1 的程序来充当两个不同应用的父进程,

这也是为什么很多人都会用 systemd 或者 supervisord 这样的软件来代替应用本身作为容器的启动进程

Docker 项目来说,它最核心的原理实际上就是为待创建的用户进程:

启用 Linux Namespace 配置;

设置指定的 Cgroups 参数;

切换进程的根目录(Change Root)。

总结:

1、虚拟机 是硬件隔离,因为hypervisor 虚拟一系列硬件资源

2、容器是 进程级隔离,依靠NameSpace 机制实现进程间的隔离

3、容器的资源限制,依靠Linux Cgroups,它就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

4、容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的就还是同一个宿主机的操作系统内核。

5、通过exec在容器中执行启动的后台进程,实际不受docker控制(回收和生命周期),只有PID=1的受控制。

6、Namespace做隔离,Cgroups做限制,rootfs做文件系统

[k8s]容器基础-隔离与限制的更多相关文章

  1. K8s容器编排

    K8s容器编排 Kubernetes(k8s)具有完备的集群管理能力: 包括多层次的安全防护和准入机制 多租户应用支撑能力 透明的服务注册和服务发现机制 内建智能负载均衡器 强大的故障发现和自我修复能 ...

  2. Kubernetes(K8s)基础概念 —— 凿壁偷光

    Kubernetes(K8s)基础概念  --  凿壁偷光 K8s是什么:全称 kubernetes  (k12345678s) 作用:用于自动部署,扩展和管理"容器化应用程序"的 ...

  3. Rancher 快速构建k8s容器管理平台解决方案(图片见原文链接)

    转载自Rancher 快速构建k8s容器管理平台解决方案_IT干货的博客-CSDN博客_k8s容器管理平台 一.Rancher 概述 Rancher 是企业级多集群Kubernetes管理平台,一个为 ...

  4. Docker 容器的隔离性

    Docker 容器的隔离性 就是 使用Linux namespace 来隔离运行环境和成 cgroup 限制容器使用的资源.  namespace 可以顾名思义 命名空间:所以可以理解为每个独立的容器 ...

  5. docker容器基础

    一.docker容器基础6种名称空间:UTS.MOunt.IPC.PID.User.Net (1) Linux Namespaces:namespace 系统调用参数 隔离内容 内核版本  UTS   ...

  6. 微服务与K8S容器云平台架构

    微服务与K8S容器云平台架构 微服务与12要素 网络 日志收集 服务网关 服务注册 服务治理- java agent 监控 今天先到这儿,希望对技术领导力, 企业管理,系统架构设计与评估,团队管理, ...

  7. K8S - 容器编排工具Kubernetes简介

    1 - Kubernetes Kubernetes(简称K8s,用8代替8个字符"ubernete")是Google开源的一个容器编排引擎. 目前最为广泛且流行的容器编排调度系统, ...

  8. 08 | 白话容器基础(四):重新认识Docker容器

    你好,我是张磊.今天我和你分享的主题是:白话容器基础之重新认识Docker容器. 在前面的三次分享中,我分别从Linux Namespace的隔离能力.Linux Cgroups的限制能力,以及基于r ...

  9. Kubernetes_手把手打镜像并运行到k8s容器上(亲测可用)

    一.前言 本文使用两个机器 192.168.100.150 是master节点,192.168.100.151 是node1 节点,如下: 演示三个示例,第一个示例wordpress博客系统是指将别人 ...

  10. C++ 顺序容器基础知识总结

    0.前言 本文简单地总结了STL的顺序容器的知识点.文中并不涉及具体的实现技巧,对于细节的东西也没有提及.一来不同的标准库有着不同的实现,二来关于具体实现<STL源码剖析>已经展示得全面细 ...

随机推荐

  1. flannel,canal,网络控制

    docker网络: bridge 自连网络名称空间 joined 与另外容器共享使用网络名称空间 open 容器直接共享宿主机的网络名称空间 none 不使用任何网络名称空间 k8s网络通信模型 容器 ...

  2. 题目集8~9总结性Blog

    一.前言 对这两次题目集的总结: 这两次题目集相较于上次迭代作业来说,在题目量和难度上都做了下调.但要求我们在理解题目意思.设计好程序结构.掌握并运用知识这三方面有一定的要求.涉及到类的继承与多态,抽 ...

  3. windows环境下的常用命令

    1.appwiz.cpl 程序和功能 2.certmgr.msc 证书管理实用程序 3.control 控制面板 4.firewall.cpl 防火墙 5.fsmgmt.msc 共享文件夹管理器 6. ...

  4. 抖音主播选品到复盘:8款增长工具提升直播ROI

    随着短视频和直播电商的快速崛起,抖音直播成为品牌和主播们争相布局的风口.想要在激烈的直播竞争中脱颖而出,主播不仅需要精准选品,更要借助多样的增长工具,提升直播的观众转化和最终ROI(投资回报率).本文 ...

  5. ChatMoney智能占星师:不一样的AI工具

    本文由 ChatMoney团队出品 在科技的前沿领域,诞生了一位独特的存在--AI占星师.它并非传统意义上的占星师,而是融合了先进的人工智能技术与神秘的占星学知识. 这能够凭借其强大的数据分析能力和精 ...

  6. 肝了一个月整理了这份Java学习路线导图

    很多人都在问应该怎么样学习java的知识点,java有哪些知识点?最近准备面试了,java知识点太多了又不知道如何开始复习?java的知识点太多太多,学完了又忘了.所以我们可以为每个知识点都整理成一份 ...

  7. 复制REUSE_ALV_GRID_DISPLAY_LVC,给函数添加简易的F4处理能力

    翻遍REUSE_ALV_GRID_DISPLAY_LVC这个函数我们可以发现,这个函数里预定义了一些事件类型. 不过也缺少了一些类型,看看SLIS这个类型池就可以发现,ONF4事件是没有的. 为了把这 ...

  8. 数栈优化案例:物流客户Elasticsearch集群性能优化

    一.客户背景 客户使用ES来进行数据存储.快速查询业务订单记录,但是经常会出现业务高峰期ES集群的cpu负载.内存使用均较高,查询延迟大,导致前端业务访问出现大量超时的情况,极大影响其客户使用体验. ...

  9. 国贸股份 x 袋鼠云:推进全链业务深度数字化,为产业综合服务插上数字化翅膀

    数据治理是推动大型集团企业转型升级.提升竞争优势.实现高质量发展的重要引擎.通过全链数据结构化,实现业务对象.业务规则.业务流程数字化,推进全链业务深度数字化,夯实数据运营底座. 厦门国贸集团股份有限 ...

  10. Claude Code 初体验 - Windows

    1. 前言 Cursor 和 Claude Code 都是编程神器,它们的主要区别是什么呢? Cursor 主要对不同的AI模型进行整合,提供友好的代码编辑体验,包括OpenAI 的 GPT 系列.G ...