继续上文未完的内容
4、接口和实现
接口这个词广泛存在于各种技术文档中,到底接口是什么?
其实,狭义的接口是指代码编写的一个技巧,比如在Java语言里面,一个接口(interface)的特性是只定义了方法返回值、名称、参数等,但没有定义其具体的实现。
接口(interface)无法被实例化,但是可以被实现。一个实现(implements)接口的类(class),必须实现接口内所描述的所有方法,否则就必须声明为抽象类(Abstract Class)
Java 接口实现
interface Animal {
public void eat();
public void travel();
}
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
以上是Java的接口类型,但除了狭义的接口,我们在开发各种软件中也会用到广义的接口
接口对于调用方来说就是一种事先约定好的协议,它也许是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
而在Kubernetes里面,其很多组件或者实现都采用了接口的形式,留给使用者非常灵活的扩展空间。
比如CRI \ CSI \ CNI 等等,都是Kubernetes留给其底层实现的接口方式。
Kubernetes作为云原生应用的佳部署平台,已经开放了容器运行时接口(CRI)、容器网络接口(CNI)和容器存储接口(CSI),这些接口让Kubernetes的开放性变得大化,而Kubernetes本身则专注于容器调度
我们逐个了解一下以上3个接口,就可以对Kubernetes的实现思想有一定的感受,从而更深地理解其它类似的接口实现。
CRI(Container Runtime Interface,容器运行时接口)
Kubernetes其实是不会直接和容器打交道,Kubernetes的使用者能接触到的概念只有pod,而pod里包含了多个容器。
CRI中定义了容器和镜像的服务的接口,因为容器运行时与镜像的生命周期是彼此隔离的。
当我们在Kubernetes里用kubectl执行各种命令时,这一切是通过Kubernetes工作节点里所谓“容器运行时”的软件在起作用。大家熟悉的容器运行时软件当然是Docker,然而Docker只是Kubernetes支持的容器运行时技术的一种。
为了让Kubernetes不和某种特定的容器运行时(Docker)技术绑死,而是能无需重新编译源代码就能够支持多种容器运行时技术的替换,和我们面向对象设计中引入接口作为抽象层一样,在Kubernetes和容器运行时之间我们引入了一个抽象层,即容器运行时接口。以后就算Docker不再流行了,甚至有了Eocker、Focker等等,就可以通过CRI接口无缝地融入Kubernetes体系。
CSI(Container Storage Interface,容器存储接口)
CSI 代表容器存储接口,CSI 试图建立一个行业标准接口的规范,借助 CSI 容器编排系统(CO)可以将任意存储系统暴露给自己的容器工作负载。
类似于 CRI,CSI 也是基于 gRPC 实现。CSI 卷类型是一种 in-tree(即跟其它存储插件在同一个代码路径下,随 Kubernetes 的代码同时编译的) 的 CSI 卷插件,用于 Pod 与在同一节点上运行的外部 CSI 卷驱动程序交互。部署 CSI 兼容卷驱动后,用户可以使用 csi 作为卷类型来挂载驱动提供的存储。
CNI(Container Network Interface,容器存储接口)
CNI(Container Network Interface)是CNCF旗下的一个项目,由一组用于配置Linux容器的网络接口的规范和库组成,同时还包含了一些插件。CNI仅关心容器创建时的网络分配,和当容器被删除时释放网络资源。
kubernetes 网络的发展方向是希望通过插件的方式来集成不同的网络方案, CNI 就是这一努力的结果。CNI只专注解决容器网络连接和容器销毁时的资源释放,提供一套框架,所以CNI可以支持大量不同的网络模式,并且容易实现。
CNI的接口中包括以下几个方法:
type CNI interface {
AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (*.Result, error)
DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error
AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*.Result, error)
DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
}
有四个方法:添加网络、删除网络、添加网络列表、删除网络列表