当前位置: 首页 > news >正文

Kubernetes对象深入学习之五:TypeMeta无效之谜

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本文是《Kubernetes对象深入学习之五》系列的第五篇,从前文的分析也能看出,代表对象类型的schema.ObjectKind,于对象而言是至关重要的,那是它的类型和身份,既然如此,与之有关的问题也不能放过,因此本篇就来看一个对象类型相关的问题,本文由以下内容组成:
  1. 复现问题:我的代码中获取的对象类型为空
  2. 问题原因
  3. 为什么会有这个问题?
  4. 这个问题有解吗?

复现问题

  • 问题很容易复现,回顾《Kubernetes对象深入学习之四:对象属性编码实战》的代码,controller.go有下面这么一段代码,作用是在controller监听到对象变化时,将对象的ObjectMeta内容在控制台打印出来,现在咱们在黄色箭头前面添加两端代码
    在这里插入图片描述
  • 新增的代码是下面这些,先用现成的方法做一次提取,得到Kind和APIVersion,再尝试直接转换成objectruntime.Object类型获取GVK
// 第一次尝试:通过公共方法转为Type接口
objType, err := meta.TypeAccessor(obj)
if err != nil {klog.Errorf("TypeAccessor [%s], failed with %v", key, err)return err
}fmt.Printf("** 通过公共方法获取Kind, kind [%s], version [%s]\n", objType.GetKind(), objType.GetAPIVersion())// 第二次尝试:亲自尝试强转
runtimeObj, _ := obj.(objectruntime.Object)
fmt.Printf("** 强转获取Kind: %v\n", runtimeObj.GetObjectKind().GroupVersionKind())
  • 修改后整体效果如下,黄框中是本次新增内容
    在这里插入图片描述
  • 程序启动后,打印日志如下,可见不论是哪种方式,kind和version的值都是空
I0827 01:15:58.890491 2945049 controller.go:144] Starting Pod controller
** 通过公共方法获取Kind, kind [], version []
** 强转获取Kind: /, Kind=
** 通过公共方法获取Kind, kind [], version []
** 强转获取Kind: /, Kind=
** 通过公共方法获取Kind, kind [], version []
** 强转获取Kind: /, Kind=
  • 好了,现在问题已复现:TypeMeta内容为空,接下来去寻找问题原因

问题原因

  • 咱们按照顺序捋一下代码,在main.go中调用了CreateAndStartController来创建controller,此时指定了类型是&v1.Pod{}
    在这里插入图片描述

  • 在CreateAndStartController方法内会调用NewListWatchFromClient来创建ListWatcher,指定了resource就是刚才传入的pods
    在这里插入图片描述

  • 继续展开,就看到了关键代码NewFilteredListWatchFromClient方法,这里指出了list操作的具体实现,该方法其余代码略去不看了:

func NewFilteredListWatchFromClient(c Getter, resource string, namespace string, optionsModifier func(options *metav1.ListOptions)) *ListWatch {listFunc := func(options metav1.ListOptions) (runtime.Object, error) {optionsModifier(&options)return c.Get().Namespace(namespace).Resource(resource).VersionedParams(&options, metav1.ParameterCodec).Do(context.TODO()).Get()}// 剩余的代码省略不看...
}
  • 注意,重点来了,先展开上面的Do方法,这里面发起了远程请求,获取资源列表,并且指定transformResponse方法用来处理收到的响应
func (r *Request) Do(ctx context.Context) Result {var result Resulterr := r.request(ctx, func(req *http.Request, resp *http.Response) {result = r.transformResponse(resp, req)})if err != nil {return Result{err: err}}return result
}
  • 这个transformResponse方法的代码太多,我们只关注重点,就是这个decoder对象,记住这个decoder
    在这里插入图片描述
  • 看完了Do方法,再来看Get方法,关键代码是黄色箭头指出的部分:使用decoder对响应的body进行处理
    在这里插入图片描述
  • 再来看这个Decode方法的内容(apimachinery@v0.22.8/pkg/runtime/helper.go),很明显,这里故意调用了SetGroupVersionKind方法,入参是个新的GroupVersionKind对象,如此一来,所有类型有关的信息就被清除了
