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

简介: 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资源信息。除此之外,运用的则是处理输出格式的依赖应用包或者逻辑判断所需的成熟接口方法的包。


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
10月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
1043 0
|
8月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟蒋星熠Jaxonic,Go语言探索者。深耕云计算、微服务与并发编程,以代码为笔,在二进制星河中书写极客诗篇。分享Go核心原理、性能优化与实战架构,助力开发者掌握云原生时代利器。#Go语言 #并发编程 #性能优化
665 43
Go语言深度解析:从入门到精通的完整指南
|
9月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟 蒋星熠Jaxonic,执着的星际旅人,用Go语言编写代码诗篇。🚀 Go语言以简洁、高效、并发为核心,助力云计算与微服务革新。📚 本文详解Go语法、并发模型、性能优化与实战案例,助你掌握现代编程精髓。🌌 从goroutine到channel,从内存优化到高并发架构,全面解析Go的强大力量。🔧 实战构建高性能Web服务,展现Go在云原生时代的无限可能。✨ 附技术对比、最佳实践与生态全景,带你踏上Go语言的星辰征途。#Go语言 #并发编程 #云原生 #性能优化
|
12月前
|
存储 设计模式 安全
Go 语言单例模式全解析:从青铜到王者段位的实现方案
单例模式确保一个类只有一个实例,并提供全局访问点,适用于日志、配置管理、数据库连接池等场景。在 Go 中,常用实现方式包括懒汉模式、饿汉模式、双重检查锁定,最佳实践是使用 `sync.Once`,它并发安全、简洁高效。本文详解各种实现方式的优缺点,并提供代码示例与最佳应用建议。
400 5
|
10月前
|
缓存 监控 安全
告别缓存击穿!Go 语言中的防并发神器:singleflight 包深度解析
在高并发场景中,多个请求同时访问同一资源易导致缓存击穿、数据库压力过大。Go 语言提供的 `singleflight` 包可将相同 key 的请求合并,仅执行一次实际操作,其余请求共享结果,有效降低系统负载。本文详解其原理、实现及典型应用场景,并附示例代码,助你掌握高并发优化技巧。
735 0
|
10月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
存储 算法 Go
【LeetCode 热题100】17:电话号码的字母组合(详细解析)(Go语言版)
LeetCode 17题解题思路采用回溯算法,通过递归构建所有可能的组合。关键点包括:每位数字对应多个字母,依次尝试;递归构建下一个字符;递归出口为组合长度等于输入数字长度。Go语言实现中,使用map存储数字到字母的映射,通过回溯函数递归生成组合。时间复杂度为O(3^n * 4^m),空间复杂度为O(n)。类似题目包括括号生成、组合、全排列等。掌握回溯法的核心思想,能够解决多种排列组合问题。
535 11
|
Go
【LeetCode 热题100】155:最小栈(详细解析)(Go语言版)
本文详细解析了力扣热题155:最小栈的解题思路与实现方法。题目要求设计一个支持 push、核心思路是使用辅助栈法,通过两个栈(主栈和辅助栈)来维护当前栈中的最小值。具体操作包括:push 时同步更新辅助栈,pop 时检查是否需要弹出辅助栈的栈顶,getMin 时直接返回辅助栈的栈顶。文章还提供了 Go 语言的实现代码,并对复杂度进行了分析。此外,还介绍了单栈 + 差值记录法的进阶思路,并总结了常见易错点,如 pop 操作时忘记同步弹出辅助栈等。
445 6
|
Go 索引
【LeetCode 热题100】739:每日温度(详细解析)(Go语言版)
这篇文章详细解析了 LeetCode 第 739 题“每日温度”,探讨了如何通过单调栈高效解决问题。题目要求根据每日温度数组,计算出等待更高温度的天数。文中推荐使用单调递减栈,时间复杂度为 O(n),优于暴力解法的 O(n²)。通过实例模拟和代码实现(如 Go 语言版本),清晰展示了栈的操作逻辑。此外,还提供了思维拓展及相关题目推荐,帮助深入理解单调栈的应用场景。
494 6
|
存储 算法 物联网
解析局域网内控制电脑机制:基于 Go 语言链表算法的隐秘通信技术探究
数字化办公与物联网蓬勃发展的时代背景下,局域网内计算机控制已成为提升工作效率、达成设备协同管理的重要途径。无论是企业远程办公时的设备统一调度,还是智能家居系统中多设备间的联动控制,高效的数据传输与管理机制均构成实现局域网内计算机控制功能的核心要素。本文将深入探究 Go 语言中的链表数据结构,剖析其在局域网内计算机控制过程中,如何达成数据的有序存储与高效传输,并通过完整的 Go 语言代码示例展示其应用流程。
269 0

推荐镜像

更多