Skip to content

Commit

Permalink
更新容器编排
Browse files Browse the repository at this point in the history
  • Loading branch information
isno committed Mar 10, 2024
1 parent 5a87abe commit 8fc4658
Showing 1 changed file with 19 additions and 11 deletions.
30 changes: 19 additions & 11 deletions container/orchestration.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,36 @@

那么,容器是本质什么呢?如果吧 Kubernetes 比作云原生时代的操作系统,那么容器就是这个操作系统之内的特殊进程。

特殊之处在于容器利用操作系统内核技术通过约束和修改进程的动态表现,从而为其创造一出一个“边界”。实现“边界”的核心技术是 namespace(隔离,)、cgroup(约束能用多少资源,内存/磁盘。cpu等)

特殊之处在于容器利用 namespace 对其视图进行隔离,利用 cgroup(约束能用多少资源,内存/磁盘。cpu等)对其资源使用进行约束。

使用 Namespace 其实也非常简单,它其实只是 Linux 创建新进程的一个可选参数。比如,在 Linux 系统中创建线程的系统调用是 clone。
```
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
```

:::tip 沙盒
当我们创建一个新的进程时,

容器并不是真正的沙盒,也不是轻量化的虚拟机。
:::
```
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
```

这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID 是 1。

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

容器技术是动态的容器、静态的镜像、远程的仓库这三者的组合。
隔离之后,还有一个关键问题:操作系统如何管理或者限制被隔离进程使用的资源(CPU、内存、网络带宽、磁盘等)?这就是上面提到的第二项技术了: Linux Control Cgroup,即 cgroups。

cgroups 是一种内核级别的资源管理机制,最早由 Google 工程师在 2007年提出,它主要的作用就是限制一个进程组所使用的资源上限。使用 cgroups 也很方便,通过 /sys/fs/cgroup 查看系统支持的被限制的资源种类。然后再想限制的资源下新建一个目录,配置资源的限制,绑定指定的进程即可。

由此可见,容器不是轻量化的虚拟机,也没有创造出真正的沙盒(共享了操作系统内核,这也是为什么又出现了 kata、gVisor 等沙盒容器),只是使用了 namespace 技术进行隔离、cgroups 技术进行资源限制的进程。。

## 容器编排的第一个扩展是进程组

在一个真正的 OS 内,进程并非“孤苦伶仃”独自运行,而是以进程组,有原则的组织在一起,。登录到一台 Linux 机器,展示当前系统中正在运行的进程述状结构,执行如下命令:
在一个真正的 OS 内,进程并非“孤苦伶仃”独自运行,而是以进程组,有原则的组织在一起。

登录到一台 Linux 机器,展示当前系统中正在运行的进程述状结构,执行如下命令:

```
$ pstree -g
Expand All @@ -47,13 +57,11 @@ systemd(1)─┬─abrt-dbus(540)─┬─{abrt-dbus}(540)

那么现在的问题是如果把上面的进程用容器跑起来,你该怎么做?自然的解法启动一个 Docker 容器,里面运行四个进程,可是这样会有一个问题:容器里面 PID=1 的进程该是谁?这个核心问题在于容器的设计本身是一种“单进程”模型,不是说容器里只能起一个进程,而是容器的应用等于进程,Docker 只能通过监视 PID 为 1 的进程的运行状态来判断容器的工作状态是否正常。

再或者把进程 PID = 1 的进程改为可以管理进程应用(例如 supervisord)。但改成 supervisord 的问题容器生命周期不再是工作进程的生命周期(而是supervisord),工作进程是否正常也无法在直接知道。

如果现在我们把容器与进程在概念上对应起来,那容器编排的第一个扩展点,就是要找到容器领域中与“进程组”相对应的概念,这是实现容器从隔离到协作的第一步。
既然我们把容器与进程在概念上对应起来,那容器编排的第一个扩展点,就是要找到容器领域中与“进程组”相对应的概念,这是实现容器从隔离到协作的第一步。

## 超亲密容器组

进程组的实现在 Kubernetes 中叫做 Pod。
进程组的实现在 Kubernetes 中叫做 Pod,Pod 是 Kubernetes 中最基本、最重要的概念

容器之间原本是被 Linux Namespace 和 cgroups 隔开的,Pod 第一个要解决的问题是怎么去打破这个隔离,让 Pod 内的容器可以像进程组一样天然的共享资源和数据(例如网络和存储)。

Expand Down

0 comments on commit 8fc4658

Please sign in to comment.