// Decode does not do conversion. It removes the gvk during deserialization.
func (d WithoutVersionDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) {obj, gvk, err := d.Decoder.Decode(data, defaults, into)if obj != nil {kind := obj.GetObjectKind()// clearing the gvk is just a convention of a codeckind.SetGroupVersionKind(schema.GroupVersionKind{})}return obj, gvk, err
}
  • 至此,真相大白,kubernetes官方在处理api-server的响应内容时,刻意将TypeMeta清理掉了

为什么会有这个问题?

  • 对于这么做的原因,首先是个人猜测,回到main.go,如下图,作为使用方,既然已经明确了要监听的资源是pod,那么得到的结果自然就只能是v1.Pod了,所以无需再从结果中获取类型,
    在这里插入图片描述
  • 至于根本原因,由于欣宸英语水平太差,未能从一群老外的讨论中得到明确答案,下面是和这个问题相关的pr和issue,可见抱有相同疑惑的人着实不少,并且这个问题已经持续多年,并且一直没有解决
  • https://github.com/kubernetes/kubernetes/pull/59264#issuecomment-362579495
  • https://github.com/kubernetes/client-go/issues/541
  • https://github.com/kubernetes/client-go/issues/861
  • https://github.com/kubernetes/kubernetes/issues/80609

这个问题可以解决吗?

  • 老外有个建议,就是用DoRaw方法得到api-server响应的原始body,然后自己做反序列化,我这里试了下
    在这里插入图片描述
  • 日志打印出原始body内容如下,太长了只截取部分
raw : {"kind":"PodList","apiVersion":"v1","metadata":{"resourceVersion":"12435998"},"items":[{"metadata":{"name":"nginx-deployment-78f6b696d9-cr47w","generateName":"nginx-deployment-78f6b696d9-","namespace":"client-go-tutorials","uid":"645628af-0d20-4548-b15d-0faf9e03b733","resourceVersion":"12227486","creationTimestamp":"2023-08-13T11:15:59Z","labels":{"app":"nginx-app","business-service-type":"web","language":"c","pod-template-hash":"78f6b696d9","service-update-time":"20230813120623","type":"front-end"},"annotations":{"cni.projectcalico.org/containerID":"e94b7b0ebe60d1cada361f7a672b2c6df71f2d89c4b5c1ae4056f82dec6a78db","cni.projectcalico.org/podIP":"100.91.64.45/32","cni.projectcalico.org/podIPs":"100.91.64.45/32"},"ownerReferences":[{"apiVersion":"apps/v1","kind":"ReplicaSet","name":"nginx-deployment-78f6b696d9","uid":"642c39e7-814a-491f-9b4f-295f34e959a3","controller":true,"blockOwnerDeletion":true}],"managedFields":[{"manager":"kube-controller-manager","operation":"Update","apiVersion":"v1","time":"2023-08-13T11:15:59Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:generateName":{},"f:labels":{".":{},"f:app":{},"f:business-service-type":{},"f:language":{},"f:pod-template-hash":{},"f:type":{}},"f:ownerReferences":{".":{},"k:{\"uid\":\"642c39e7-814a-491f-9b4f-295f34e959a3\"}":{}}},"f:spec":{"f:containers":{"k:{\"name\":\"nginx-container\"}":{".":{},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:resources":{".":{},"f:limits":{".":{},"f:cpu":{},"f:memory":{}},"f:requests":{".":{},"f:cpu":{},"f:memory":{}}},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{}}},"f:dnsPolicy":{},"f:enableServiceLinks":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{},"f:terminationGracePeriodSeconds":{}}}},
...
..
.
  • 拿到这样的json内容后,去工具网站转为go的数据结构代码,这样就能在代码中完成反序列化,例如:https://zxjson.com/json2go/, 如下图,转为go的数据接口
    在这里插入图片描述
  • 如此一来,跌跌撞撞的拿到了完整的json对象,当然了,这并不是个好的办法
  • 至此ypeMeta无效之谜已经解开,如果您有更好的解法或者更多官方消息,欢迎留言,感谢您的帮助

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

相关文章:

Kubernetes对象深入学习之五:TypeMeta无效之谜

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《Kubernetes对象深入学习之五》系列的第五篇,从前文的分析也能看出,代表对象类型的schema.ObjectKind,于…...

Gitlab设置中文

1. 打开设置 2.选择首选项Preferences 3. 下滑选择本地化选项Localization,设置简体中文,然后保存更改save changes。刷新网页即可。...

【微服务部署】05-安全:强制HTTPS

文章目录 安全 : 强制HTTPS的两种方式1. Ingress配置重定向2. 应用程序配置3. Ingress配置4. 应用程序配置代码总结 安全 : 强制HTTPS的两种方式 互联网发展中,安全是非常重要的,由其是现在HTTPS非常普及的情况下,应用程序在公网上一般都会被…...

Config:服务端连接Git配置

创建子模块 Pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org…...

c++学习 之 类和对象 public , protected ,private

前言 在C中&#xff0c;访问控制修饰符&#xff08;Access Control Modifiers&#xff09;用于控制类的成员&#xff08;成员变量和成员函数&#xff09;的访问权限。这些修饰符分为三种&#xff1a;public、protected和private。它们定义了成员可以在何处访问&#xff0c;具体…...

ECharts图表动态修改series显示隐藏

文章目录 1、前言2、思路3、实现 1、前言 最近做的大数据平台&#xff0c;里面很多部分用到了ECharts&#xff0c;其中有个功能&#xff0c;要求将图表分组&#xff0c;根据用户选择的组&#xff0c;来确定ECharts要显示那些线条和柱子&#xff0c;也就是动态的显示option.seri…...

云服务器(Centos7系统)配置JAVA+mysql+tomcat 环境

文章主要内容来源云服务器&#xff08;Centos7系统&#xff09;部署javaweb项目&#xff08;二&#xff09;配置JAVAmysqltomcat 环境_man_zuo的博客-CSDN博客 模仿途中遇到的问题 连接无效 有时连接无法下载&#xff0c;可能是过期了&#xff0c;将其更换为官网给的下载连接即…...

【计算机视觉 | 目标检测】目标检测常用数据集及其介绍(四)

文章目录 一、JTA (Joint Track Auto)二、AVD (Active Vision Dataset)三、ExDark (Exclusively Dark Image Dataset)四、InteriorNet五、ScanRefer Dataset六、FlickrLogos-32七、SIXray八、Clear Weather (DENSE)九、DVQA (Data Visualizations via Question Answering)十、M…...

Dockerfile制作镜像与搭建LAMP环境

一.编写Dockerfile制作Web应用系统nginx镜像&#xff0c;生成镜像nginx:v1.1&#xff0c;并推送其到私有仓库。具体要求如下&#xff1a; &#xff08;1&#xff09;基于centos基础镜像&#xff1b; &#xff08;2&#xff09;指定作者信息&#xff1b; &#xff08;3&#xff…...

Linux系统中查看端口的方法

一、使用netstat命令 netstat命令是一种非常实用的命令&#xff0c;可以用来显示网络连接、路由表、网络接口和网络统计信息等。它还可以用来显示系统中正在监听的端口。要查看端口&#xff0c;只需在终端中输入以下命令&#xff1a; netstat -tuln 这个命令的意思是列出所有…...

java mysql传入string数组返回string数组的简单写法

一、前言 最近有个需求&#xff0c;需要一个传入string数组返回string数组的sql逻辑。 懒得封装成javabean了&#xff0c;于是就写了一个简单的样例&#xff0c;总结下。 二、代码 1.mapper.java&#xff0c;可以这样写&#xff1a; public interface MyMapper {String[] …...

【PHP】PHP基本语法

1、PHP标记 当解析一个文件时&#xff0c;PHP 会寻找起始和结束标记&#xff0c;也就是 <?php 和 ?>&#xff0c;告诉 PHP 开始和停止解析二者之间的代码。此种解析方式使得 PHP 可以被嵌入到各种不同的文档中去&#xff0c;而任何起始和结束标记之外的部分都会被 PHP…...

SystemVerilog interface详细介绍

1. Interface概念 System Verilog中引入了接口定义&#xff0c;接口与module 等价的定义&#xff0c;是要在其他的接口、module中直接定义&#xff0c;不能写在块语句中&#xff0c;跟class是不同的。接口是将一组线捆绑起来&#xff0c;可以将接口传递给module。 2. 接口的优…...

计网第四章(网络层)(三)

IPV4地址的应用规划&#xff1a; 定长的子网掩码FLSM&#xff1a; 使用同一个子网掩码划分子网&#xff0c;每个子网所分配的IP地址数量相同&#xff0c;造成IP地址的浪费。 变长的子网掩码VLSM&#xff1a; 使用不同的子网掩码划分子网&#xff0c;每个子网所分配的IP地址…...

python学习1之安装

前言 目前&#xff0c;Python有两个版本&#xff0c;一个是2.x版&#xff0c;一个是3.x版&#xff0c;这两个版本是不兼容的。由于3.x版越来越普及&#xff0c;我们的教程将以最新的Python 3.9版本为基础。 1、下载 官网地址 https://www.python.org/downloads/ 2、安装 点击…...

Autofac在WebApi,Winform中应用

安装注意事项 使用AOP的时候需要安装Autofac.Extras.DynamicProxy,如果发现VS老是提示报错,需要把VS重启下才可以识别。 WebApi 注意事项:WebApi中多一个ApiController中构造注入功能。 注入和AOP拦截 var siteNameList ClassHelper.GetConstants(typeof(SiteName));//创建…...

uview ui 查看版号

版本查询2种方式 有两种方式可以查询到正在使用的uView的版本&#xff1a; // 通过console.log打印的形式 console.log(uni.$u.config.v);// 可以查阅uView的配置文件得知当前版本号&#xff0c;具体位置为&#xff1a; /uview-ui/libs/config/config.js...

Python 爬虫网页图片下载到本地

您可以使用Python的requests库来获取网页的源码&#xff0c;使用BeautifulSoup库来解析HTML&#xff0c;并使用urllib库来下载图片到本地。下面是一个示例代码&#xff1a; import requests from bs4 import BeautifulSoup import urllib # 获取网页源码 url https://examp…...

PyQt open3d 加载 显示点云

PyQt加载 显示点云&#xff0c;已经有三种方式&#xff0c;使用 open3d; 使用 vtk; 使用 pcl; 下面是使用 open3d: import sys import open3d as o3d import numpy as np import pyqtgraph.opengl as gl from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QFi…...

Linux搭建SSLVpn

安装http、ssl服务 编辑http配置文件 修改http的136行&#xff0c;276行以及990行 1、136行将监听端口注释 2、276行和990行修改为自己的域名和要访问的端口 修改http文档最后那部分 新添ssl配置信息&#xff0c;将端口修改为443&#xff08;截图错了server.key应该放在/etc/…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...