开发者学堂课程【理解 Pod 和容器设计模式:【公开课】理解 Pod 和容器设计模式】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/826/detail/13946
【公开课】理解 Pod 和容器设计模式
内容介绍:
一、为什么我们需要 Pod
一、为什么我们需要 Pod
Pod 是 Kubernetes 项目中一个重要的概念,是一个非常最要的原子
1.容器的基本概念
容器的本质:
一个视图被隔离、资源受限的进程
容器里 PID =1 的进程就是应用本身
管理虚拟机=管理基础设施;管理容器=直接管理应用本身
是不可变基础设施最佳的体现
那么 Kubernetes 呢?
Kubernetes 就是云时代的操作系统!
以此类推,容器镜像其实就是:这个操作系统的软件安装包
2.真实操作系统案例
举例: helloworld 程序
helloworld 程序实际上是由一组进程(Linux 里的线程)组成
$ pstree -p
...
|helloworld,3062l
| |-{api},3063
| |-{main} ,3064l
| |-{log} ,3065
| 、-{ compute} ,3133
进程等同于 Linux 里的线程
在 Linux 里查看 helloworld 里面的 pstree
有四个线程组成,api、main、log、compute
这4个进程共享 helloworld 程序的资源,相互协作,完成 helloworld 程序的工作
思考
Kubernetes =操作系统(比如:Linux)
容器=进程(Linux 线程)
Pod = ?
进程组(Linux 线程组)
在真实的操作系统中,一个程序往往是由进程组进行管理
将 Kubernetes 类比为操作系统,如 Linux,也可以类比为进程,容器也可以类比为进程,也就是 Linux 线程,而 Pod 即为进程组,也就是 Linux 线程组这样一个类比关系
3.进程组
举例:
helloworld 程序由4个进程组成,这些进程之间共享某些文件
问题: helloworld 程序如何用容器跑起来呢?
解法一:启动一个 Docker 容器中,启动这4个进程
疑问∶容器 PID= 1的进程就是应用本身比如 main 进程,那么“谁"来负责管理剩余的3个进程?
核心问题:容器是“单进程"模型!
由于容器等于应用等于进程,只能管理 PID=1的进程
除非:
应用进程本身具备"进程管理"能力〈这意味着: helloworld 程序需要具备 systemd 的能力)
或者,容器的 PID=1进程改成 systemd,或者在容器运行 systemd
这会导致:管理容器=管理 systemd !=直接管理应用本身
由于容器实际是一个单进程模型,如果在容器里启动多个进程,只有其中一个可以作为 PID=1的进程,如果 PID=1的进程失败退出了,其他三个进程无法管理和回收资源
如果在容器里运行一个 systemd,用 systemd 来管理其他进程,会出现没办法直接管理应用,应用被 systemd 接管,应用状态的生命周期不等于容器的生命周期
4.Pod=“进程组”
$ pstree -p
...
|helloworld,3062l
| |-{api},3063
| |-{main} ,3064l
| |-{log} ,3065
| 、-{ compute} ,3133
apiVersion: v1
kind: Pod
metadata:
name: helloworld
spec: .
containers:
- name: api
image: api
ports:
- containerPort: 80
- name: main
image: main
- name: log
image: log
volumeMounts:
- name: log-storage
name: compute
image: compute
volumeMounts:
- name: data-storage
在 Kubernetes 里面,Pod 实际上是 Kubernetes 项目抽象出来的一个可以类比为进程组的概念。由四个进程共同组织的一个应用 helloworld,在 Kubernetes 里面实际上会被定义为一个拥有四个容器的 Pod。有四个进程,有四个职责不同、相互协作的进程要需要放在容器里运行。
在 Kubernetes 里,并不会将他们一起放入一个容器里,在 Kubernetes 中,把四个独立的进程分别用四个独立的容器启动起来,然后定义在一个 Pod 中。当Kubernetes 把 helloworle 运行起来时,实际上会看到四个容器。他们共享某些资源,这些资源都属于 Pod。Pod 在 Kubernetes 中只是一个逻辑单位,没有一个真实的东西对应这个P od。物理上存在的是四个容器,这四个容器的组合成为 Pod,Pod 是 Kubernetes 分配资源的一个单位。因为这些容器它要共享资源,所以 Pod是多个容器的组合 Kubernetes 的原子调度单位
Pod:一个逻辑单位,多个容器的组合 Kubernetes 的原子调度单位
5.来自 Google Borg 的思考
Google 的工程师们发现,在 Borg 项目部署的应用,往往都存在着类似于“进程和进程组”的关系。更具体地说,就是这些应用之间有着密切的协作关系,使得它们必须部署在同一台机器上并且共享某些信息
是进程组的概念,也是 Pod 的用法
- Large-scale cluster management at Google with Borg, EuroSys'15
6.为什么 Pod 必须是原子调度单位
举例:两个容器紧密协作
App:业务容器,写日志文件
LogCollector:转发日志文件到 ElasticSearch 中
内存要求:
App: 1G
LogCollector: 0.5G
当前可用内存:
Node_A: 1.25G
Node_B: 2G
如果 App 先被调度到了 Node_A 上,会怎么样?
LogCollector 无法调度到了 Node_A 上,因为资源不够
整个应用本身出现问题
Task co-scheduling 问题
Mesos:资源囤积(resource hoarding) :
所有设置了 Affinity 约束的任务都达到时,才开始统一进行调度
调度效率损失和死锁
Google Omega:乐观调度处理冲突:
先不管这些冲突,而是通过精心设计回轨机制在出现了冲突之后解决问题
复杂
Kubernetes: Pod
7.再次理解Pod
亲密关系-调度解决
两个应用需要运行在同一台宿主机上
超亲密关系-Pod 解决
会发生直接的文件交换
使用 localhost 或者 Socket 文件进行本地通信
会发生非常频繁的 RPC 调用
会共享某些 Linux Namespace (比如,一个容器要加入另一个容器的Network Namespace)


