容器运行时接口流式传输解析

💡 原文英文,约1700词,阅读约需6分钟。
📝

内容提要

Kubernetes的容器运行时接口(CRI)连接kubelet与容器运行时,支持Exec、Attach和PortForward等远程过程调用(RPC)。Exec用于在容器内运行命令并流式传输输出,Attach用于连接到正在运行的进程,PortForward则转发主机端口到容器。所有RPC通过gRPC接口进行通信,支持WebSocket以满足最新需求。

🔎

延伸解读

设计权衡:为何采用URL重定向而非原生流式

文章指出,CRI的Exec、Attach和PortForward RPC最初设计于2016年,早于KEP流程。当时考虑过原生gRPC流式传输,但被否决,因为kubelet会成为网络瓶颈,且未来运行时无法自由选择服务器实现细节。最终方案是RPC仅返回一个URL,由运行时提供流式服务器,客户端连接后升级为SPDY或WebSocket进行数据传输。这种设计赋予运行时灵活性,也简化了测试路径。

协议差异:Exec/Attach与PortForward的不同实现

虽然三个RPC表面相似,但内部协议不同。Exec和Attach被定义为远程命令,其协议有五个版本(channel.k8s.io到v5.channel.k8s.io),且每个数据包首字节标识流类型(0-4及255)。PortForward则没有简单协议定义,客户端直接流式传输SPDY帧,需用moby/spdystream等库解析。运行时必须实现kubelet库提供的Runtime接口,其中Exec和Attach需处理协议解释,而PortForward需进入容器网络命名空间并分配端口。

WebSocket迁移与运行时生态影响

KEP #4006推动用WebSocket替换SPDY传输协议,这需要运行时和客户端共同支持。crictl v1.30新增--transport标志,允许在exec、attach和port-forward子命令中选择websocket或spdy。CRI-O实验性地将流式服务器移至conmon-rs(Rust实现的容器监视器),使其能直接支持WebSocket,且CRI-O无需运行即可保持会话。这些变化要求运行时持续跟进最新实现,以保持功能兼容。

❓

Q&A

Kubernetes的容器运行时接口(CRI)是什么?

Kubernetes的容器运行时接口(CRI)是连接kubelet与容器运行时的接口,支持多种远程过程调用(RPC)。

Exec、Attach和PortForward的主要功能是什么?

Exec用于在容器内运行命令并流式传输输出,Attach用于连接到正在运行的进程,PortForward则将主机端口转发到容器。

如何通过CRI与容器进行交互?

通过CRI,客户端可以请求Exec、Attach或PortForward会话,容器运行时实现相应的流式服务器来处理这些请求。

Exec和Attach的协议定义有什么不同?

Exec和Attach被定义为远程命令,具有不同版本的协议定义,而PortForward遵循独特的内部协议定义。

为什么Kubernetes选择使用gRPC进行RPC通信?

Kubernetes选择gRPC进行RPC通信是为了提供灵活性和高效性,允许容器运行时根据需要实现Exec、Attach和PortForward的逻辑。

crictl工具如何增强与容器的交互能力?

crictl工具通过新增--transport标志,允许用户在exec、attach和port-forward命令中选择WebSocket或SPDY作为传输协议。

🏷️

标签

➡️

继续阅读