ÔÚÉÏÎÄÖУ¬±ÊÕßͨ¹ý·ÖÎöDockerµÄ¼Ü¹¹£¬³õ²½×÷ÁËDockerµÄ¼Ü¹¹Í¼¡£¼Ü¹¹Í¼±¾Éí¸ü¶àµÄ³öÓÚ±ÊÕßµÄÀí½â£¬ÎªÁ˱ãÓÚÀí½â£¬¶ÔÓÚDocker´úÂë±¾Éí×öÁËһЩ³éÏó£¬ÀýÈçServerµÄÔËÐж¼ÊÇÒÔÒ»¸öJobµÄÐÎʽ´æÔڵ쬶ø¼Ü¹¹Í¼Öв¢Î´Ã÷ÏԵıíÃ÷ÕâÒ»µã¡£
DockerÄ£¿é¼ò½é
±¾ÎĽ«´ÓÔ´ÂëµÄ½Ç¶È·ÖÎöDockerµÄÆô¶¯£¬Ö÷ÒªÊÇ×÷Ϊһ¸ödaemon½ø³ÌµÄÆô¶¯¡£ÔÚÕâ֮ǰ£¬ÐèÒªÏÈÇåÎúDockerÄÚ²¿×îÖ÷ÒªµÄ¼¸¸ö¸ÅÄDaemon£¬EngineÒÔ¼°Job¡£
Daemon
Daemon¿ÉÒÔÈÏΪÊÇDockerÊØ»¤½ø³ÌµÄÔØÌå¡£´ÓÔ´ÂëµÄÊÓ½ÇÀ´¿´£¬Daemon¿ÉÒÔÈÏΪÊÇDaemon½á¹¹Ì壬ÒÔ¼°Daemon
packageÖж¨ÒåµÄһϵÁз½·¨µÄ×ܺ͡£Í¬Ê±DaemonÒ²ÊÇDockerÄÚ²¿µÄÒ»¸ö½á¹¹Ì壬´Ó½á¹¹ÌåµÄ¶¨Ò壬¿ÉÒÔ¿´³öDaemon¹ØÁªÁËDockerµÄ¾ø´ó²¿·ÖµÄÄÚÈÝ£¬Daemon½á¹¹µÄ¶¨ÒåÈçÏ£º
type Daemon struct { repository string sysInitPath string containers *contStore graph *graph.Graph repositories *graph.TagStore idIndex *truncindex.TruncIndex sysInfo *sysinfo.SysInfo volumes *graph.Graph eng *engine.Engine config *Config containerGraph *graphdb.Database driver graphdriver.Driver execDriver execdriver.Driver } |
ÒÔϼòÒª½éÉܽṹÌåÄÚ²¿Ã¿¸ö¶ÔÏó£º
repository ËùÓÐcontainerµÄĿ¼µÄ¸¸Ä¿Â¼
sysInitPath sysInitµÄ·¾¶
containers ËùÓÐcontainerµÄ´æ´¢¼Ç¼
graph ¹ØÓÚimageµÄgraphÐÅÏ¢
repositories GraphµÄ´æ´¢¿â
idIndex
sysInfo DockerËù´¦hostµÄϵͳÐÅÏ¢
volumes ËÞÖ÷»úÉÏÇÒÔÚÈÝÆ÷¸ùĿ¼ÍâµÄһЩĿ¼£¬¿ÉÒÔ¹ÒÔØÖÁÈÝÆ÷ÄÚ²¿
eng DockerÄÚ²¿ËùÓÐJobµÄÖ´ÐÐÒýÇæ
config DockerËùÐèÒªµÄÅäÖÃÐÅÏ¢
containerGraph GraphDB¶ÔÏó£¬ÓÃÓÚgraphÐÅÏ¢µÄ´æÈ¡
driver ÓйØimageµÄ´æ´¢µÄgraphÇý¶¯
execDriver ÓйØÈÝÆ÷ÔËÐÐÓë¹ÜÀíµÄ²Ù×÷Çý¶¯
ÓÉÓÚ½éÉÜ·±ÔÓµÄDockerÄÚÊôÐÔ²»ÊDZ¾ÎĵÄÄ¿µÄ£¬¹Ê²»ÔÙ׸Êö¡£
Engine
ÔÚÔ´´úÂëÖйØÓÚEngineµÄ½éÉܷdz£È·ÇУºEngineÊÇÕû¸öDockerµÄºËÐIJ¿·Ö£¬Ëü°çÑÝËùÓÐDocker
ContainerµÄ´æ´¢²Ö¿âµÄ½ÇÉ«£¬²¢ÇÒͨ¹ýÖ´ÐÐJobÀ´ÊµÏÖ²Ù×ÝÕâЩÈÝÆ÷¡£
EngineµÄ½á¹¹Ì嶨ÒåÈçÏ£º
type Engine struct { handlers map[string]Handler catchall Handler hack Hack // data for temporary hackery (see hack.go) id string Stdout io.Writer Stderr io.Writer Stdin io.Reader Logging bool tasks sync.WaitGroup l sync.RWMutex // lock for shutdown shutdown bool onShutdown []func() // shutdown handlers } |
ÆäÖÐÐèÒªÌØ±ð×¢ÒâµÄ¾ÍÊÇhandlersÊôÐÔ£¬¸ÃÊôÐÔΪһ¸ömapÀàÐ͵ĶÔÏ󣬴洢µÄ¶¼ÊǹØÓÚij¸öÌØ¶¨handlerµÄ´¦Àí·½·¨£¬Ö®ºó»áÏêϸ·ÖÎöhandler¡£
Job
¹ØÓÚJobµÄ¶¨Ò壬ԴÂëÖÐ×¢ÊÍÈç´Ë˵µÀ£ºÔÚDockerµÄengineÖУ¬JobÊÇ×î»ù±¾»ù±¾¹¤×÷µ¥Î»¡£Docker¿ÉÒÔ×öµÄËùÓй¤×÷£¬×îÖÕ¶¼±ØÐë±íʾ³ÉÒ»¸öJob¡£ÀýÈ磺ÔÚÈÝÆ÷ÄÚÖ´ÐÐÒ»¸ö½ø³Ì£¬ÕâÊÇÒ»¸öJob£»´´½¨Ò»¸öÐÂÈÝÆ÷£¬ÕâÊÇÒ»¸öJob£»´ÓInternetÉÏÏÂÔØÒ»·ÝÎĵµ£¬ÕâÊÇÒ»¸öJob£»·þÎñÓÚHTTPµÄAPI£¬ÕâÒ²ÊÇÒ»¸öJob£¬µÈµÈ¡£JobµÄ¶¨ÒåÔ´ÂëÈçÏ£º
type Job struct { Eng *Engine Name string Args []string env *Env Stdout *Output Stderr *Output Stdin *Input handler Handler status Status end time.Time } |
ͬʱ£¬JobµÄAPIÉè¼ÆµÃºÜÏñÒ»¸öunixµÄ½ø³Ì£º±ÈÈç˵£¬JobÓÐÒ»¸öÃû³Æ£¬ÓвÎÊý£¬Óл·¾³±äÁ¿£¬Óбê×¼µÄÊäÈëÊä³ö£¬ÓдíÎó´¦Àí£¬Óзµ»Ø×´Ì¬£¬ÆäÖзµ»Ø0±íʾִÐгɹ¦£¬·µ»ØÆäËûÊý×Ö±íʾ´íÎó¡£
DockerµÄÆô¶¯
DockerµÄÆô¶¯¿ÉÒÔÈÏΪÊÇͨ¹ýDockerµÄ¿ÉÖ´ÐÐÎļþ£¬Æô¶¯Ò»¸öDockerµÄÊØ»¤½ø³Ì£¬Õâ¸öÊØ»¤½ø³ÌÔÚÆô¶¯¹ý³ÌÖÐÍê³ÉÁËÆô¶¯ËùÐèÒªµÄËùÓй¤×÷£¬²¢ÇÒ×îÖÕ×÷Ϊһ¸öserver¿ÉÒÔΪdocker
client·¢ËÍÀ´µÄÖÚ¶àÇëÇó·þÎñ¡£
ÒÔÏ´ÓÔ´ÂëµÄ½Ç¶È·ÖÎöDockerµÄÆô¶¯¡£
Ê×ÏÈ£¬DockerµÄmainº¯ÊýλÓÚ./docker/docker.goÖС£Ö´ÐÐÁ÷³ÌÈçÏ¡£
reexec¡¢flag½âÎöÓëÅжÏ
ÔÚmainº¯ÊýÖУ¬Ê×ÏÈÖ´ÐÐÁËÒÔÏÂÄÚÈÝ£º
if reexec.Init() { return } flag.Parse() // FIXME: validate daemon flags here if *flVersion { showVersion() return } if *flDebug { os.Setenv("DEBUG", "1") } |
Ê×ÏÈÅжÏreexec.Init()µÄ·µ»ØÖµ£¬ÈôÎªÕæ£¬Ö±½Ó·µ»Ø£»·ñÔò½øÐÐflag.Parse()·½·¨£¬¸Ã·½·¨Ö÷Òª½âÎöÁËflag²ÎÊý£¬²¢ÎªÖ®ºóµÄflag²ÎÊýÅжÏ×ö×¼±¸¡£ÖÚ¶àµÄflag²ÎÊýλÓÚ./docker/flag.goÖУ¬²¢ÇÒÔÚmainº¯ÊýÖ´ÐÐ֮ǰ¾ÍÍê³ÉvarµÄ¶¨ÒåÒÔ¼°initº¯ÊýµÄÖ´ÐС£½âÎöÍæflag²ÎÊýÖ®ºó£¬Ëæ¼´ÅжÏÖÚ²ÎÊý£¬Èô*flVersionÎªÕæµÄ»°£¬Ö±½Óͨ¹ýshowVersion()·½·¨ÏÔʾDockerµÄ°æ±¾ºÅ£¬Ëæºó·µ»Ø£»Èô*flVersion²»ÎªÕ棬Ôò¼ÌÐøÍùÏÂÅжϣ¬Èô*flDebugÎªÕæ£¬¶ÔÓÚDEBUG»·¾³±äÁ¿ÉèÖÃֵΪ1£¬¼ÌÐøÍùÏÂÖ´ÐС£
flHostsÐÅÏ¢µÄ»ñÈ¡
½Ó×ŵĴúÂëÖ´ÐÐÈçÏ£º
if len(flHosts) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { // If we do not have a host, default to unix socket defaultHost = fmt.Sprintf("unix://%s", api.DEFAULTUNIXSOCKET) } defaultHost, err := api.ValidateHost(defaultHost) if err != nil { log.Fatal(err) } flHosts = append(flHosts, defaultHost) } |
ÒÔÉÏ´úÂëµÄ¹¦ÄÜÖ÷ÒªÊDzéÕÒhostµØÖ·£¬×÷Ϊ֮ºóserverµÄ¼àÌýµØÖ·¡£Èç¹ûÔÚflagµÄ¶¨ÒåÒÔ¼°³õʼ»¯Ö®ºó£¬flHostsµÄ³¤¶ÈÒÀ¾ÉΪ0µÄ»°£¬Ôò˵Ã÷ÅäÖÃÖÐûÓÐÉ趨HostµØÖ·£¬ÐèÒª³ÌÐò×ÔÐвéÕÒ¡£Ê×ÏÈ£¬Í¨¹ýËÞÖ÷»ú»·¾³±äÁ¿ÖеÄDOCKER_HOSTÀ´¸øÄ¬ÈÏhost±äÁ¿defaultHost¸³Öµ£¬Èç¹ûÈÔȻΪ¿Õ£¬»òÕß*flDaemonÎªÕæµÄ»°£¬Í¨¹ýapi¶¨ÒåµÄDEFAULTDAEMONÊôÐÔÀ´³õʼ»¯defaultHost£¬Ä¬ÈÏΪһ¸öunix
socket¡£¾¹ýÑéÖ¤¸ÃdefaultHostÖ®ºó£¬½«defaultHostÌí¼ÓÖÁflHostsĩβ¡£
ÒÔÉÏ¿ÉÒÔÈÏΪÊÇΪDocker daemonµÄÔËÐÐ×öÁ˳ä×ãµÄ×¼±¸¹¤×÷£¬ÒÔϵĴúÂëÕæÕýÔÚ×öDocker
DaemonµÄÆô¶¯¡£
if *flDaemon { mainDaemon() return } |
Ò²¾ÍÊÇ˵Èô*flDaemonÎªÕæ£¬ÔòÖ±½ÓÔËÐÐmainDaemon()·½·¨¡£ÒÔϽ«´óƪ·ù·ÖÎö½éÉÜmainDaemon()Ëù×öµÄ¹¤×÷¡£
mainDaemon()
mainDaemon()µÄʵÏÖλÓÚÎļþ./docker/daemon.goÖС£
flag.Narg()
Ê×ÏÈ£¬DaemonÖ´ÐÐflag.NArg()£¬µ±flag²ÎÊý±»´¦Àíºó£¬ÒѾûÓÐÆäËûµÄ²ÎÊýʱ£¬¼ÌÐøÍùÏÂÖ´ÐС£
´´½¨engine²¢²¶»ñshutdown
Daemon´´½¨Ò»¸öengine£¬²¢ËæÊ±²¶»ñengineµÄshutdownÐźš£
¼ÓÔØbuiltins
¼ÓÔØbuiltins£¬´úÂëΪbuiltins.Register(eng)£¬½øÈë./docker/builtins.go,Ôڸ÷½·¨ÖÐÖ÷Òª°üº¬ÁËÎå¸ö²½Ö裬ÈçÏ£º
func Register(eng *engine.Engine) error { if err := daemon(eng); err != nil { return err } if err := remote(eng); err != nil { return err } if err := events.New().Install(eng); err != nil { return err } if err := eng.Register("version", dockerVersion); err != nil { return err } return registry.NewService().Install(eng) } |
1. daemon(eng) : Ëù×ö¹¤×÷ÊÇΪengine×¢²áÒ»¸öhandler£¬¾ßÌåµÄhandlerÃû³ÆÎª¡°init_networkdriver¡±¡£¾ßÌåµÄ¹¦ÄÜÊdzõʼ»¯Docker»·¾³µÄdocker0ÍøÇÅ£¬´¦Àí·½·¨µÄʵÏÖλÓÚ./daemon/networkdriver/bridge/driver.goÖеÄInitDriver.
func daemon(eng *engine.Engine) error { return eng.Register("init_networkdriver", bridge.InitDriver) } |
2.remote(eng) : Ëù×öµÄ¹¤×÷ÊÇΪengine×¢²áÁ½¸öhandler£¬µÚÒ»¸öhandlerµÄÃû³ÆÎª¡°serveapi¡±£¬¾ßÌåµÄ¹¦ÄÜÊÇʹµÃdaemonÌṩRESTfulµÄAPI£¬±£Ö¤daemon¿ÉÒÔÓëÍâ½ç½¨Á¢Í¨ÐÅ£¬´¦Àí·½·¨µÄʵÏÖΪ./api/server/server.goÖеÄServeApi£»µÚ¶þ¸öhandlerµÄÃû³ÆÎª¡°acceptconnection¡±£¬¾ßÌåµÄ¹¦ÄÜÊÇʹµÃ³õʼ»¯Íê±ÏµÄdaemon¿ÉÒÔ½ÓÊÕÇëÇ󣬴¦Àí·½·¨µÄʵÏÖΪ./api/server/server.goÖеÄAcceptConnections¡£´úÂëÈçÏ£º
func remote(eng *engine.Engine) error { if err := eng.Register("serveapi", apiserver.ServeApi); err != nil { return err } return eng.Register("acceptconnections", apiserver.AcceptConnections) } |
3.events.New().Install(eng)£º DockerµÄeventʼþµÄʵÏÖ£¬¹¦ÄÜÊÇÈÃÍâ½çÖªµÀDockerÄÚ²¿µÄevents£¬ÄÚ²¿µÄlogÒÔ¼°ÄÚ²¿µÄsubscribers_count£¬¾ßÌåµÄjobÃû³Æ·Ö±ðΪ¡°events¡±£¬¡°logs¡±£¬subscribers_count¡°£¬´¦Àí·½·¨µÄʵÏÖΪ./events/events.goÖеÄGet£¬Log£¬SubscribersCount
¡£
// Install installs events public api in docker engine func (e *Events) Install(eng *engine.Engine) error { // Here you should describe public interface jobs := map[string]engine.Handler{ "events": e.Get, "log": e.Log, "subscribers_count": e.SubscribersCount, } for name, job := range jobs { if err := eng.Register(name, job); err != nil { return err } } return nil } |
4.eng.Register("version",dockerVersion):
DockerµÄengine×¢²áÒ»¸öÃû³ÆÎª¡° version¡±µÄhandler£¬´¦Àí·½·¨µÄʵÏÖΪµ±Ç°builtins.goÎļþÖеÄdockerVersion¡£
5.registry.NewService().Install(eng)£º·½·¨ÊµÏÖλÓÚ./registry/service.go£¬Ê×ÏÈÏÈ»ñÈ¡Service¶ÔÏó£¬Ëæºóͨ¹ýInstall·½·¨À´×¢²áÁ½¸öhandler£¬µÚÒ»¸öµÄÃû³ÆÎª¡°auth¡±£¬ÊµÏÖÔÚ¹«ÓÐregistryÖеÄÈÏÖ¤£»µÚ¶þ¸öµÄÃû³ÆÎª¡°search¡±£¬ÊµÏÖÔÚ¹«ÓÐregistryÖвéÕÒimageµÄ¹¦ÄÜ¡£
// Install installs registry capabilities to eng. func (s *Service) Install(eng *engine.Engine) error { eng.Register("auth", s.Auth) eng.Register("search", s.Search) return nil } |
¼ÓÔØDaemon
ÒÔÉÏ·ÖÎö´ó²¿·Öbuiltins.Register(eng)µÄʵÏÖ¡£»Øµ½mainDaemon·½·¨ÖУ¬¼´½øÈëÒ»¸ögoroutine£¬ÈçÏ£º
go func() { d, err := daemon.NewDaemon(daemonCfg, eng) if err != nil { log.Fatal(err) } if err := d.Install(eng); err != nil { log.Fatal(err) } b := &builder.BuilderJob{eng, d} b.Install() // after the daemon is done setting up we can tell the api to start // accepting connections if err := eng.Job("acceptconnections").Run(); err != nil { log.Fatal(err) } }() |
ÒÔÉÏʹÓÃÒ»¸ögoroutineÀ´¼ÓÔØdaemon£¬ÒÔ±£Ö¤Óë´Ëͬʱ£¬¿ÉÒÔ¾¡¿ìµÄÔËÐÐserveapiµÄjob£¬ÒÔÖÂÓÐЩconnectionÀ´ÁÙʱ²»»áÒòΪdaemonÕýÔÚ¼ÓÔØ¶øµÃ²»µ½ÏàÓ¦¡£
NewDaemon()
Ê×ÏÈÖ´ÐеÄÊÇd, err := daemon.NewDaemon(daemonCfg, eng)£¬×÷ÓÃΪ´´½¨Ò»¸ödaemon¶ÔÏ󣬴úÂëʵÏÖλÓÚ./daemon/daemon.goµÄNewDaemon·½·¨¡£ÔÚNewDaemonµÄʵÏÖ¹ý³ÌÖУ¬¿ÉÒÔ·¢ÏÖ¾ßÌåµ÷Óõķ½·¨Îªdaemon,
err := NewDaemonFromDirectory(config, eng)¡£ÔÚÕâÀÎÒÃÇ¿ÉÒÔÏÈÀ´¿´¿´¸Ãconfig²ÎÊýµÄÀ´Àú¡£ÔÚ¼ÓÔØdaemonµÄgoroutineÖУ¬NewDaemonµÄʵ²ÎΪdaemonCfg¡£ÔÚ./docker/daemon.goÖУ¬ÓÐdaemonCfg
= &daemon.Config{}£¬¶øÔÚ¸ÃÎļþÖеÄinit()·½·¨ÖÐʵÏÖÁËdaemonCfg.InstallFlags()£¬¶øInstallFlags()µÄʵÏÖλÓÚ./docker/daemon/config.go£¬ÊµÏÖ¹ý³ÌÖмÓÔØÁ˺ܶàÐèÒªµÄÅäÖÃÏ¼¸ºõDockerËùÐèÒªµÄËùÓÐÅäÖÃÐÅÏ¢¶¼Ôڸ÷Ű¡ÖÐʵÏÖ³õʼ»¯¡£
ÕâÀïÉæ¼°µ½ÁËGolangµÄÒ»¸öÌØÐÔ£¬¼´init()·½·¨µÄÖ´ÐС£ÔÚgolangÖÐinit()·½·¨µÄÌØÐÔÈçÏ£º
init·½·¨ÓÃÓÚ³ÌÐòÖ´ÐÐǰ°üµÄ³õʼ»¯¹¤×÷£¬±ÈÈç³õʼ»¯±äÁ¿µÈ£»
ÿ¸ö°ü¿ÉÒÔÓжà¸öinit·½·¨£»
°üµÄÿһ¸öÔ´ÎļþÒ²¿ÉÒÔÓжà¸öinit·½·¨£»
ͬһ¸ö°üÄÚµÄinit·½·¨µÄÖ´ÐÐ˳ÐòûÓÐÃ÷È·µÄ¶¨Ò壻
²»Í¬°üµÄinit·½·¨°´ÕÕ°üµ¼ÈëµÄÒÀÀµ¹ØÏµ¾ö¶¨³õʼ»¯µÄ˳Ðò£»
init·½·¨²»ÄÜÄÚµ÷Ó㬶øÊÇÔÚmain()º¯Êýµ÷ÓÃǰ×Ô¶¯±»µ÷Óá£
Á˽âÍêconfigµÄÀ´Àú£¬½øÈëNewDaemonFromDirectoryµÄʵÏÖ¡£¸Ã·½·¨µÄʵÏÖ£¬¿ÉÒÔ¼òÒ×µÄÈÏΪÌṩÒÔϹ¦ÄÜ¡£
1.ÑéÖ¤»òÅäÖÃconfig²ÎÊý
// Apply configuration defaults if config.Mtu == 0 { // FIXME: GetDefaultNetwork Mtu doesn't need to be public anymore config.Mtu = GetDefaultNetworkMtu() } // Check for mutually incompatible config options if config.BridgeIface != "" && config.BridgeIP != "" { return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.") } if !config.EnableIptables && !config.InterContainerCommunication { return nil, fmt.Errorf("You specified --iptables=false with --icc=false.
ICC uses iptables to function. Please set --icc or --iptables to true.") } // FIXME: DisableNetworkBidge doesn't need to be public anymore config.DisableNetwork = config.BridgeIface == DisableNetworkBridge // Claim the pidfile first, to avoid any and all unexpected race conditions. // Some of the init doesn't need a pidfile lock - but let's not try to be smart. if config.Pidfile != "" { if err := utils.CreatePidFile(config.Pidfile); err != nil { return nil, err } eng.OnShutdown(func() { // Always release the pidfile last, just in case utils.RemovePidFile(config.Pidfile) }) } |
2.Ñé֤ϵͳ֧³Ö¶ÈÒÔ¼°Ö´ÐÐÓû§µÄȨÏÞ
// Check that the system is supported and we have sufficient privileges // FIXME: return errors instead of calling Fatal if runtime.GOOS != "linux" { log.Fatalf("The Docker daemon is only supported on linux") } if os.Geteuid() != 0 { log.Fatalf("The Docker daemon needs to be run as root") } if err := checkKernelAndArch(); err != nil { log.Fatalf(err.Error()) } |
3.ÅäÖûò´´½¨DockerËùÐèÒªµÄ¹¤×÷·¾¶
// set up the TempDir to use a canonical path tmp, err := utils.TempDir(config.Root) if err != nil { log.Fatalf("Unable to get the TempDir under %s: %s", config.Root, err) } realTmp, err := utils.ReadSymlinkedDirectory(tmp) if err != nil { log.Fatalf("Unable to get the full path to the TempDir (%s): %s", tmp, err) } os.Setenv("TMPDIR", realTmp) if !config.EnableSelinuxSupport { selinuxSetDisabled() } // get the canonical path to the Docker root directory var realRoot string if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) { realRoot = config.Root } else { realRoot, err = utils.ReadSymlinkedDirectory(config.Root) if err != nil { log.Fatalf("Unable to get the full path to root (%s): %s", config.Root, err) } } config.Root = realRoot // Create the root directory if it doesn't exists if err := os.MkdirAll(config.Root, 0700); err != nil && !os.IsExist(err) { return nil, err } |
4.ÉèÖÃÒÔ¼°¼ÓÔØ¶àÖÖdriver
// Set the default driver graphdriver.DefaultDriver = config.GraphDriver // Load storage driver driver, err := graphdriver.New(config.Root, config.GraphOptions) if err != nil { return nil, err } log.Debugf("Using graph driver %s", driver) // As Docker on btrfs and SELinux are incompatible at present, error on both being enabled if config.EnableSelinuxSupport && driver.String() == "btrfs" { return nil, fmt.Errorf("SELinux is not supported with the BTRFS graph driver!") }
|
5.´´½¨Docker ImageËùÐèÒªµÄgraph,graphdb,volumnsµÈ
log.Debugf("Creating images graph") g, err := graph.NewGraph(path.Join(config.Root, "graph"), driver) if err != nil { return nil, err } // We don't want to use a complex driver like aufs or devmapper // for volumes, just a plain filesystem volumesDriver, err := graphdriver.GetDriver("vfs", config.Root, config.GraphOptions) if err != nil { return nil, err } log.Debugf("Creating volumes graph") volumes, err := graph.NewGraph(path.Join(config.Root, "volumes"), volumesDriver) if err != nil { return nil, err } log.Debugf("Creating repository list") repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g) if err != nil { return nil, fmt.Errorf("Couldn't create Tag store: %s", err) ¡¡ graphdbPath := path.Join(config.Root, "linkgraph.db") graph, err := graphdb.NewSqliteConn(graphdbPath) if err != nil { return nil, err } |
6.¹ØÓÚdockerinitµÄһϵÁвÙ×÷
localCopy := path.Join(config.Root, "init", fmt.Sprintf("dockerinit-%s", dockerversion.VERSION)) sysInitPath := utils.DockerInitPath(localCopy) if sysInitPath == "" return nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly.
See http://docs.docker.com/contributing/devenvironment for official build instructions.") } |
7.ÑéÖ¤DNS£¬ÅжÏdocker containerÊÇ·ñ¿ÉÒÔʹÓÃhostµÄresolv.confÎļþ£¬Èô²»Äܵϰ£¬Ê¹ÓÃĬÈϵÄÍâ½çDNS
server£º¡°8.8.8.8¡±ºÍ¡°8.8.4.4¡±£»
if err := daemon.checkLocaldns(); err != nil { return nil, err } |
8.ÖØÐ¼ÓÔØÖ®Ç°µÄdocker container¡£ÀýÈ磬µ±Docker½ø³ÌÖØÆôºó£¬»árestore֮ǰÔËÐÐ×ŵÄdocker
container¡£
if err := daemon.restore(); err != nil { return nil, err } |
9.×îÖÕ·µ»Ødaemon¶ÔÏó
ÒÔÉϵÄ9¸ö²½ÖèÖ´ÐÐÍêNewDaemonFromDirectoryÖ®ºó£¬ÔÚgoroutineÖ®¼äÖ´ÐÐd.Install(eng)£¬¸Ã·½·¨µÄʵÏÖλÓÚ./daemon/daemon.goÖеÄInstall·½·¨£¬¹¦ÄÜÊÇΪengine×¢²áÖÚ¶àµÄhandler£¬handlerµÄactionsλÓÚ./daemon/ϵÄÖÚ¶àgoÎļþÖС£ÀýÈçÓÐÒÔÏÂ{"create":
daemon.ContainerCreate}handler£¬Ôòµ±jobµÄÃû³ÆÎªcreateʱ£¬ÔËÐÐʱµÄactionΪdaemon.ContainerCreate,
λÓÚ./daemon/create.go¡£
builderJob.Install()
ËæºóÖ´ÐдúÂëΪ£º
b := &builder.BuilderJob{eng, d} b.Install() |
Õⲿ·ÖÄÚÈݵŦÄÜΪע²ábuildµÄhandler£¬Î»ÓÚ./builder/job.goÎļþÖУ¬jobµÄÃû³ÆÎª¡°build¡±£¬´¦Àí·½·¨ÎªCmdBuild¾ßÌåʵÏÖÈçÏ£º
func (b *BuilderJob) Install() { b.Engine.Register("build", b.CmdBuild) } |
eng.Job("acceptconnections").Run()
goroutineµÄ×îºóÒ»¸ö²½Öè¾ÍÊÇ¿ªÊ¼Ö´ÐнÓÊÕÇëÇ󣬼´Ö´ÐÐÃû³ÆÎª¡°acceptconnections¡±µÄjob£¬´¦Àí·½·¨Îª./api/server/server.goÖеÄAcceptConnections¡£
ÒÔÉϵIJ¿·Ö£¬¼´±íʾgoroutineµÄÔËÐÐÁ÷³Ì,¼´¼ÓÔØdaemonµÄÔËÐÐÁ÷³Ì¡£
eng.Job("serveapi", flHosts...).Run()
ÔÚgoroutineÔËÐеÄͬʱ£¬mainDaemonͬʱ»¹ÔÚÖ´ÐÐÃû³ÆÎª¡°serveapi¡°µÄjob£¬´úÂëÈçÏ£º
// Serve api job := eng.Job("serveapi", flHosts...) job.SetenvBool("Logging", true) job.SetenvBool("EnableCors", *flEnableCors) job.Setenv("Version", dockerversion.VERSION) job.Setenv("SocketGroup", *flSocketGroup) job.SetenvBool("Tls", *flTls) job.SetenvBool("TlsVerify", *flTlsVerify) job.Setenv("TlsCa", *flCa) job.Setenv("TlsCert", *flCert) job.Setenv("TlsKey", *flKey) job.SetenvBool("BufferRequests", true) if err := job.Run(); err != nil { log.Fatal(err) } |
ÔÚ´´½¨jobµÄͬʱ£¬Ê¹Óõ½Á˲ÎÊýflHost£¬Ò²¾ÍÊÇÔÚmainDaemon֮ǰµÄ»ñÈ¡µÄflHost¡£ÓÉÓÚÔÚ./builtins/builtins.goÖÐ×¢²áÁËÃû³ÆÎª¡°serveapi¡±µÄhandler£¬ËùÒÔÖ»ÒªÔËÐÐÏàÓ¦µÄ´¦Àí·½·¨¼´¿É£¬Îª./api/server/server.goÖеÄServeApi·½·¨¡£
×ܽá
ÒÔÉϵķÖÎö¶¼ÊǼÙÉèflDaemonÎªÕæ£¬ÄÇÑùµÄ»°DockerµÄÆô¶¯Á÷³Ì¾Í½áÊøÁË¡£
ÓÉÓÚDockerÖÐËùÓйØÓÚcontainerÒÔ¼°imageµÈ¹¤×÷¶¼±ØÐ뱩¶Ϊһ¸öjob£¬Òò´ËDockerÆô¶¯µÄÍê±Ï±êÖ¾£¬¿ÉÒÔÈÏΪÊÇDockerÍê³ÉserverµÄÆô¶¯£¬²¢×îÖÕΪͨ¹ýapiÀ´·ÃÎʵÄÇëÇó½øÐзþÎñ¡£Í¨¹ýserverÀ´´úÀíÇëÇ󣬲¢×îÖÕ·Ö·¢µ½ÏàÓ¦µÄjobÉÏÀ´Ö´ÐС£
ÔÚDockerÕû¸öÆô¶¯¹ý³ÌÖУ¬±ÊÕßÈÏΪ×îÎªÖØÒª£¬×îΪºËÐĵIJ¿·ÖΪNewDaemonFromDirectoryµÄʵÏÖ£¬¸Ã²¿·ÖÅäÖÃÁËÖÚ¶àDaemon½á¹¹ÄÚ²¿µÄÊôÐÔ£¬¶øÕâЩÊôÐÔÔÚÖ®ºó£¬¶¼»áÉæ¼°µ½ºÜ¶àʵ¼Ê²Ù×÷containerÒÔ¼°graphµÄ¹¤×÷£¬»»ÑÔÖ®£¬daemon±£ÁôÁËÆäËûÄ£¿éµÄ·ÃÎʽӿڡ£
Òò´Ë£¬ÔÚDockerÄÚ²¿£¬ÔËÐп¿engine£¬Ö´Ðп¿job£¬·ÃÎÊdriverµÈ¿¿daemon¡£ |