最近剛開始學習kubernetes這個工具莫杈,從apiserver route開始看一些kubernetes的代碼分析執(zhí)行流程,想從代碼里面深入學習一下,剛開始讀寫的比較簡單,希望有不對的地方大家可以提出來乙漓,希望可以通過一點點的積累學習這個項目。
這里先從github上面把代碼clone到本地释移,我這里是直接從master上clone下來的目測最新的版本是v1.7.9-alpha.0叭披。
首先apiserver是從cmd命令開始的,一步步執(zhí)行最終初始化一個webserver秀鞭。apiserver的執(zhí)行入口比較好找趋观,從kubernetes/cmd/kube-apiserver/apiserver.go
開始的:
func main() {
rand.Seed(time.Now().UTC().UnixNano())
//初始化默認的server配置信息
s := options.NewServerRunOptions()
//通過flag命令行參數(shù)重寫配置信息,其中包含8080,6443等端口信息
s.AddFlags(pflag.CommandLine)
flag.InitFlags()
logs.InitLogs()
defer logs.FlushLogs()
verflag.PrintAndExitIfRequested()
//這里是具體的server運行函數(shù)
if err := app.Run(s); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}
這是apiserver.go的代碼比較短就直接復制過來了,在上面加了一些注釋,可以看到其他的代碼我們都可以忽略锋边,重要的入口在app.Run(s)
所以我們可以根據(jù)這個端口一路跟蹤下去。這個方法的所在位置kubernetes/cmd/kube-apiserver/app/server.go
:
func Run(s *options.ServerRunOptions) error {
config, sharedInformers, err := BuildMasterConfig(s)
if err != nil {
return err
}
return RunServer(config, sharedInformers, wait.NeverStop)
}
func RunServer(config *master.Config, sharedInformers informers.SharedInformerFactory, stopCh <-chan struct{}) error {
m, err := config.Complete().New()
if err != nil {
return err
}
sharedInformers.Start(stopCh)
return m.GenericAPIServer.PrepareRun().Run(stopCh)
}
其中BuildMasterConfig
是構建了一大堆master的配置信息编曼,能夠看到其實RunServer
中的Run
方法是運行服務的方法繼續(xù)跟進這個方法就來到了staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
這個文件里面豆巨,這里其實是引用了一個kubernetes的apiserver的外部依賴:
func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error {
if s.SecureServingInfo != nil && s.Handler != nil {
if err := s.serveSecurely(stopCh); err != nil {
return err
}
}
if s.InsecureServingInfo != nil && s.InsecureHandler != nil {
if err := s.serveInsecurely(stopCh); err != nil {
return err
}
}
s.RunPostStartHooks()
// err == systemd.SdNotifyNoSocket when not running on a systemd system
if err := systemd.SdNotify("READY=1\n"); err != nil && err != systemd.SdNotifyNoSocket {
glog.Errorf("Unable to send systemd daemon successful start message: %v\n", err)
}
<-stopCh
return nil
}
其中s.serveInsecurely(stopCh)
這個方法就是運行8080端口server的方法,通過這個方法跟進到staging/src/k8s.io/apiserver/pkg/server/serve.go
這個文件里面:
unc (s *GenericAPIServer) serveInsecurely(stopCh <-chan struct{}) error {
insecureServer := &http.Server{
Addr: s.InsecureServingInfo.BindAddress,
Handler: s.InsecureHandler,
MaxHeaderBytes: 1 << 20,
}
glog.Infof("Serving insecurely on %s", s.InsecureServingInfo.BindAddress)
var err error
s.effectiveInsecurePort, err = runServer(insecureServer, s.InsecureServingInfo.BindNetwork, stopCh)
return err
}
其中s.InsecureServingInfo.BindAddress
這個地址就是默認的綁定的127.0.0.1:8080這個地址掐场,可以通過運行apiserver cmd命令的時候修改往扔,而s.InsecureHandler
就是這個server對apipath操作對應的一些方法,這個是最核心的東西熊户,下一步我們反過來繼續(xù)跟進這個東西萍膛。可以從上面看到runServer(insecureServer, s.InsecureServingInfo.BindNetwork, stopCh)
這個方法嚷堡,這個方法內部的具體實現(xiàn)比較長蝗罗,這里就不復制過來了,這個方法內部就是關于把這個http server運行起來的具體內容蝌戒。