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.rhkb.cn/news/265227.html

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

相关文章

R语言实现分位数回归和二次分位数回归

大家好,我是带我去滑雪!新的一年,新的气象,在接下来的日子里我将继续和各位小伙伴们分享我在科研道路上,学习的一些知识! 分位数回归和二次分位数回归是统计学中用于分析因变量与自变量之间关系的方法&…

数据结构:链表的冒泡排序

法一:修改指针指向 //法二 void maopao_link(link_p H){if(HNULL){printf("头节点为空\n");return;}if(link_empty(H)){printf("链表为空\n");return;}link_p tailNULL;while(H->next->next!tail){link_p pH;link_p qH->next;while(q…

2022《OpenScene: 3D Scene Understanding with Open Vocabularies》阅读笔记2

A. Implementation Details 3D Distillation. 我们基于PyTorch实现。为了提取,我们使用Adam[26]作为优化器,初始学习率为1e−4,并训练100个epochs。对于MinkowskiNet,我们对ScanNet和Matterport3D实验使用2cm的体素大小,对nuScenes使用5cm的体素尺寸。对于室内数据集,我…

12年高级工程师的“飞升之路”,redis和rabbitmq面试题

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

【管理咨询宝藏资料25】某能源集团五年发展战略报告

本报告首发于公号“管理咨询宝藏”,如需阅读完整版报告内容,请查阅公号“管理咨询宝藏”。 【管理咨询宝藏资料25】某能源集团五年发展战略报告 【关键词】战略规划、五年战略、管理咨询 【文件核心观点】 - LL应以快速做大做强为目标,专注…

laravel8配合jwt

composer 安装包 composer require tymon/jwt-authconfig/app.php 注册服务提供者 providers > [Tymon\JWTAuth\Providers\LaravelServiceProvider::class, ]aliases > [JWTAuth > Tymon\JWTAuth\Facades\JWTAuth::class,JWTFactory > Tymon\JWTAuth\Facades\JWT…

HTTP 的 multipart 类型

上一篇文章讲到 http 的 MIME 类型 http MIME 类型 里有一个 multipart 多部分对象集合类型,这个类型 http 指南里有讲到:MIME 中的 multipart(多部分)电子邮件报文中包含多个报文,它们合在一起作为单一的复杂报文发送…

Rocky Linux 运维工具 systemctl

一、​​systemctl​的简介 ​​systemctl​是用于管理系统服务的命令行工具。​systemctl​命令可以启动、停止、重启或重新加载服务,并管理它们。 二、systemctl​的参数说明 序号参数描述1start启动指定系统服务2stop停止指定系统服务3status显示指定系统服务的…

STM32 +合宙1.54“ 电子墨水屏(e-paper)驱动显示示例

STM32 合宙1.54“ 电子墨水屏(e-paper)驱动显示示例 📍相关篇《Arduino框架下ESP32/ESP8266合宙1.54“ 电子墨水屏(e-paper)驱动显示示例》🔖程序是从GooDisplay品牌和微雪电子下同型号规格墨水屏的示例程序…

Ubuntu Mysql Innodb cluster集群搭建+MaxScale负载均衡(读写分离)

Ubuntu系统版本 20.04.3 LTS (Focal Fossa) 、64位系统。 cat /etc/os-release查看Ubuntu系统是32位还是64位 uname -m如果显示“i686”,则表示安装了32位操作系统。如果显示“x86_64”,则表示安装了64位操作系统。 一、安装MySql 参考: https://blog.csdn.net/qq_3712…

高频面试题整理(一)

文章目录 平台无关性如何实现?JVM如何加载 .class文件?什么是反射?谈谈ClassLoader谈谈类的双亲委派机制类的加载方式Java的内存模型?JVM内存模型-jdk8程序计数器:Java虚拟机栈局部变量表和操作数栈: Java内存模型中堆和栈的区别…

Linux之前后端项目部署与发布

目录 前言 一. Nginx配置安装(自启动) 1.1 一键安装4个依赖 1.2 上传并解压安装包 1.3 安装nginx 1.4 启动Nginx服务 1.5 防火墙规则 1.6 配置开机自启动 1.7 修改/etc/rc.d/rc/local的权限 二. Nginx负载多个tomcat 2.1 准备2个tomcat 2.2 修改第二个…

【Java设计模式】四、适配器模式

文章目录 1、适配器模式2、举例 1、适配器模式 适配器模式Adapter Pattern,是做为两个不兼容的接口之间的桥梁目的是将一个类的接口转换成客户希望的另外一个接口适配器模式可以使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 最后,适配器…

阿里云中小企业扶持权益,助力企业开启智能时代创业新范式

在数字化浪潮的推动下,中小企业正面临着转型升级的重要关口。阿里云深知中小企业的挑战与机遇,特别推出了一系列中小企业扶持权益,旨在帮助企业以更低的成本、更高的效率拥抱云计算,开启智能时代创业的新范式。 一、企业上云权益…

自动驾驶消息传输机制-LCM

需要用到LCM消息通讯,遂研究下。 这里写目录标题 1 LCM简介2. LCM源码分析3 LCM C教程与实例3.1 安装配置及介绍3.2 创建类型定义3.3 初始化LCM3.4 发布publish一个消息3.5 订阅和接收一个消息3.6 LCM进程间通讯3.7 注意事项?3.7.1 当数据结构定义的是数…

SpringMVC 学习(十)之异常处理

目录 1 异常处理介绍 2 通过 SimpleMappingExceptionResolver 实现 3 通过接口 HandlerExceptionResolver 实现 4 通过 ExceptionHandler 注解实现(推荐) 1 异常处理介绍 在 SpringMVC中,异常处理器(Exceptio…

go test用法(获取单元测试覆盖率)

go test用法(获取ut覆盖率) 为了提升系统的稳定性,一般公司都会对代码的单元测试覆盖率有一定要求。下面针对golang自带的测试命令go test做讲解。 1 命令 1.1 go test ./… (运行当前目录及所有子目录下的测试用例) …

13.云原生之常用研发中间件部署

云原生专栏大纲 文章目录 mysql主从集群部署mysql高可用集群高可用互为主从架构互为主从架构如何实现主主复制中若是两台master上同时出现写操作可能会出现的问题该架构是否存在问题? heml部署mysql高可用集群 nacos集群部署官网文档部署nacoshelm部署nacos redis集…

yolov9 瑞芯微芯片rknn部署、地平线芯片Horizon部署、TensorRT部署

特别说明:参考官方开源的yolov9代码、瑞芯微官方文档、地平线的官方文档,如有侵权告知删,谢谢。 模型和完整仿真测试代码,放在github上参考链接 模型和代码。 之前写过yolov8检测、分割、关键点模型的部署的多篇博文,y…

Mysql 高可用解决方案

1.环境说明 操作系统:centos7.7 主服务器:node2(192.168.1.102) 从服务器:node3(192.168.1.103) keepalived中虚拟ip(VIP):192.168.1.100 2.准备事项 主库和从库数据库的版本一致把主库的数据同步给从库一份 3.主库配置 3.1 编辑MySQL配…