赞
踩
k8s 版本 v1.24.16
kubectl的职责
cat test/fixtures/doc-yaml/user-guide/pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
字段名 | 含义 |
---|---|
kind | Pod |
metadata.name | |
spec.containers.name | |
spec.containers.image | image名称:版本 |
对象规约(Spec) 与状态 (Status)
[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.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, ""),
},
},
}
// 进入口
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建造者设计模式
// 快速定位代码
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()
使用场景:
// 快速定位代码
cmdutil.CheckErr(o.RunCreate(f, cmd)) --> err = r.Visit(func(info *resource.Info, err error) error {
// 注意 Visit 是由 Builder 中 FilenameParam 构建的
r := f.NewBuilder().
...
// 构建 Visit
FilenameParam(enforceNamespace, &o.FilenameOptions).
...
// 创建 Visit
Do()
// 定位
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)
err = r.Visit(func(info *resource.Info, err error) error { --> if o.DryRunStrategy != cmdutil.DryRunClient { --> Create(info.Namespace, true, info.Object)(最终创建资源)
kubectl使用及进阶
至此结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。