<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
建立pod
的全流程入手,瞭解各元件的工作內容,元件主要包括以下kubectl
kube-apiserver
kube-scheduler
kube-controller
kubelet
kubectl
apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx image: nginx:1.8
kubectl create -f nginx_pod.yaml pod/nginx-pod created
提示建立成功
kubectl get pods NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 4m22s
列印出狀態:
metadata.name
我們的目標是檢視kubectl create -f nginx_pod.yaml
這個命令是怎麼執行的
在cmd/kubectl中
func main() { // 如果不呼叫rand.Seed,每次重新執行這個main函數,rand下的函數返回值始終一致 // Seed即隨機的種子,每次用時間戳作為種子,就能保證隨機性 rand.Seed(time.Now().UnixNano()) // 建立了kubectl命令的預設引數 command := cmd.NewDefaultKubectlCommand() // TODO: once we switch everything over to Cobra commands, we can go back to calling // cliflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the // normalize func and add the go flag set by hand. pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc) pflag.CommandLine.AddGoFlagSet(goflag.CommandLine) // cliflag.InitFlags() // 紀錄檔的初始化與退出 logs.InitLogs() defer logs.FlushLogs() // 執行command if err := command.Execute(); err != nil { os.Exit(1) } }
// k8s的命令列工具採用了 cobra 庫,具有命令提示等強大功能,比go語言自帶的flag強大很多,可參考 github.com/spf13/cobra func NewDefaultKubectlCommand() *cobra.Command { return NewDefaultKubectlCommandWithArgs(NewDefaultPluginHandler(plugin.ValidPluginFilenamePrefixes), os.Args, os.Stdin, os.Stdout, os.Stderr) } func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string, in io.Reader, out, errout io.Writer) *cobra.Command { // 初始化NewKubectlCommand,採用標準輸入、輸出、錯誤輸出 cmd := NewKubectlCommand(in, out, errout) if pluginHandler == nil { return cmd } if len(args) > 1 { // 這裡為傳入的引數,即 create -f nginx_pod.yaml 部分 cmdPathPieces := args[1:] // 呼叫cobra的Find去匹配args if _, _, err := cmd.Find(cmdPathPieces); err != nil { if err := HandlePluginCommand(pluginHandler, cmdPathPieces); err != nil { fmt.Fprintf(errout, "%vn", err) os.Exit(1) } } } return cmd }
程式碼較長,選擇關鍵性的內容進行講解
func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command { warningHandler := rest.NewWarningWriter(err, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(err)}) warningsAsErrors := false // 建立主命令 告訴你kubectl該怎麼用 cmds := &cobra.Command{ Use: "kubectl", Short: i18n.T("kubectl controls the Kubernetes cluster manager"), Long: templates.LongDesc(` kubectl controls the Kubernetes cluster manager. Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/`), Run: runHelp, // 初始化後,在執行指令前的勾點 PersistentPreRunE: func(*cobra.Command, []string) error { rest.SetDefaultWarningHandler(warningHandler) // 這裡是做pprof效能分析,跳轉到對應程式碼可以看到,我們可以用引數 --profile xxx 來採集效能指標,預設儲存在當前目錄下的profile.pprof中 return initProfiling() }, // 執行指令後的勾點 PersistentPostRunE: func(*cobra.Command, []string) error { // 儲存pprof效能分析指標 if err := flushProfiling(); err != nil { return err } // 列印warning條數 if warningsAsErrors { count := warningHandler.WarningCount() switch count { case 0: // no warnings case 1: return fmt.Errorf("%d warning received", count) default: return fmt.Errorf("%d warnings received", count) } } return nil }, // bash自動補齊功能,可通過 kubectl completion bash 命令檢視 // 具體安裝可參考 https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion BashCompletionFunction: bashCompletionFunc, } // 範例化Factory介面,工廠模式 f := cmdutil.NewFactory(matchVersionKubeConfigFlags) // 省略範例化的過程程式碼 // kubectl定義了7類命令,結合Message和各個子命令的package名來看 groups := templates.CommandGroups{ { // 1. 初級命令,包括 create/expose/run/set Message: "Basic Commands (Beginner):", Commands: []*cobra.Command{ create.NewCmdCreate(f, ioStreams), expose.NewCmdExposeService(f, ioStreams), run.NewCmdRun(f, ioStreams), set.NewCmdSet(f, ioStreams), }, }, { // 2. 中級命令,包括explain/get/edit/delete Message: "Basic Commands (Intermediate):", Commands: []*cobra.Command{ explain.NewCmdExplain("kubectl", f, ioStreams), get.NewCmdGet("kubectl", f, ioStreams), edit.NewCmdEdit(f, ioStreams), delete.NewCmdDelete(f, ioStreams), }, }, { // 3. 部署命令,包括 rollout/scale/autoscale Message: "Deploy Commands:", Commands: []*cobra.Command{ rollout.NewCmdRollout(f, ioStreams), scale.NewCmdScale(f, ioStreams), autoscale.NewCmdAutoscale(f, ioStreams), }, }, { // 4. 叢集管理命令,包括 cerfificate/cluster-info/top/cordon/drain/taint Message: "Cluster Management Commands:", Commands: []*cobra.Command{ certificates.NewCmdCertificate(f, ioStreams), clusterinfo.NewCmdClusterInfo(f, ioStreams), top.NewCmdTop(f, ioStreams), drain.NewCmdCordon(f, ioStreams), drain.NewCmdUncordon(f, ioStreams), drain.NewCmdDrain(f, ioStreams), taint.NewCmdTaint(f, ioStreams), }, }, { // 5. 故障排查和偵錯,包括 describe/logs/attach/exec/port-forward/proxy/cp/auth Message: "Troubleshooting and Debugging Commands:", Commands: []*cobra.Command{ describe.NewCmdDescribe("kubectl", f, ioStreams), logs.NewCmdLogs(f, ioStreams), attach.NewCmdAttach(f, ioStreams), cmdexec.NewCmdExec(f, ioStreams), portforward.NewCmdPortForward(f, ioStreams), proxy.NewCmdProxy(f, ioStreams), cp.NewCmdCp(f, ioStreams), auth.NewCmdAuth(f, ioStreams), }, }, { // 6. 高階命令,包括diff/apply/patch/replace/wait/convert/kustomize Message: "Advanced Commands:", Commands: []*cobra.Command{ diff.NewCmdDiff(f, ioStreams), apply.NewCmdApply("kubectl", f, ioStreams), patch.NewCmdPatch(f, ioStreams), replace.NewCmdReplace(f, ioStreams), wait.NewCmdWait(f, ioStreams), convert.NewCmdConvert(f, ioStreams), kustomize.NewCmdKustomize(ioStreams), }, }, { // 7. 設定命令,包括label,annotate,completion Message: "Settings Commands:", Commands: []*cobra.Command{ label.NewCmdLabel(f, ioStreams), annotate.NewCmdAnnotate("kubectl", f, ioStreams), completion.NewCmdCompletion(ioStreams.Out, ""), }, }, } groups.Add(cmds) filters := []string{"options"} // alpha相關的子命令 alpha := cmdpkg.NewCmdAlpha(f, ioStreams) if !alpha.HasSubCommands() { filters = append(filters, alpha.Name()) } templates.ActsAsRootCommand(cmds, filters, groups...) // 程式碼補全相關 for name, completion := range bashCompletionFlags { if cmds.Flag(name) != nil { if cmds.Flag(name).Annotations == nil { cmds.Flag(name).Annotations = map[string][]string{} } cmds.Flag(name).Annotations[cobra.BashCompCustom] = append( cmds.Flag(name).Annotations[cobra.BashCompCustom], completion, ) } } // 新增其餘子命令,包括 alpha/config/plugin/version/api-versions/api-resources/options cmds.AddCommand(alpha) cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams)) cmds.AddCommand(plugin.NewCmdPlugin(f, ioStreams)) cmds.AddCommand(version.NewCmdVersion(f, ioStreams)) cmds.AddCommand(apiresources.NewCmdAPIVersions(f, ioStreams)) cmds.AddCommand(apiresources.NewCmdAPIResources(f, ioStreams)) cmds.AddCommand(options.NewCmdOptions(ioStreams.Out)) return cmds }
func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { // create子命令的相關選項 o := NewCreateOptions(ioStreams) // create子命令的相關說明 cmd := &cobra.Command{ Use: "create -f FILENAME", DisableFlagsInUseLine: true, Short: i18n.T("Create a resource from a file or from stdin."), Long: createLong, Example: createExample, // 驗證引數並執行 Run: func(cmd *cobra.Command, args []string) { if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) { ioStreams.ErrOut.Write([]byte("Error: must specify one of -f and -knn")) defaultRunFunc := cmdutil.DefaultSubCommandRun(ioStreams.ErrOut) defaultRunFunc(cmd, args) return } cmdutil.CheckErr(o.Complete(f, cmd)) cmdutil.CheckErr(o.ValidateArgs(cmd, args)) // 核心的執行程式碼邏輯是在這裡的RunCreate cmdutil.CheckErr(o.RunCreate(f, cmd)) }, } o.RecordFlags.AddFlags(cmd) usage := "to use to create the resource" // 加入檔名選項的flag -f,儲存到o.FilenameOptions.Filenames中,對應上面 cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage) cmdutil.AddValidateFlags(cmd) cmd.Flags().BoolVar(&o.EditBeforeCreate, "edit", o.EditBeforeCreate, "Edit the API resource before creating") cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows", "Only relevant if --edit=true. Defaults to the line ending native to your platform.") cmdutil.AddApplyAnnotationFlags(cmd) cmdutil.AddDryRunFlag(cmd) cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)") cmd.Flags().StringVar(&o.Raw, "raw", o.Raw, "Raw URI to POST to the server. Uses the transport specified by the kubeconfig file.") cmdutil.AddFieldManagerFlagVar(cmd, &o.fieldManager, "kubectl-create") o.PrintFlags.AddFlags(cmd) // create的子命令,指定create物件 cmd.AddCommand(NewCmdCreateNamespace(f, ioStreams)) cmd.AddCommand(NewCmdCreateQuota(f, ioStreams)) cmd.AddCommand(NewCmdCreateSecret(f, ioStreams)) cmd.AddCommand(NewCmdCreateConfigMap(f, ioStreams)) cmd.AddCommand(NewCmdCreateServiceAccount(f, ioStreams)) cmd.AddCommand(NewCmdCreateService(f, ioStreams)) cmd.AddCommand(NewCmdCreateDeployment(f, ioStreams)) cmd.AddCommand(NewCmdCreateClusterRole(f, ioStreams)) cmd.AddCommand(NewCmdCreateClusterRoleBinding(f, ioStreams)) cmd.AddCommand(NewCmdCreateRole(f, ioStreams)) cmd.AddCommand(NewCmdCreateRoleBinding(f, ioStreams)) cmd.AddCommand(NewCmdCreatePodDisruptionBudget(f, ioStreams)) cmd.AddCommand(NewCmdCreatePriorityClass(f, ioStreams)) cmd.AddCommand(NewCmdCreateJob(f, ioStreams)) cmd.AddCommand(NewCmdCreateCronJob(f, ioStreams)) return cmd }
func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error { // f為傳入的Factory,主要是封裝了與kube-apiserver互動使用者端 schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate")) if err != nil { return err } cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace() if err != nil { return err } // 範例化Builder,這塊的邏輯比較複雜,我們先關注檔案部分 這些大部分是給builder設定引數,在Do的時候執行邏輯,返回我們想要的Result r := f.NewBuilder(). Unstructured(). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). // 讀取檔案資訊,發現除了支援簡單的本地檔案,也支援標準輸入和http/https協定存取的檔案,儲存為Visitor FilenameParam(enforceNamespace, &o.FilenameOptions). LabelSelectorParam(o.Selector). Flatten(). Do() err = r.Err() if err != nil { return err } count := 0 // 呼叫visit函數,建立資源 err = r.Visit(func(info *resource.Info, err error) error { // 我們看到的pod建立成功就是在這裡列印的 列印結果 xxxx created return o.PrintObj(info.Object) }) return nil }
站在前人的肩膀上,向前輩致敬,Respect!
cmd/kubectl
中找到kubectl的啟動過程,kubernetes的命令列工具了利用spf13/cobra
庫,傳入並解析引數,去匹配子命令,設定kubectl的預設引數。NewKubectlCommand
中進行初始化,有初始化前後的勾點和七類命令,還實現了Factory
,在命令中進入Create,進行驗證引數並執行,把檔名設定到CreateOptions中,進入RunCreate
,其中傳入的Factory,封裝了與kube-apiserver互動的使用者端。Builder
,該函數呼叫了NewBuilder、Schema等一系列函數,這段程式碼所做的事情是將命令列接收到的引數轉化為一個資源的列。它使用了Builder模式的變種,使用獨立的函數做各自的資料初始化工作。函數Schema、ContinueOnError、NamespaceParam、DefaultNamespace、FilenameParam、SelectorParam和Flatten都引入了一個指向Builder結構的指標,執行一些對它的修改,並且將這個結構體返回給呼叫鏈中的下一個方法來執行這些修改。Visitor
,再呼叫Visit
返回結果,下一節將介紹Visitor存取者模式是和發請求建立pod的細節是怎麼實現的。以上就是Kubernetes kubectl中Pod建立流程原始碼解析的詳細內容,更多關於Kubernetes kubectl Pod建立的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45