Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【3】validating_admission.go源码解析

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
云解析 DNS,旗舰版 1个月
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【3】validating_admission.go源码解析

文章目录

相关阅读:


Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【1】动手实践感受区别所在

KubernetesImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【3】validating_admission.go源码解析

Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【4】main.go源码解析

kubernetes 快速学习手册

1. 代码依赖

https://pkg.go.dev/k8s.io/api/admission/v1beta1#AdmissionReview

https://pkg.go.dev/k8s.io/api/core/v1#PhotonPersistentDiskVolumeSource.XXX_Size

https://pkg.go.dev/k8s.io/api/imagepolicy/v1alpha1#ImageReview


源码:https://github.com/kainlite/kube-image-bouncer

2. handler的validating_admission.go

我们分析完了handlerImage_Policy.go,接下来运用同样的方式分析validating_admission.go

我们看一下报错信息

$ kubectl describe rc nginx-latest  #警告不允许有latest标签的镜像
.....
Warning  FailedCreate  11s (x14 over 53s)  replication-controller  Error creating: admission webhook "image-bouncer-webhook.default.svc" denied the request: Images using latest tag are not allowed

搜索关键词:Images using latest tag are not allowed

我们看的在validating_admission.go的51行找到了

1670930810269.png

2.1 metav1.status是什么?

我们首先看一下代码的依赖去向

1035234-20181020215539574-213176954.png

metav1是什么包,还记得在上一篇文章我提到过吧

meta 是字面标签的意思,v1表达的是版本。

包v1包含所有版本都通用的API类型,但它们分为两类,一类是对外的,也就是能为我们开发定制的,另一部分是内部的。总之,我们纵观全览,这个包定义了k8s许多资源对象。

1035234-20181020215539574-213176954.png

status.message这里描述的是设定操作状态的描述。根据代码功能需求的描述"Images using latest tag are not allowed",正是我们需要表达的。

2.2 admissionReview.Response.Result是什么?

它的来源是"k8s.io/api/admission/v1beta1",地址是https://pkg.go.dev/k8s.io/api/admission/v1beta1,搜索AdmissionReview

1035234-20181020215539574-213176954.png

AdmissionReviewImageReview大同小异,这是定义对象类型、请求属性、返回属性。

1035234-20181020215539574-213176954.png

admissionReview.Response.Allowed 是一个布尔值

admissionReview.Response.Result代表的是*metav1.Status类型,然而status的结构体又是包含什么呢?如图:

1035234-20181020215539574-213176954.png

meta.status.message表达的是对此状态的一种描述。正好对于代码的输出内容:"Images using latest tag are not allowed"


再往上分析一下usingLatest,即假如存在usingLatest,就将是否允许运用拉取的布尔值设置为false,并输出一个关于存在lastest的描述性问题。

1035234-20181020215539574-213176954.png

usingLatest来自rules.IsUsingLatestTag(container.Image),根据上篇文章Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析,详细的分析,此函数


当镜像仓库名称不对的时候返回:false,err;

当存在lastest的时候返回:true,nil;

当仓库名正确并且不存在lastest的时候返回:false,nill

这个有一个与Image_Policy.go不一样的地方,即镜像的获取方式。

1035234-20181020215539574-213176954.png

那么它们的区别是什么?

pod来自v1.Pod{},依赖包k8s.io/api/core/v1,v1代表稳定版本。

imageReview来自v1alpha1.ImageReview,aplha1代表随时可能抛弃或者存在bug的版本,ImageReview这个结构体主要的目的是为了存放检查pod的镜像的各种存在可能性结果。而pod这个结构体主要的目的是为了存放或者说是描述运行pod的各种信息,包括容器一系列的细节。


为什么他们获取的容器镜像不一样呢,自然是针对不同的准入控制对象有已经成熟的依赖包。根据他们各自所需,通过各自的API获取镜像的方式也就大同小异,回想当初我们部署ImagePolicyWebhook与ValidatingAdmissionWebhook的时候,ImagePolicyWebhook的针对资源对象是image,依赖的包自然是k8s.io/api/imagepolicy/v1alpha1,而ValidatingAdmissionWebhook则是部署一个k8s资源对象pod,自然依赖的包k8s.io/api/admission/v1beta1。


