DOCKER源碼分析1 docker client命令行執行流程


 

源碼閱讀基於docker 19.03

 

1. docker client的入口main

1.1 源碼

docker client的main函數位於cli/cmd/docker/docker.go,代碼的主要內容是:

funcmain(){...dockerCli:=command.NewDockerCli(stdin,stdout,stderr)cmd:=newDockerCommand(dockerCli)iferr:=cmd.Execute();...}

這部分代碼的主要工作是:

  • 生成一個帶有輸入輸出的客戶端對象
  • 根據dockerCli客戶端對象,解析命令行參數,生成帶有命令行參數及客戶端配置信息的cmd命令行對象
  • 根據輸入參數args完成命令執行

 

1.2 流程圖

我們需要追蹤的是docker run的執行流程,從流程圖中可以看到,從cmd := newDockerCommand(dockerCli)的一步步進行下去,可以追蹤到runContainer(dockerCli,opts,copts,contianerConfig),而這里就是run命令的執行函數。 在具體了解runContainer()的具體執行之前,先了解一下cobra.Command結構體。

 

1.3 cobra.Command

1.3.1 首先介紹cobra這個庫的簡單使用:

packagemainimport("fmt""github.com/spf13/cobra")funcmain(){//1.定義主命令varVersionboolvarrootCmd=&cobra.Command{Use:"root [sub]",Short:"My root command",//命令執行的函數Run:func(cmd*cobra.Command,args[]string){fmt.Printf("Inside rootCmd Run with args: %v\n",args)ifVersion{fmt.Printf("Version:1.0\n")}},}//2.定義子命令varsubCmd=&cobra.Command{Use:"sub [no options!]",Short:"My subcommand",//命令執行的函數Run:func(cmd*cobra.Command,args[]string){fmt.Printf("Inside subCmd Run with args: %v\n",args)},}//添加子命令rootCmd.AddCommand(subCmd)//3.為命令添加選項flags:=rootCmd.Flags()flags.BoolVarP(&Version,"version","v",false,"Print version information and quit")//執行命令_=rootCmd.Execute()}

基本用法大概就是四步:

  • 定義一個主命令(包含命令執行函數等)
  • 定義若干子命令(包含命令執行函數等,根據需要可以為子命令定義子命令),並添加到主命令
  • 為命令添加選項
  • 執行命令

1.3.2 docker中cobra.Command的使用

docker中Command的使用就體現在commands.AddCommands()。在commands.AddCommands(cmd, dockerCli)中,將run、build等一些命令的執行函數添加到commands中。

 

 

2. runContainer()

2.1 源碼

runContainer()的代碼位於cli/command/container/run.go代碼的主要部分為:

funcrunContainer(dockerCli*command.DockerCli,opts*runOptions,copts*containerOptions,containerConfig*containerConfig)error{config:=containerConfig.ConfighostConfig:=containerConfig.HostConfig...createResponse,err:=createContainer(ctx,dockerCli,containerConfig,opts.name)//向daemon發送create...client.ContainerStart(ctx,createResponse.ID,types.ContainerStartOptions{})////向daemon發送post}

2.2 流程圖

ContainerCreate()ContainerStart()中分別向daemon發送了create和start命令。下一步,就需要到docker daemon中分析daemon對create和start的處理。

 

結語

本文分析了docker client對於docker run命令的處理流程,從上文的分析中的最后可以看到,client向daemon分別發送了create和start兩個命令,這是容易創建的兩個步驟,在下一篇文章中將分析daemon的處理流程。

 

參考

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM