在上一期,我们提到了,容器运行时引擎需要符合CRI规范。
CRI规范中,有三类接口:
1、获取对方的CRI版本;
2、RuntimeService类型的调用,用于创建、停止、列出运行时对象——sandbox或container。
3、ImageService类型的调用,可以列出、拉取、查看状态、移除容器镜像。
我们注意到,运行时对象有两种——一种叫container,另一种叫sandbox。它们之间有什么区别呢?
实际上,我们很好理解container是什么。前文中提到的,利用docker run命令运行的容器,实际上就是一个container。
而sandbox,对外的名称叫pod,字面意思是“豆荚”。
顾名思义,pod是豆荚,豆荚中可以有多个豆子。每个豆子实际上就是一个容器。
我们知道,Kubernetes是一个使用了面向对象思想设计的系统,每种资源在Kubernetes中都以对象的方式存在。
对象是有生命周期的。Pod对象的生命周期如下图所示:
我们会发现,在一个pod的生命历程中,除了提供服务的main container外,还有init container。
当然,我们可以在yaml文件中描述init container:
代码语言:javascript复制apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: ikubernetes/myapp:v1
initContainers:
-name: init-foobar
image: busybox
command: ['sh', '-c', 'sleep 10']
注意到这个范例中,initcontainers的描述,它启动了一个busybox,并且运行了一条命令,休眠10秒。在init container运行完毕后,kubelet会启动main container。
如main container的字面意义,pod中的这个容器运行着主要功能,如果pod中还有其他容器,只是为它提供支持服务的“边斗”(sidecar)。
图上就是具备了sidecar的侉界之王——长江750摩托车。它加装了边斗以后,可以装备7.62mm机枪或40mm火箭筒,大大增强了战斗力,成为高机动性的战车。
同样地,Kubernetes可以为container装备sidecar,形成一个pod,也可以实现非侵入式的微服务架构等。微服务架构的话题我们将在其他专题里面详解。
我们梳理一下kubelet启动pod的过程,如果pod中有1个init container,1个main container,1个sidecar。它会调用几次CRI接口呢?
这个问题比较简单,我们不留到下期了,就在这里解答吧:
- 首先创建pod:调用RunPodSandbox;
- 启动init container: 调用CreateContainer和RunContainer;
- init container执行完毕后,调用RemoveContainer移除init container;
- 调用CreateContainer和RunContainer启动main container和sidecar;
当然,在main container和sidecar运行期间,kubelet还可以通过ContainerStatus等调用,监控Pod内各个container的运行状态。
我们还注意到,在main container的生命周期中,有两个新的概念:post start hook和pre stop hook。它们的作用是什么呢?
原来,这两个概念指的是函数钩子。post start hook可以在容器初始化时调用,而pre stop hook会在停止容器运行前操作,并阻塞容器删除调用,也就是说,pre stop hook的调用完成之前,是不会进入容器删除流程的。
今天遗留了一个小问题:kubelet是如何探测容器的工作状态呢?
下一期中,我们将揭开谜底。