回到validating_admission.go,我们自上而下推断一下这个文件代码的整体流程。


c.bind即是echo web客户端绑定的方法,为了输出打印admissionReview结构体的相关性信息。根据是否报错,输出相关返回结果。

pod := v1.Pod{}是一个获取pod列表的方法。

对admissionReview.Response进行初始化,并根据是否有lastest以及是否来自健康的仓库即代码里标注是白名单,修改标志性状态。

最后打印接受或者拒绝此镜像的信息,并通过http返回admissionReview的json格式。

那么这里有一个问题来了。RegistryWhitelist的逻辑判断是怎么实现的呢?

1035234-20181020215539574-213176954.png

rules.IsFromWhiteListedRegistry来自rules目录下from_whitelisted_registry.go,rules目录下的代码是定制逻辑判断规则细节的地方。而validating_admission.go整体看来是对此规则运行的一层包装。

代码如下:

1035234-20181020215539574-213176954.png

reference.ParseNormalizedNamed(image)在上篇文章中,我们已经做过分析。是对镜像格式严谨式的一次检查,并最终返回它完整的名字。即 r.Name() + ":" + r.tag + "@" + r.digest.String()

res := strings.SplitN(named.Name(), "/", 2)指定切割成两个字符串,如果len(res)不等于2表示没有仓库名,返回false

最后如果有仓库名呢,遍历res的字符串,判断是否与whitelist,即符合白名单的仓库名,返回true,nil

终于,validating_admission.go的代码分析结束。我们做一下总结吧。

3. 总结

关于k8s的包有很多,我们无法记住它全部的使用的方式,但是我们可以先弄清楚知道包名就能推测它的作用,包含了哪些可能的方法。另外,源码包文档有清晰的关于结构体、方法、函数的目录。多看关于项目中涉及到的k8s的应用对提高k8s开发大有裨益,有些常用的方法我可以积累去保存作为笔记,比如:c.Bind(&imageReview)、for _, container := range imageReview.Spec.Containers、rules.IsUsingLatestTag(container.Image)、for _, container := range pod.Spec.Containers、admissionReview.Response.Result = &metav1.Status等等。

关于准入控制ImagePolicyWebhook与ValidatingAdmissionWebhook的开发,目前大概有了个思路,他们有已成熟的API包,根据我们的需求依赖包可以满足我们如何去开发,当然,提供给api-server去调用做出检测,我们就需要一个URL接口,而echo 这个依赖包恰好是非常便利的处理绑定k8s资源信息。除此之外,运用的则是处理输出格式的依赖应用包或者逻辑判断所需的成熟接口方法的包。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
6天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
21 2
|
7天前
|
存储 安全 Linux
Golang的GMP调度模型与源码解析
【11月更文挑战第11天】GMP 调度模型是 Go 语言运行时系统的核心部分,用于高效管理和调度大量协程(goroutine)。它通过少量的操作系统线程(M)和逻辑处理器(P)来调度大量的轻量级协程(G),从而实现高性能的并发处理。GMP 模型通过本地队列和全局队列来减少锁竞争,提高调度效率。在 Go 源码中,`runtime.h` 文件定义了关键数据结构,`schedule()` 和 `findrunnable()` 函数实现了核心调度逻辑。通过深入研究 GMP 模型,可以更好地理解 Go 语言的并发机制。
|
19天前
|
消息中间件 缓存 安全
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
39 3
|
1月前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
53 5
|
14天前
|
安全 测试技术 Go
Go语言中的并发编程模型解析####
在当今的软件开发领域,高效的并发处理能力是提升系统性能的关键。本文深入探讨了Go语言独特的并发编程模型——goroutines和channels,通过实例解析其工作原理、优势及最佳实践,旨在为开发者提供实用的Go语言并发编程指南。 ####
|
18天前
|
Go
|
1月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
67 0
|
1月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
54 0
|
1月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
60 0
|
1月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
80 0

推荐镜像

更多