爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

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

      首页 知识中心 软件开发 文章详情页

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

      2023-05-31 08:44:55 阅读次数:464

      kubernetes,镜像

      . handler的Image_Policy.go

      我们首先看看ImagePolicyWebhook 检验效果的报错信息

      $ kubectl describe rc nginx-latest  #警告不允许有latest标签的镜像
        Warning  FailedCreate  8s (x6 over 87s)  replication-controller  (combined from similar events): Error creating: pods "nginx-latest-f7667" is forbidden: image policy webhook backend denied one or more images: Images using latest tag are not allowed
      

      搜索关键报错语句:Images using latest tag are not allowed

      我们在image_policy.go的37行找到了
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      review.Status.Reason是什么?

      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      从代码中:

      • review.Status.Reason可能是一个字符串类型,存储我们表达的信息。
      • review.Status可能是一个接口之类的东西
      • review是一个v1alpha1.ImageReview类型的变量

      v1alpha1.ImageReview是什么?

      从图中我们知道他来自专属k8s.io/api/imagepolicy/v1alpha`的包。那我们只能去它的源代码库查看了。

      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      看到这里我们知道了,v1alpha1.ImageReview是个结构体,结构体顾名思义是形容一类物体的统称范畴,结构体肯定包含特定属性的组成部分,它即可以抽象的,也可以是具体的。例如:

      type  人 struct {
        中国人  string
        日本人  string
        美国人 string
        .......
      }
      

      我们还可以这样分:

      type  人 struct {
        黄种人  string
        黑种人 string
        白种人 string
      ...........
      }
      
      type  人  struct {
         名字 string
         年龄  int
         籍贯  string
         人体结构  json
         状态   json
      }
      

      总之,从某一个角度,根据我们是否需要想怎么分就怎么分。

      回到本文中来,ImageReview,是描述的什么结构体呢,是一个pod的镜像,有什么内容呢?

      1. metav1.TypeMeta 代表的镜像类型的元信息
      2. metav1.ObjectMeta 代表的镜像对象的元信息
      3. Spec ImageReviewSpec 代表的镜像的细节描述信息
      4. Status ImageReviewStatus 代表的镜像的状态
      metav1是表达的什么?

      meta 是标签的意思,v1表达的是版本。
      最后发现meta其实也是一个包,它的调用方式是k8s.io/apimachinery/pkg/apis/meta/v1
      这个包包含了什么?
      包v1包含所有版本都通用的API类型,但它们分为两类,一类是对外的,也就是能为我们开发定制的,另一部分是内部的。总之,我们纵观全览,这个包定义了k8s许多对象。我们继续往下看

      metav1.TypeMeta中的TypeMeta包含了什么?
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      原来,TypeMeta也是结构体,里边包含:

      • kind: 对象类型,这个我们非常常见,描述资源对象的类型。专业术语描述就是:Kind是一个字符串值,表示该对象所表示的REST资源,不能被更新。
      • APIversion: APIVersion定义了对象的这种表示的版本模式。
      metav1.ObjectMeta包含了什么?

      这个不用多说,一查就能知道;由于它的描述非常庞大,这里不展示原文注释,只展示这个结构体有什么,让我们心里有个大概。但陌生的内容我会加点注释。

      type ObjectMeta struct {
      	Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
      	#GenerateName是一个可选的前缀,由服务器使用,以生成惟一的name ONLY如果没有提供name字段。
      	GenerateName string `json:"generateName,omitempty" protobuf:"bytes,2,opt,name=generateName"`
      	Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`
      	#SelfLink是一个表示这个对象的URL,Kubernetes将在1.20版本中停止传播该字段,该字段已经计划好了在1.21版本中被删除
      	SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,4,opt,name=selfLink"`
      	UID types.UID `json:"uid,omitempty"protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"`
      	#ResourceVersion表示该对象的内部版本的不透明值,客户端可使用该值确定对象何时发生更改。可以用于乐观并发、更改检测和对资源或资源集的监视操作。客户端必须将这些值视为不透明的,并将未经修改的值传回服务器。它们可能只对特定的资源或资源集有效。
      	ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"`
      	#Generation表示所需状态的特定生成的序列号
      	Generation int64 `json:"generation,omitempty" protobuf:"varint,7,opt,name=generation"`
      	CreationTimestamp Time `json:"creationTimestamp,omitempty" protobuf:"bytes,8,opt,name=creationTimestamp"`
      	DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"`
      	#DeletionGracePeriodSeconds在将该对象从系统中删除之前,允许该对象正常终止的秒数。仅当还设置了deletionTimestamp时设置。可能只会缩短。
      	DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"`
      	#Labels可用于组织和分类(范围和选择)对象的字符串键和值的映射。可以匹配复制控制器和服务的选择器。
      	Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`
      	#注释是一种非结构化的键值映射,存储在资源中,外部工具可以设置该资源来存储和检索任意元数据。它们是不可查询的,在修改对象时应该保留它们。
      	Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`
      	
      	#由该对象依赖的对象列表,如果列表中的所有对象都有被删除,该对象将被垃圾回收。如果该对象由控制器管理,那么这个列表中的一个条目将指向这个控制器,当控制器字段设置为true时。管理控制器不能多于一个。
      	OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"`
      #在 k8s 删除对应资源时同时删除关联的外部资源,那么可以通过 Finalizers 来实现。Finalizers 是由字符串组成的列表,当 Finalizers 字段存在时,相关资源不允许被强制删除。存在 Finalizers 字段的的资源对象接收的第一个删除请求设置 metadata.deletionTimestamp 字段的值, 但不删除具体资源,在该字段设置后, finalizer 列表中的对象只能被删除,不能做其他操作。当 metadata.deletionTimestamp 字段非空时,controller watch 对象并执行对应 finalizers 的动作,当所有动作执行完后,需要清空 finalizers ,之后 k8s 会删除真正想要删除的资源。
      	Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"`
      	ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"`
      	#ManagedFields包含了唯一的管理器。 管理器由管理实体自身的基本信息组成,比如操作类型、API 版本、以及它管理的字段。机制追踪对象字段的变化。 当一个字段值改变时,其所有权从当前管理器(manager)转移到施加变更的管理器。 
      	ManagedFields []ManagedFieldsEntry `json:"managedFields,omitempty" protobuf:"bytes,17,rep,name=managedFields"`
      
      }
      

      内容非常常见,当我们执行kubectl descibe pod 或者kubectl get pod ....-oyaml就能看到这类信息,作为运维k8s人员,大家应该知道他们的含义。

      ImageReviewSpec作为spect的类型有什么?

      如下:

      type ImageReviewSpec struct {
           #Containers是正在创建的Pod的每个容器中的信息子集的列表
      	Containers []ImageReviewContainerSpec `json:"containers,omitempty" protobuf:"bytes,1,rep,name=containers"`
      	#annotation是从Pod的注释中提取的键值对列表。webhook有时会用到它。
      	Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,2,rep,name=annotations"`
      	Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`
      }
      
      ImageReviewStatus 作为Status的类型包含了什么?

      如下:

      type ImageReviewStatus struct {
          #Allowed表示允许运行所有映像
      	Allowed bool `json:"allowed" protobuf:"varint,1,opt,name=allowed"`
      	#显示报错信息
      	Reason string `json:"reason,omitempty" protobuf:"bytes,2,opt,name=reason"`
      	#对象的属性对象将添加AuditAnnotations,允许控制器使用'AddAnnotation',key应该没有前缀(即,允许控制器将添加一个合适的前缀)。
      	AuditAnnotations map[string]string `json:"auditAnnotations,omitempty" protobuf:"bytes,3,rep,name=auditAnnotations"`
      }
      

      奥,看到这里终于明白了。回到我们的代码中,原来review.Status.Reason是留给我们设置输出报错信息的。

      同时呢,我们也根据review.Status.Allowed的源代码库的解释,也明白了它在我们代码中的意义。即是否允许镜像运行的一个判断标志,其实根据代码含义我们也能推测出来。假如allow=true,表达运行镜像运行容器,allow=false,输出错误,并break停止运行程序。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      同时,我们也发现了for循环中的imageReview.Spec.Containers,如果你浏览了代码库,定也明白它的含义,那就是显示正在创建的Pod的每个容器中的信息子集的列表。

      我们注意到for循环中有一个container.Image,它是怎么来的呢?
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      发现 ImageReviewContainerSpec是有结构体的,里边包含image,同时,ImageReviewContainerSpec作为containers的切片对象,所以我们知道container.Image只是显示pod里的容器镜像,通过apped方法把所有镜像添加images切片中,当然,要提前做好切片初始化images := []string{}。

      3. rule目录的not_latest.go

      毫无疑问,代码中rule的方法,我们是引用的不是源代码库,而是本项目中的另一个代码文件的方法,它在rule目录中。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      rules目录下有:
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      我们找到了,它不叫方法,它叫函数调用。我们看看这个函数里写了什么逻辑。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      传入镜像参数,通过调用reference.ParseNormalizedNamed函数返回名字,我们又要看看这个reference.ParseNormalizedNamed到底是什么逻辑,能明白它的准确意思,不能靠猜。所以,我们还有继续寻找代码的源头。

      我们找到了这个函数所在的目录,具体是哪个文件呢?
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      normalize.go

      找关键词ParseNormalizedNamed和normalize.go有点关联。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      果然找到了,注释翻译是:ParseNormalizedNamed将字符串解析为命名引用,将Docker UI中的熟悉名称转换为完全限定引用。如果值可能是一个标识符,则使用ParseAnyReference。

      没看明白,还是看具体代码逻辑吧

      anchoredIdentifierRegexp.MatchString

      anchoredIdentifierRegexp.MatchString又是什么?在这个normalize.go没有发现,通过关键词Regexp找,应该同目录下的regexp.go
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      果然又找到了,注释翻译:anchoredIdentifierRegexp用于检查或匹配标识符值,锚定在字符串的开始和结束。问题又来了,anchored(IdentifierRegexp)又是啥,我点慌了,我像个鼹鼠挖地洞。

      这个函数翻译描述是通过添加开始和结束分隔符锚定正则表达式。类似传达一个正则表达式的意思。就是分隔符匹配

      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      regexp.Regexp是包regexp的结构体,看看是啥,是个空结构体,空结构体不占据内存空间,因此被广泛作为各种场景下的占位符使用。一是节省资源,二是空结构体本身就具备很强的语义,即这里不需要任何值,仅作为占位符。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      奥,看到这里明白一件事,MatchString是Regexp的方法,也就是,Regexp.MatchString是可以调用,而Regexp结构体本身是anchored函数的传参,anchored(ShortIdentifierRegexp)又被定义anchoredShortIdentifierRegexp,所以,根据go语言的传递规则,anchoredShortIdentifierRegexp可以直接调用Regexp的MatchString,即anchoredIdentifierRegexp.MatchString(s),它是什么意思呢?那就 得明白anchored的return的正则匹配规则,负责检查s(字符串)格式是否负责这个规则。也就是说看看这个规则match(^+ expression(res...).String() +$)是什么意思。
      代码中

      var match = regexp.MustCompile
      

      也就是

      regexp.MustCompile(`^` + expression(res...).String() + `$`)
      
      • ^ 代表匹配首
      • $ 代表匹配尾

      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      express函数对传递的res的正则符合字符串化,并与字符串s拼接。这里好像是闭包函数的使用。与我们的代码中使用的场景联想一下,正是镜像的格式例如:nginx:latest 、kainlite/kube-image-bouncer:latest,其实express作用的就是镜像中特殊字符为了避免被识别为正则表达式。

      回头来看,nchoredIdentifierRegexp.MatchString(s)的作用就是判断s是不是一个镜像。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      splitDockerDomain(s)

      splitDockerDomain(s)在第90行,通过字段其实大概就能明白它的意思。字段切分。具体怎么实现的呢?
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      strings.IndexRune(name, '/')方法,可以参考go strings方法,IndexRune返回字符/在字符串s中第一次出现的位置,如果找不到,则返回-1。domain就等于docker.io,在代码中已初始化好,name等于remainder
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      如果镜像中有‘/’呢,例如:kainlite/kube-image-bouncer:latest,domain取kainlite,remainder取kube-image-bouncer:latest

      假如domain等于index.docker.io,就重定义为docker.io

      假如domain等于docker.io,并且再次确认remainder不包含‘/’,就将remainder再次重新定义 officialRepoName + "/" + remainder

      splitDockerDomain(s)函数分析完毕。继续ParseNormalizedNamed(s string) (Named, error)的分析:

      定义个remoteName

      tagSep := strings.IndexRune(remainder, ‘:’),即确认:的位置,如果>-1,即如果存在,则
      tagSep等于镜像的标签,否则,就等于镜像的名字

      strings.ToLower将s中的所有字符修改为其小写格式,如果remotename存在大写的话则不符合仓库名字规范。

      parse

      Parse(domain + "/" + remainder)是什么意思呢?

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

      又是好大的一个函数。
      那我们慢慢来分析吧

      referenceRegexp.FindStringSubmatch(s)

      referenceRegexp.FindStringSubmatch(s)是啥意思?翻译过来就是ReferenceRegexp是完全支持的引用格式。regexp被锚定,并具有名称、标记和摘要组件的捕获组。描述看不懂。还是具体代码逻辑吧
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      anchored大体明白了,就是通过添加开始和结束分隔符锚定正则表达式并作为返回值。Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析将含有正则表达式字符的字符串转换字符串形式。

      capture函数与anchored大同小异,只是将含有正则表达式字符的字符串转换数组形式并作为返回值。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      optional似乎是对字符串可有可无的一种设定,并且optional字面意思是可选的。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

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

      literal函数是什么意思?翻译是将文本编译为文本正则表达式,转义任何regexp保留字符。字面非常容易理解。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      • QuoteMeta返回一个字符串,该字符串转义参数文本中的所有正则表达式元字符;返回的字符串是与文本匹配的正则表达式。
      • var match = regexp.MustCompile
      • re := regexp.MustCompile(正则字符串)
      • re就是单纯的正则表达式了。
      • Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
        LiteralPrefix返回一个字面值字符串,该字符串必须以正则表达式re的任何匹配项开始。如果字面值字符串包含整个正则表达式,则返回布尔值true。
        Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      后面的函数方法其实大同小异,这里不一一拆解。
      回到函数ReferenceRegexp.FindStringSubmatch(s),FindStringSubmatch(s)是regexp的方法FindStringSubmatch返回一个字符串切片,其中包含正则表达式在s中最左匹配的文本,以及它的子表达式的匹配(如果有的话),如包注释中的’Submatch’描述中定义的那样。返回值为nil表示没有匹配。

      ReferenceRegexp函数其实设定了一个正则表达式,使字符串s能够通过我们希望的分割的方式,形成一个切片。它的关键之处是获取s的正则表达式,融入到设定的规则之中。

      • 假如matches为nil,报错
      • 假如matches[1]长度>255,也会报错
      nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
      

      这段代码其实是对domain的再度切片,如果它较多的递级目录,那我们就要对目录与仓库名称做出区分。

      这里定义了一个关于镜像仓库名与标签的结构体,这是非常重要的一步。

      ref := reference{
      	namedRepository: repo,
      	tag:             matches[2],
      }
      

      matches[3]是什么? matches[2]是镜像的版本标签,在这之后,又是通过@分割当然是一个哈希字符串的内容,是可有可无的。所以有下面的一个判断。

      if matches[3] != "" {
      	var err error
      	ref.digest, err = digest.Parse(matches[3])
      	if err != nil {
      		return nil, err
      	}
      }
      

      digest包正是处理哈希字符串的。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      getBestReferenceType(ref)是什么?字面推断是对ref再次处理。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      对包含镜像的仓库、标签、哈希值的ref结构体再次检查判断,有什么输出什么。并重构还有该特性的结构体。一共有三类结构体。如下:
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      到这里,关于parse的函数分析已经结束了,这一路下来学到了不少方法,不能说全盘了解,但调用的机理已经摸透。

      named, isNamed := ref.(Named)是个非常有趣的值得摸索记住的。我不懂,结构体跟点跟括号。后续研究。,但根据下面的代码逻辑推理,可能:

        r.Name() + ":" + r.tag + "@" + r.digest.String()
      

      Named是管道,ref是结构体reference结构体的定义,那么自然会承接Reference管道中的refence的String()
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

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

      剩下要做的就是看看这个parse函数返回值被如何用了,自然可以推理出来,如下

      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      strings.HasSuffix判断字符串s是否以某个字符串结尾,

      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      TagNameOnly函数很好理解,就是判断镜像有没有标签,如果没有标签就添加默认"latest"。
      那我们来看看他怎么实现的吧。

      IsNameOnly函数在helpers.goKubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      来到这里我们又遇到了ref.(NamedTagged),看到这里,也许有一丝明白过来,这个对ref的结构体属性的判断,根据结构体中的属性是否包含值,通过接口组合成一个判断类型。之前,named, isNamed := ref.(Named)代表返回一个完整的镜像+标签的内容,并判断是否正常返回,这里代表是否只返回标签,也就是只判断是否有标签。下面的ref.(Canonical)则是判断标签是否有哈希值。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      最后,如果没有任何标签,即为true,继续执行namedTagged, err := WithTag(ref, defaultTag)
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      withtag函数传递两个函数,获取的镜像的信息,和latest标签。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      这个对已经获取的Named的对象重新进行定义,目的是为了把默认没有标签的镜像打上latest标签。

      当withtag函数执行结束,TagNameOnly(named)也就返回新的镜像结构体,然后通过String()方法,字符串化,Strings.HasSuffix方法判断这个字符串是否以:latest结尾。根据正确与否返回true或false。

      IsUsingLatestTag函数的逻辑终于也就结束了。

      回到我们的image_policy代码中来。

      下面就是根据判断是否有latest做出终端日志输出判断,并且打个是否allow的标签。

      我们完成了哪些部分的代码分析呢?真的是九牛一毛。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析

      4. echo包

      下面只需要分析明白如下内容。
      Kubernetes ImagePolicyWebhook与ValidatingAdmissionWebhook【2】Image_Policy.go源码解析
      echo web框架是go语言开发的一种高性能,可扩展,轻量级的web框架。
      echo框架真的非常简单,几行代码就可以启动一个高性能的http服务端。
      echo.Context表示当前 HTTP 请求的上下文。它保存请求和响应引用、路径、路径参数、数据、注册处理程序和 API 以读取请求和写入响应。由于 Context 是一个接口,因此很容易使用自定义 API 对其进行扩展。
      handlerFunc定义http请求,匿名函数像变量一样返回给echo.HandlerFunc

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

      c.bind(&imageReview)意思是通过将请求参数绑定到一个名叫imageReview的struct对象的方式获取数据。这种方式获取请求参数支持json、xml、k/v键值对等多种方式。

      该函数最终返回一个json格式的pod拉去一个镜像的属性信息,并伴随http请求状态。

      分析到这里,我们完成了对Image_Policy.go的步步分析,也深刻的体会到读源码的重要性。

      5. 总结

      我对go有了以下感悟:

      1. go的logo是一只土拨鼠,土拨鼠的习性是挖地洞,因此,我们在学习go的时候要有土拨鼠的挖洞精神,在每个包、每个函数、每个方法、每个接口、每个结构体找到它最真实的面孔。
      2. echo web框架的使用,请参考这篇文章
      3. 匿名函数作为返回值的使用

      匿名函数由一个不带函数名的函数声明和函数体组成。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。这是它最大的特点。这里将一个函数当做一个变量一样的操作作为函数的返回值输出给echo.HandlerFunc

      1. 依赖包的结构体具体特性进行变量声明,方便简化代码的逻辑。例如:var imageReview v1alpha1.ImageReview

      谁在调用image_policy.go ,是main.go,在下一篇接文章,我们慢慢分析它的逻辑是什么。

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://ghostwritten.blog.csdn.net/article/details/119811128,作者:ghostwritten,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:Linux命令之测试条件表达式test

      下一篇:大数据测试过程、策略及挑战

      相关文章

      2025-05-16 09:15:10

      Docker多阶段构建:减小镜像大小,提升构建效率

      Docker 多阶段构建是一种在 Dockerfile 中使用多个 FROM 指令来构建镜像的方法。它的主要目的是减小最终生成的镜像大小,并提高镜像的安全性和可维护性。多阶段构建通常用于编译和打包应用程序的过程中。

      2025-05-16 09:15:10
      Dockerfile , 应用程序 , 构建 , 编译 , 镜像
      2025-05-14 09:51:21

      Docker大学生看了都会系列(三、常用帮助、镜像、容器命令)

      Docker大学生看了都会系列(三、常用帮助、镜像、容器命令)

      2025-05-14 09:51:21
      container , docker , 命令 , 容器 , 查看 , 镜像
      2025-04-18 07:11:19

      打镜像部署到k8s中,prometheus配置采集并在grafana看图

      打镜像部署到k8s中,prometheus配置采集并在grafana看图

      2025-04-18 07:11:19
      grafana , node , pod , prometheus , 镜像
      2025-03-12 09:32:22

      使用docker安装gitlab

      使用docker安装gitlab

      2025-03-12 09:32:22
      代码 , 版本 , 镜像
      2025-03-12 09:32:22

      docker安装rabbitmq详解

      docker安装rabbitmq详解

      2025-03-12 09:32:22
      rabbitmq , 客户端 , 镜像
      2025-03-10 09:52:02

      Spring Boot 3.0与Jakarta EE 10的深度解析

      随着Java生态的不断演进,Spring Boot和Jakarta EE始终是现代Java开发中的两大核心框架。在2023年,Spring Boot 3.0与Jakarta EE 10的发布标志着Java技术又迈上了一个新的台阶。

      2025-03-10 09:52:02
      Boot , Java , Spring , 原生 , 支持 , 镜像
      2025-03-10 09:50:17

      docker中安装官方rocketmq

      docker中安装官方rocketmq

      2025-03-10 09:50:17
      Docker , rocketmq , RocketMQ , 安装 , 镜像
      2025-03-10 09:50:17

      docker安装nacos单机部署

      docker安装nacos单机部署

      2025-03-10 09:50:17
      nacos , 安装 , 版本 , 镜像
      2025-02-26 07:22:11

      【网络】新华三H3C交换机 抓包|H3C交换机文档

      【网络】新华三H3C交换机 抓包|H3C交换机文档

      2025-02-26 07:22:11
      ACL , interface , 镜像
      2025-02-18 07:28:44

      【质量】镜像漏洞扫描工具Trivy原理和操作

      【质量】镜像漏洞扫描工具Trivy原理和操作

      2025-02-18 07:28:44
      扫描 , 漏洞 , 镜像
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5244141

      查看更多

      最新文章

      Docker多阶段构建:减小镜像大小,提升构建效率

      2025-05-16 09:15:10

      使用docker安装gitlab

      2025-03-12 09:32:22

      Spring Boot 3.0与Jakarta EE 10的深度解析

      2025-03-10 09:52:02

      算法题:剑指 Offer 27. 二叉树的镜像(题目+思路+代码+注释)时空 O(N) O(1) 0ms击败100%、64%用户

      2025-01-15 08:08:29

      算法题:剑指 Offer 28. 对称的二叉树(题目+思路+代码+注释)时空 O(N) O(N) 0ms击败100%、15%用户

      2025-01-15 08:08:29

      使用Java和Docker构建高可用的容器化应用

      2024-12-20 07:55:03

      查看更多

      热门文章

      在Rainbond上使用Locust进行压力测试

      2023-05-23 01:22:48

      linux内核源码解析03–启动代码分析之主内核页表创建

      2023-06-21 06:39:35

      Kubernetes中Java应用Heap Dump

      2023-05-12 07:08:44

      云原生|kubernetes|k8s集群测试时的一些基本操作

      2023-05-16 09:43:15

      Kubernetes Java 服务最小化镜像方案

      2023-05-12 07:09:20

      k8s自定义controller三部曲之二:自动生成代码

      2024-04-17 02:21:24

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      算法题:剑指 Offer 28. 对称的二叉树(题目+思路+代码+注释)时空 O(N) O(N) 0ms击败100%、15%用户

      Kubernetes中Java应用Heap Dump

      Kubernetes Java 服务最小化镜像方案

      使用docker安装gitlab

      Spring Boot 3.0与Jakarta EE 10的深度解析

      在Rainbond上使用Locust进行压力测试

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号