kubectl使用及源码阅读
目录
- 概述
- 实践
- 样例
- yaml 中的必须字段
- kubectl 代码原理
- kubectl 命令行设置pprof 抓取火焰图
- kubectl 中的 cobra
- 七大分组命令
- kubectl create
- createCmd中的builder模式
- createCmd中的visitor访问者模式
- 外层VisitorFunc分析
- 结束
概述
k8s 版本 v1.24.16
kubectl的职责
- 1.主要的工作是处理用户提交的东西(包括,命令行参数,yaml文件等)
- 2.将用户提交的这些东西组织成一个数据结构体
- 3.再将其发送给 api server
实践
| 文章名 | 链接 |
|---|---|
| linux k8s 源码编译及单集群测试 | 地址 |
| k8s源码debug | 地址 |
样例
cat test/fixtures/doc-yaml/user-guide/pod.yaml
apiVersion: v1
kind: Pod
metadata:name: nginxlabels:app: nginx
spec:containers:- name: nginximage: nginxports:- containerPort: 80
| 字段名 | 含义 |
|---|---|
| kind | Pod |
| metadata.name | |
| spec.containers.name | |
| spec.containers.image | image名称:版本 |
对象规约(Spec) 与状态 (Status)
- 几乎每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec (规约) 和对象 status (状态)
- 对于具有 spec 的对象,必须在创建对象时设置具体内容,描述你希望对象所具有的特征:期望状态 (Desired State)
yaml 中的必须字段
- 在想要创建的 Kubernetes 对象对应的 yaml 文件中,需要配置如下的字段:
- apiVersion - 创建该对象所使用的 Kubernetes API 的版本
- kind - 想要创建的对象的类别
- metadata - 帮助唯一标识对象的一些数据,包括一个 name 字符串、UID和可选的 namespace
[root@test kubernetes]# ./cluster/kubectl.sh get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 89s
| 字段名 | 含义 |
|---|---|
| NAME | nginx就是对应yaml中metadata.name |
| READY | 就绪个数 |
| STATUS | 当前的状态,RUNNING表示运行中 |
| RESTARTS | 重启的次数,代表没有重启过 |
| AGE | 运行的时长 |
kubectl 代码原理
- 1.从命令行和 yaml 文件中获取信息
- 2.通过 Builder 模式并将其转成一系列的资源
- 3.最后用 Visitor 模式来迭代处理这些 Resources
源码位置
kubectl 命令行设置pprof 抓取火焰图
kubectl 中的 cobra
- 底层函数 NewKubectlCommand 解析
- 在 PersistentPreRunE 设置 prrof 采集相关指令
- 在 PersistentPostRunE 设置了 pprof 统计结果落盘
- 执行采集 pprof cpu 的 kubelet 命令
kubectl.go --> command := cmd.NewDefaultKubectlCommand()cmd.go --> return NewDefaultKubectlCommandWithArgs(KubectlOptions{ -->cmd := NewKubectlCommand(o)
# cpu.pprof 文件在当前命令执行目录下
kubectl get node --profile=cpu --profile-output=cpu.pprof
# ll
# 使用 go 工具将 pprof 转换成 svg 火焰图
go tool pprof -svg cpu.pprof > kubectl_get_node_cpu.svg
# 下载下来,在浏览器打开
七大分组命令
kubectl.go --> command := cmd.NewDefaultKubectlCommand()cmd.go --> var defaultConfigFlags = genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag().WithDiscoveryBurst(300).WithDiscoveryQPS(50.0) --> f := cmdutil.NewFactory(matchVersionKubeConfigFlags) --> proxyCmd := proxy.NewCmdProxy(f, o.IOStreams)proxyCmd.PreRun = func(cmd *cobra.Command, args []string) {kubeConfigFlags.WrapConfigFn = nil}
groups := templates.CommandGroups{{Message: "Basic Commands (Beginner):",Commands: []*cobra.Command{create.NewCmdCreate(f, o.IOStreams),expose.NewCmdExposeService(f, o.IOStreams),run.NewCmdRun(f, o.IOStreams),set.NewCmdSet(f, o.IOStreams),},},{Message: "Basic Commands (Intermediate):",Commands: []*cobra.Command{explain.NewCmdExplain("kubectl", f, o.IOStreams),getCmd,edit.NewCmdEdit(f, o.IOStreams),delete.NewCmdDelete(f, o.IOStreams),},},{Message: "Deploy Commands:",Commands: []*cobra.Command{rollout.NewCmdRollout(f, o.IOStreams),scale.NewCmdScale(f, o.IOStreams),autoscale.NewCmdAutoscale(f, o.IOStreams),},},{Message: "Cluster Management Commands:",Commands: []*cobra.Command{certificates.NewCmdCertificate(f, o.IOStreams),clusterinfo.NewCmdClusterInfo(f, o.IOStreams),top.NewCmdTop(f, o.IOStreams),drain.NewCmdCordon(f, o.IOStreams),drain.NewCmdUncordon(f, o.IOStreams),drain.NewCmdDrain(f, o.IOStreams),taint.NewCmdTaint(f, o.IOStreams),},},{Message: "Troubleshooting and Debugging Commands:",Commands: []*cobra.Command{describe.NewCmdDescribe("kubectl", f, o.IOStreams),logs.NewCmdLogs(f, o.IOStreams),attach.NewCmdAttach(f, o.IOStreams),cmdexec.NewCmdExec(f, o.IOStreams),portforward.NewCmdPortForward(f, o.IOStreams),proxyCmd,cp.NewCmdCp(f, o.IOStreams),auth.NewCmdAuth(f, o.IOStreams),debug.NewCmdDebug(f, o.IOStreams),},},{Message: "Advanced Commands:",Commands: []*cobra.Command{diff.NewCmdDiff(f, o.IOStreams),apply.NewCmdApply("kubectl", f, o.IOStreams),patch.NewCmdPatch(f, o.IOStreams),replace.NewCmdReplace(f, o.IOStreams),wait.NewCmdWait(f, o.IOStreams),kustomize.NewCmdKustomize(o.IOStreams),},},{Message: "Settings Commands:",Commands: []*cobra.Command{label.NewCmdLabel(f, o.IOStreams),annotate.NewCmdAnnotate("kubectl", f, o.IOStreams),completion.NewCmdCompletion(o.IOStreams.Out, ""),},},
}
kubectl create
// 进入口
create.NewCmdCreate(f, o.IOStreams)// 核心的cmd.Run函数
// 校验文件参数
if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) {ioStreams.ErrOut.Write([]byte("Error: must specify one of -f and -k\n\n"))defaultRunFunc := cmdutil.DefaultSubCommandRun(ioStreams.ErrOut)defaultRunFunc(cmd, args)return
}// 完善并填充所需字段
cmdutil.CheckErr(o.Complete(f, cmd))
// 校验参数
cmdutil.CheckErr(o.ValidateArgs(cmd, args))
// 核心的RunCreate
// 发送请求与 api server 通信
cmdutil.CheckErr(o.RunCreate(f, cmd))
createCmd中的builder模式
createCmd中的builder建造者设计模式
// 快速定位代码
cmdutil.CheckErr(o.RunCreate(f, cmd)) -->
r := f.NewBuilder().Unstructured().Schema(schema).ContinueOnError().NamespaceParam(cmdNamespace).DefaultNamespace().FilenameParam(enforceNamespace, &o.FilenameOptions).LabelSelectorParam(o.Selector).Flatten().Do()

createCmd中的visitor访问者模式
- 访问都模式(Visitor Pattern) 是一种将数据结构与数据操作分离的设计模式
- 指封装一些作用于某种数据结构中的各元素的操作
- 可以在不改变数据结构的前提下定义作用于这些元素的新的操作
- 属于行为型设计模式
使用场景:
- 数据结构稳定,作用于数据结构的操作经常变化的场景
- 需要数据结构与数据操作分享的场景
- 需要对不同数据类型(元素)进行操作,而不使用分支判断具体类型的场景
// 快速定位代码
cmdutil.CheckErr(o.RunCreate(f, cmd)) --> err = r.Visit(func(info *resource.Info, err error) error {// 注意 Visit 是由 Builder 中 FilenameParam 构建的
r := f.NewBuilder()....// 构建 VisitFilenameParam(enforceNamespace, &o.FilenameOptions)....// 创建 VisitDo()
// 定位
FilenameParam --> b.Path(recursive, matches...) --> visitors, err := ExpandPathsToFileVisitors(b.mapper, p, recursive, FileExtensions, b.schema) -->visitor := &FileVisitor{Path: path,StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),}
FilenameParam --> b.Path(recursive, matches…) 位置
// NewStreamVisitor is a helper function that is useful when we want to change the fields of the struct but keep calls the same.
func NewStreamVisitor(r io.Reader, mapper *mapper, source string, schema ContentValidator) *StreamVisitor {return &StreamVisitor{Reader: r,mapper: mapper,Source: source,Schema: schema,}
}// 解析 yaml 或者 json 配置
// Visit implements Visitor over a stream. StreamVisitor is able to distinct multiple resources in one stream.
func (v *StreamVisitor) Visit(fn VisitorFunc) error {d := yaml.NewYAMLOrJSONDecoder(v.Reader, 4096)for {ext := runtime.RawExtension{}if err := d.Decode(&ext); err != nil {if err == io.EOF {return nil}return fmt.Errorf("error parsing %s: %v", v.Source, err)}// TODO: This needs to be able to handle object in other encodings and schemas.ext.Raw = bytes.TrimSpace(ext.Raw)if len(ext.Raw) == 0 || bytes.Equal(ext.Raw, []byte("null")) {continue}if err := ValidateSchema(ext.Raw, v.Schema); err != nil {return fmt.Errorf("error validating %q: %v", v.Source, err)}info, err := v.infoForData(ext.Raw, v.Source)if err != nil {if fnErr := fn(info, err); fnErr != nil {return fnErr}continue}if err := fn(info, nil); err != nil {return err}}
}
// 上面方法中,重点如下代码
info, err := v.infoForData(ext.Raw, v.Source)// obj 代表 k8s的对象
// gvk 代表 Group/Version/Kind 的缩写
obj, gvk, err := m.decoder.Decode(data, nil, nil)
外层VisitorFunc分析
- 如查出错即返回错误
- DryRunStrategy 代表试运行策略
- 默认为 None 代表不试运行
- client 代表客户端试运行,不发送请求至 server
- server 点服务端试运行,发送请求,但是如果会改变状态的话就不做
err = r.Visit(func(info *resource.Info, err error) error { --> if o.DryRunStrategy != cmdutil.DryRunClient { --> Create(info.Namespace, true, info.Object)(最终创建资源)
结束
kubectl使用及进阶 至此结束。
相关文章:
kubectl使用及源码阅读
目录 概述实践样例yaml 中的必须字段 kubectl 代码原理kubectl 命令行设置pprof 抓取火焰图kubectl 中的 cobra 七大分组命令kubectl createcreateCmd中的builder模式createCmd中的visitor访问者模式外层VisitorFunc分析 结束 概述 k8s 版本 v1.24.16 kubectl的职责 1.主要的…...
C++面试宝典第32题:零钱兑换
题目 给定不同面额的硬币coins和一个总金额amount,编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,则返回-1。说明:你可以认为每种硬币的数量是无限的。 示例1: 输入:coins = [1, 2, 5], amount = 11 输出:3 解释:11 = …...
pyspark分布式部署随机森林算法
前言 分布式算法的文章我早就想写了,但是一直比较忙,没有写,最近一个项目又用到了,就记录一下运用Spark部署机器学习分类算法-随机森林的记录过程,写了一个demo。 基于pyspark的随机森林算法预测客户 本次实验采用的…...
【Python笔记-设计模式】中介者模式
一、说明 中介者模式是一种行为设计模式,减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。 (一) 解决问题 降低系统中对象之间的直接通信,将复杂的交互转化为通过中介者进行的间接交…...
大语言模型构建的主要四个阶段(各阶段使用的算法、数据、难点以及实践经验)
大语言模型构建通常包含以下四个主要阶段:预训练、有监督微调、奖励建模和强化学习,简要介绍各阶段使用的算法、数据、难点以及实践经验。 预训练 需要利用包含数千亿甚至数万亿 单词的训练数据,并借助由数千块高性能 GPU 和高速网络组成的…...
[云原生] 二进制安装K8S(中)部署网络插件和DNS
书接上文,我们继续部署剩余的插件 一、K8s的CNI网络插件模式 2.1 k8s的三种网络模式 K8S 中 Pod 网络通信: (1)Pod 内容器与容器之间的通信 在同一个 Pod 内的容器(Pod 内的容器是不会跨宿主机的)共享…...
云端技术驾驭DAY13——Pod污点、容忍策略、Pod优先级与抢占、容器安全
往期回顾: 云端技术驾驭DAY01——云计算底层技术奥秘、云服务器磁盘技术、虚拟化管理、公有云概述 云端技术驾驭DAY02——华为云管理、云主机管理、跳板机配置、制作私有镜像模板 云端技术驾驭DAY03——云主机网站部署、web集群部署、Elasticsearch安装 云端技术驾驭…...
掌握Docker:让你的应用轻松部署和管理
文章目录 一、引言(为什么要学习docker?)1.1 环境不一致1.2 隔离性1.3 弹性伸缩1.4 学习成本 二、Docker介绍2.1 Docker的由来2.2 什么是Docker2.3 为什么要用Docker2.3.1 虚拟机2.3.2 Linux容器 2.4 Docker与传统虚拟机的区别2.5 Docker的思…...
5G-A,未来已来
目前,全国首个5G-A规模组网示范完成。这项由北京联通携手华为共同打造的示范项目,实现了北京市中心金融街、历史建筑长话大楼、大型综合性体育场北京工人体育场三个重点场景的连片覆盖。 实际路测结果显示,5G-A用户下行峰值速率达到10Gbps&am…...
智慧公厕让社区生活更美好
随着科技的迅猛发展,城市管理、城市服务均使用科技化的手段进行升级改造,社区生活更美好赋予全新的智慧效能,其中智慧公厕也成为了城市环卫设施的新宠。智慧公厕以物联网、互联网、大数据、云计算、5G通信、自动化控制等技术为核心࿰…...
Apache软件基金会的孵化标准和毕业标准
Apache软件基金会的孵化标准和毕业标准是一个项目成功的重要衡量指标。这些标准关注项目的多个方面,包括开放性、合作性、共建性、透明性、技术可行性、社区建设以及用户基础等。在孵化阶段,Apache软件基金会主要关注项目的开放性和合作性。首先…...
什么是高可用架构
一、什么是高可用 在运维中,经常听到高可用,那么什么是高可用架构呢?通俗点讲,高可用就是在服务故障,节点宕机的情况下,业务能够保证不中断,服务正常运行。 举个例子,支付宝&#…...
【Vuforia+Unity】AR04-地面、桌面平面识别功能(Ground Plane Target)
不论你是否曾有过相关经验,只要跟随本文的步骤,你就可以成功地创建你自己的AR应用。 官方教程Ground Plane in Unity | Vuforia Library 这个功能很棒,但是要求也很不友好,只能支持部分移动设备,具体清单如下: 01.Vuforia的地面识别功能仅支持的设备清单: Recommended…...
【Git】解决‘每次初始化一个新仓库时,都需要执行git config --global --add safe.directory命令‘
问题 这个命令是用来将一个安全目录添加到全局的 Git 配置中。但每次克隆一个仓库或者新建一个仓库,并且对该仓库进行操作时,都需要执行该命令,十分麻烦! 这是因为,Git 近期进行了版本升级,添加了新的目录…...
Qt的QThread、QRunnable和QThreadPool的使用
1.相关描述 随机生产1000个数字,然后进行冒泡排序与快速排序。随机生成类继承QThread类、冒泡排序使用moveToThread方法添加到一个线程中、快速排序类继承QRunnable类,添加到线程池中进行排序。 2.相关界面 3.相关代码 widget.cpp #include "widget…...
windows安装部署node.js并搭建Vue项目
一、官网下载安装包 官网地址:https://nodejs.org/zh-cn/download/ 二、安装程序 1、安装过程 如果有C/C编程的需求,勾选一下下图所示的部分,没有的话除了选择一下node.js安装路径,直接一路next 2、测试安装是否成功 【winR】…...
【计算机】本科考研还是就业?
其实现在很多计算机专业的学生考研,也是无奈的选择 技术发展日新月异,而在本科阶段,大家学着落后的技术,出来找工作自然会碰壁。而且现在用人单位的门槛越来越高,学历默认研究生起步,面试一般都是三轮起步…...
ChatGPT调教指南 | 咒语指南 | Prompts提示词教程(三)
在人工智能成为我们日常互动中无处不在的一部分的时代,与大型语言模型(llm)有效沟通的能力是无价的。“良好提示的26条原则”为优化与这些复杂系统的交互提供了全面的指导。本指南证明了人类和人工智能之间的微妙关系,强调清晰、专一和结构化的沟通方法。…...
小程序一键链接WIFI
1.小程序一键链接WIFI connectWifi: function() {var that this;//检测手机型号wx.getSystemInfo({success: function(res) {var system ;if (res.platform android) system parseInt(res.system.substr(8));if (res.platform ios) system parseInt(res.system.substr(4…...
结构体位域保存传感器数据
1、原理图分析: 8个74HC4052共用两个选通引脚,8个输入引脚,一共可以检测64个数字红外传感器。74HC4052的功能表如下,nY0表示所有Y0引脚。 S1 S0 Channel on 0 0 nY0 0 1 nY1 1 0 nY2 1 1 nY3 enum sensor_id{HS01 0, HS02, HS03, HS0…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

