惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V2EX - 技术
V2EX - 技术
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
S
Securelist
P
Privacy & Cybersecurity Law Blog
Scott Helme
Scott Helme
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
量子位
博客园 - Franky
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
T
Troy Hunt's Blog
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
N
Netflix TechBlog - Medium
小众软件
小众软件
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学
L
Lohrmann on Cybersecurity
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Last Watchdog
The Last Watchdog
S
Security @ Cisco Blogs
P
Privacy International News Feed
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
T
Tailwind CSS Blog
博客园_首页
云风的 BLOG
云风的 BLOG
V
Vulnerabilities – Threatpost
D
DataBreaches.Net
Recent Announcements
Recent Announcements
酷 壳 – CoolShell
酷 壳 – CoolShell
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
罗磊的独立博客
Engineering at Meta
Engineering at Meta
Forbes - Security
Forbes - Security
T
Tenable Blog

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念 软件版本语义化
Kubernetes - CRI 概述
2023-11-07 · via 蛮荆

2023-11-07 Cloud Native Kubernetes 读代码

概述

CRI(Container Runtime Interface, 容器运行时接口)是 Kubernetes 用于管理容器运行时和容器镜像的 gRPC 协议接口集合,kubelet 可以通过 CRI 来使用不同的容器运行时,而无需重新编译集群组件。

为了保证 CRI 可以正常工作,Kubernetes 集群中的每个节点都需要有一个实现了 CRI 的具体容器运行时 (例如 containerd),这样 kubelet 可以直接对 Pod 及其内部容器进行操作。

下面以 containerd 为例进行说明,containerd 是来自 Docker 的高级容器运行时,实现了 CRI 规范

containerd 实现了 CRI

宏观接口模型

因为 Pod 是 Kubernetes 中应用运行的最小单位,此外容器运行时除了运行、重启、停止 Pod 操作外,还有容器对应的镜像拉取、删除等操作, 结合两者,我们可以给出一个粗糙的 CRI 模型示例图:

CRI 模型

然后就可以直接将上述接口模型转化成伪代码 (Go 语言实现):

type CRI interface {
	PullImage(name string)   // 拉取容器镜像
	RemoveImage(name string) // 删除容器镜像

	StartPod(name string)  // 启动 Pod
	StopPod(name string)   // 停止 Pod
	RemovePod(name string) // 删除 Pod

	StartContainer(name string)  // 启动 Pod
	StopContainer(name string)   // 停止 Pod
	RemoveContainer(name string) // 删除 Pod
}

// Containerd (模拟) 实现了 CRI 接口
type Containerd struct {
}

func (c *Containerd) PullImage(name string)       {}
func (c *Containerd) RemoveImage(name string)     {}
func (c *Containerd) StartPod(name string)        {}
...
func (c *Containerd) RemoveContainer(name string) {}

// Rktlet (模拟) 实现了 CRI 接口
type Rktlet struct {
}

func (r *Rktlet) PullImage(name string)       {}
func (r *Rktlet) RemoveImage(name string)     {}
func (r *Rktlet) StartPod(name string)        {}
...
func (d *Rktlet) RemoveContainer(name string) {}

// CRI-O 实现了 CRI 接口
type CRI-O struct {
}

func (c *CRI-O) PullImage(name string)       {}
func (c *CRI-O) RemoveImage(name string)     {}
func (c *CRI-O) StartPod(name string)        {}
...
func (c *CRI-O) RemoveContainer(name string) {}

通过上面的伪代码,我们可以对 CRI 有一个基础的认识,下面我们一起看看 Kubernetes 中 CRI 的代码,学习一下成熟的方案和设计思路。


Kubernetes 中的 CRI

Kubernetes 中的 CRI 功能对应的源代码位于 Kubernetes 项目的 staging/src/k8s.io/cri-api 目录,本文以 Kubernetes v1.28 版本源代码进行分析。

CRI 定义和实现使用的是 gRPC 协议,在对应的 gRPC 定义文件中,可以看到两个 Service:

  1. RuntimeService: 定义了容器运行时的相关操作 API
  2. ImageService: 定义了容器镜像管理的相关操作 API
// cri-api/pkg/apis/runtime/v1/api.proto

service RuntimeService {
    rpc Version(VersionRequest) returns (VersionResponse) {}
	
    rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
    rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
    rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
	
	...
}

service ImageService {
    rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
    rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
	
	...
}

上面的 Service 对应的 Go 代码如下:

// cri-api/pkg/apis/services.go

type RuntimeVersioner interface {
	Version(ctx context.Context, apiVersion string) (*runtimeapi.VersionResponse, error)
}

// 容器管理接口
type ContainerManager interface {
	CreateContainer(ctx context.Context, podSandboxID string, ...) (string, error)
	StartContainer(ctx context.Context, containerID string) error
	StopContainer(ctx context.Context, containerID string, timeout int64) error
	RemoveContainer(ctx context.Context, containerID string) error
	ListContainers(ctx context.Context, filter *runtimeapi.ContainerFilter) ([]*runtimeapi.Container, error)
    ...
}

// Pod 管理接口
type PodSandboxManager interface {
	RunPodSandbox(ctx context.Context, ...) (string, error)
	StopPodSandbox(pctx context.Context, odSandboxID string) error
	RemovePodSandbox(ctx context.Context, podSandboxID string) error
    ...
}

// 通过内嵌上述几个接口,形成一个 CRI 主要接口
type RuntimeService interface {
	RuntimeVersioner
	ContainerManager
	PodSandboxManager

	UpdateRuntimeConfig(ctx context.Context, runtimeConfig *runtimeapi.RuntimeConfig) error
	Status(ctx context.Context, verbose bool) (*runtimeapi.StatusResponse, error)
	RuntimeConfig(ctx context.Context) (*runtimeapi.RuntimeConfigResponse, error)
}

// 镜像管理接口
type ImageManagerService interface {
	PullImage(ctx context.Context, image *runtimeapi.ImageSpec, ...) (string, error)
	RemoveImage(ctx context.Context, image *runtimeapi.ImageSpec) error
	...
}

containerd

containerd, Docker 和 CRI 交互

这里以 containerd 为例,看看其内部关于 CRI 接口的具体代码结构,时间所限,这里只留下相关代码骨架截图,具体的源代码不再进行分析。

remote_image.go 实现了容器镜像相关操作

remote_runtime.go 实现了容器运行时相关操作

Reference

扩展阅读