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
字段名含义
kindPod
metadata.name
spec.containers.name
spec.containers.imageimage名称:版本

对象规约(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
字段名含义
NAMEnginx就是对应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使用及进阶 至此结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/494022.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flutter/Android】新建项目,打开android 目录,报错红色以及开启 MultiDex 配置

1 报错红色问题。 单独打开 Flutter 项目下的 android 项目即可。 也就是说,你要一部分原生代码开发,你就需要自己把 android 项目单独出去做(其实就相当于android 项目引用 Flutter的dart部分)。也就是说,在 Flutter…

时间序列分析实战(六):ARIMA乘法(疏系数)模型建模及预测

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…

紫外-可见吸收光谱法(UV-Vis)是最常用吸收光谱技术 市场持续扩大

紫外-可见吸收光谱法(UV-Vis)是最常用吸收光谱技术 市场持续扩大 紫外-可见吸收光谱法,也称为紫外-可见分光光度法,简称UV-Vis,利用样品分子在紫外和可见光激发下产生电子能级跃迁形成的吸收光谱,对元素进行…

【lv14 day10内核模块参数传递和依赖】

一、模块传参 module_param(name,type,perm);//将指定的全局变量设置成模块参数 /* name:全局变量名 type: 使用符号 实际类型 传参方式 bool bool insmod xxx.ko 变量名0 或 1 invbool bool insmod xxx.ko 变量名0 或 1 charp char * insmod xxx.ko 变量名“字符串…

Sora - 真正单兵作战时代来临了

一、 OpenAI Sora 视频生成模型技术报告总结 不管是在视频的保真度、长度、稳定性、一致性、分辨率、文字理解等方面,Sora都做到了SOTA(当前最优)。 技术细节写得比较泛(防止别人模仿)大概就是用视觉块编码&#xff08…

Java数据结构----时间和空间复杂度

目录 1.算法效率 2.时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3 推导大O阶方法 3.4 常见时间复杂度计算举例 3.空间复杂度 1.算法效率 算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度&#xf…

Linux-基础命令(黑马学习笔记)

Linux的目录结构 Linux的目录结构 Linux的目录结构是一个树形结构 Windows系统可以拥有多个盘符,如C盘、D盘、E盘 Linux没有盘符这个概念,只有一个根目录 /,所有文件都在它下面 Linux路径的描述方式 ● 在Linux系统中,路径之…

idea 创建打包 android App

1、使用 idea 创建 android 工程 2、 配置构建 sdk 3、配置 gradle a、进入 gradle 官网,选择 install (默认是最新版本) b、选择包管理安装,手动安装选择下面一个即可 c、安装 sdk 并通过 sdk 安装 gradle 安装 sdk&#xff1a…

元学习(meta-learning)的通俗解释

目录 1、什么是元学习 2、元学习还可以做什么 3、元学习是如何训练的 1、什么是元学习 meta-learning 的一个很经典的英文解释是 learn to learn,即学会学习。元学习是一个很宽泛的概念,可以有很多实现的方式,下面以目标检测的例子来解释…

3. Java中的锁

文章目录 乐观锁与悲观锁乐观锁(无锁编程,版本号机制)悲观锁两种锁的伪代码比较 通过 8 种锁运行案例,了解锁锁相关的 8 种案例演示场景一场景二场景三场景四场景五场景六场景七场景八 synchronized 有三种应用方式8 种锁的案例实际体现在 3 个地方 从字节码角度分析 synchroni…

移动端学习:如何把exe转换成apk

exe转换成apk是怎么实现的呢?-电脑端-一门科技将exe文件转换成apk文件是一个比较常见的需求,尤其是对于一些开发者和用户来说。但是,这个过程并不是简单的复制和粘贴。在本文中,我们将介绍exe转换成apk的原理和详细介绍。首先,我们需要了解什么https://www.yimenapp.net/k…

前端sql条件拼接js工具

因为项目原因&#xff0c;需要前端写sql&#xff0c;所以弄了一套sql条件拼接的js工具 ​ /*常量 LT : " < ", LE : " < ", GT : " > ", GE : " > ", NE : " ! ", EQ : " ", LIKE : " like &qu…