Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
DockerÔ´Âë·ÖÎö--Docker DaemonµÄÆô¶¯
 
×÷Õß shlallenµÄ²©¿Í£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-10-20
  3638  次浏览      30
 

ÔÚÉÏÎÄÖУ¬±ÊÕßͨ¹ý·ÖÎö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¶ÔÏó

return daemon, nil  

ÒÔÉϵÄ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¡£

   
3638 ´Îä¯ÀÀ       30
 
Ïà¹ØÎÄÕÂ

ÔÆ¼ÆËãµÄ¼Ü¹¹
¶ÔÔÆ¼ÆËã·þÎñÄ£ÐÍ
ÔÆ¼ÆËãºËÐļ¼ÊõÆÊÎö
Á˽âÔÆ¼ÆËãµÄ©¶´
 
Ïà¹ØÎĵµ

ÔÆ¼ÆËã¼ò½é
ÔÆ¼ÆËã¼ò½éÓëÔÆ°²È«
ÏÂÒ»´úÍøÂç¼ÆËã--ÔÆ¼ÆËã
ÈídzÎöÔÆ¼ÆËã
 
Ïà¹Ø¿Î³Ì

ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ
ÔÆ¼ÆËãÓ¦ÓÃÓ뿪·¢
CMMIÌåϵÓëʵ¼ù
»ùÓÚCMMI±ê×¼µÄÈí¼þÖÊÁ¿±£Ö¤
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

ר¼ÒÊӽǿ´ITÓë¼Ü¹¹
Èí¼þ¼Ü¹¹Éè¼Æ
ÃæÏò·þÎñÌåϵ¼Ü¹¹ºÍÒµÎñ×é¼þµÄ˼¿¼
ÈËÈËÍøÒÆ¶¯¿ª·¢¼Ü¹¹
¼Ü¹¹¸¯»¯Ö®ÃÕ
̸ƽ̨¼´·þÎñPaaS
Ïà¹ØÅàѵ¿Î³Ì

ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ
Windows Azure ÔÆ¼ÆËãÓ¦ÓÃ

ĦÍÐÂÞÀ­ ÔÆÆ½Ì¨µÄ¹¹½¨ÓëÓ¦ÓÃ
ͨÓù«Ë¾GE DockerÔ­ÀíÓëʵ¼ù
ijÑз¢ÖÐÐÄ Openstackʵ¼ù
ÖªÃûµç×Ó¹«Ë¾ ÔÆÆ½Ì¨¼Ü¹¹ÓëÓ¦ÓÃ
ijµçÁ¦ÐÐÒµ »ùÓÚÔÆÆ½Ì¨¹¹½¨ÔÆ·þÎñ
ÔÆ¼ÆËãÓëWindows AzureÅàѵ
±±¾© ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