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

1Ôª 10Ôª 50Ôª





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



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
DockerÔ´Âë·ÖÎö£¨Ê®£©£ºDocker¾µÏñÏÂÔØ
 
×÷Õß ËïºêÁÁ  À´Ô´£ºinfoq »ðÁú¹ûÈí¼þ  ·¢²¼ÓÚ 2015-4-15
  4437  次浏览      27
 

1.ǰÑÔ

˵Docker ImageÊÇDockerÌåϵµÄ¼ÛÖµËùÔÚ£¬Ã»ÓÐË¿ºÁµÃ¿ä´óÆä´Ê¡£Docker Image×÷ΪÈÝÆ÷ÔËÐл·¾³µÄ»ùʯ£¬³¹µ×½â·ÅÁËDockerÈÝÆ÷´´½¨µÄÉúÃüÁ¦£¬Ò²¼¤·¢ÁËÓû§¶ÔÓÚÈÝÆ÷ÔËÓõÄÎÞÏÞÏëÏóÁ¦¡£

Íæ×ªDocker£¬±ØÈ»Àë²»¿ªDocker ImageµÄÖ§³Ö¡£È»¶ø¡°ÍòÎï½ÔÓÐÔ´¡±£¬Docker ImageÀ´×Ժη½£¬Docker ImageÓÖÊÇͨ¹ýºÎÖÖ;¾¶´«Êäµ½Óû§»úÆ÷£¬ÒÔÖÂÓû§¿ÉÒÔͨ¹ýDocker Image´´½¨ÈÝÆ÷£¿»ØÒä³õ´Î½Ó´¥DockerµÄ³¡¾°£¬´ó¼Ò¿Ï¶¨¶ÔÁ½ÌõÃüÁİÉú£ºdocker pullºÍdocker run¡£ÕâÁ½ÌõÃüÁîÖУ¬ÕýÊÇǰÕßʵÏÖÁËDocker ImageµÄÏÂÔØ¡£Docker DaemonÔÚÖ´ÐÐÕâÌõÃüÁîʱ£¬»á½«Docker Image´ÓDocker RegistryÏÂÔØÖÁ±¾µØ£¬²¢±£´æÔÚ±¾µØDocker Daemon¹ÜÀíµÄgraphÖС£

̸¼°Docker Registry£¬Docker°®ºÃÕßÊ×ÏÈÁªÏëµ½µÄ×ÔÈ»ÊÇDocker Hub¡£Docker Hub×÷ΪDocker¹Ù·½Ö§³ÖµÄDocker Registry£¬ÓµÓÐÈ«Çò³ÉǧÉÏÍòµÄDocker Image¡£È«ÇòµÄDocker°®ºÃÕß³ýÁË¿ÉÒÔÏÂÔØDocker Hub¿ª·ÅµÄ¾µÏñ×ÊÔ´Ö®Í⣬»¹¿ÉÒÔÏòDocker Hub¹±Ï×¾µÏñ×ÊÔ´¡£ÔÚDocker HubÉÏ£¬Óû§²»½ö¿ÉÒÔÏíÊܹ«ÓоµÏñ´øÀ´µÄ±ãÀû£¬¶øÇÒ¿ÉÒÔ´´½¨Ë½ÓоµÏñ¿â¡£Docker HubÊÇÈ«¹ú×î´óµÄPublic Registry£¬ÁíÍâDocker»¹Ö§³ÖÓû§×Ô¶¨Òå´´½¨Private Registry¡£Private RegistryÖ÷ÒªµÄ¹¦ÄÜÊÇΪ˽ÓÐÍøÂçÌṩDocker¾µÏñµÄרÊô·þÎñ£¬Ò»°ã¶øÑÔ£¬¾µÏñÖÖÀàÊÊÓ¦Óû§ÐèÇó£¬Ë½ÃÜÐԽϸߣ¬ÇÒ²»»áÕ¼Óù«ÓÐÍøÂç´ø¿í¡£

2.±¾ÎÄ·ÖÎöÄÚÈݰ²ÅÅ

±¾ÎÄ×÷Ϊ¡¶DockerÔ´Âë·ÖÎö¡·ÏµÁеĵÚʮƪ¡ª¡ªDocker¾µÏñÏÂÔØÆª£¬Ö÷Òª´ÓÔ´ÂëµÄ½Ç¶È·ÖÎöDockerÏÂÔØDocker ImageµÄ¹ý³Ì¡£·ÖÎöÁ÷³ÌÖУ¬dockerµÄ°æ±¾¾ùΪ1.2.0¡£

·ÖÎöÄÚÈݵݲÅÅÈçÒÔÏÂ4²¿·Ö£º

(1) ¸ÅÊöDocker¾µÏñÏÂÔØµÄÁ÷³Ì£¬Éæ¼°Docker Client¡¢Docker ServerÓëDocker Daemon£»

(2) Docker Client´¦Àí²¢·¢ËÍdocker pullÇëÇó£»

(3) Docker Server½ÓÊÕdocker pullÇëÇ󣬲¢´´½¨¾µÏñÏÂÔØÈÎÎñ²¢´¥·¢Ö´ÐУ»

(4) Docker DaemonÖ´ÐоµÏñÏÂÔØÈÎÎñ£¬²¢´æ´¢¾µÏñÖÁgraph¡£

3.Docker¾µÏñÏÂÔØÁ÷³Ì

Docker Image×÷ΪDockerÉú̬Öеľ«Ë裬ÏÂÔØ¹ý³ÌÖÐÐèÒªDocker¼Ü¹¹Öжà¸ö×é¼þµÄЭ×÷¡£Docker¾µÏñµÄÏÂÔØÁ÷³ÌÈçͼ3.1£º


ͼ3.1 Docker¾µÏñÏÂÔØÁ÷³Ìͼ

ÈçÉÏͼ£¬ÏÂÔØÁ÷³Ì£¬¿ÉÒÔ¹éÄÉΪÒÔÉÏ3¸ö²½Ö裺

(1) Óû§Í¨¹ýDocker Client·¢ËÍpullÇëÇó£¬×÷ÓÃΪ£ºÈÃDocker DaemonÏÂÔØÖ¸¶¨Ãû³ÆµÄ¾µÏñ£»

(2) Docker DaemonÖиºÔðDocker APIÇëÇóµÄDocker Server£¬½ÓÊÕDocker¾µÏñµÄpullÇëÇ󣬴´½¨ÏÂÔØ¾µÏñÈÎÎñ²¢´¥·¢Ö´ÐУ»

(3) Docker DaemonÖ´ÐоµÏñÏÂÔØÈÎÎñ£¬´ÓDocker RegistryÖÐÏÂÔØÖ¸¶¨¾µÏñ£¬²¢½«Æä´æ´¢Óë±¾µØµÄgraphÖС£

ÏÂÎļ´´ÓÈý¸ö·½Ãæ·ÖÎödocker pullÇëÇóÖ´ÐеÄÁ÷³Ì¡£

4.Docker Client

Docker¼Ü¹¹ÖУ¬DockerÓû§µÄ½ÇÉ«¾ø´ó¶àÊýÓÉDocker ClientÀ´°çÑÝ¡£Òò´Ë£¬Óû§¶ÔDockerµÄ¹ÜÀíÇëÇóÈ«²¿ÓÉDocker ClientÀ´·¢ËÍ£¬Docker¾µÏñÏÂÔØÇëÇó×ÔȻҲ²»ÀýÍâ¡£

ΪÁ˸üÇåÎúµÄÃèÊöDocker¾µÏñÏÂÔØ£¬±¾ÎĽáºÏ¾ßÌåµÄÃüÁî½øÐзÖÎö£¬ÈçÏ£º

docker pull ubuntu:14.04

ÒÔÉϵÄÃüÁî´ú±í£ºÓû§Í¨¹ýdocker¶þ½øÖÆ¿ÉÖ´ÐÐÎļþ£¬Ö´ÐÐpullÃüÁ¾µÏñ²ÎÊýΪubuntu:14.04£¬¾µÏñÃû³ÆÎªubuntu£¬¾µÏñ±êǩΪ14.04¡£´ËÃüÁîÒ»¾­´¥·¢£¬µÚÒ»¸ö½ÓÊܲ¢´¦ÀíµÄDocker×é¼þΪDocker Client£¬Ö´ÐÐÄÚÈݰüÀ¨ÒÔÏÂÈý¸ö²½Ö裺

(1) ½âÎöÃüÁîÖÐÓëDocker¾µÏñÏà¹ØµÄ²ÎÊý£»

(2) ÅäÖÃDockerÏÂÔØ¾µÏñʱËùÐèµÄÈÏÖ¤ÐÅÏ¢£»

(3) ·¢ËÍRESTfulÇëÇóÖÁDocker Daemon¡£

4.1 ½âÎö¾µÏñ²ÎÊý

ͨ¹ýdocker¶þ½øÖÆÎļþÖ´ÐÐdocker pull ubuntu:14.04 ʱ£¬Docker ClientÊ×ÏȻᱻ´´½¨£¬Ëæºóͨ¹ý²ÎÊý´¦Àí·ÖÎö³öÇëÇóÀàÐÍpull£¬×îÖÕÖ´ÐÐpullÇëÇóÏàÓ¦µÄ´¦Àíº¯Êý¡£¹ØÓÚDocker ClientµÄ´´½¨ÓëÃüÁîÖ´ÐпÉÒԲμû¡¶DockerÔ´Âë·ÖÎö¡·ÏµÁеڶþƪ¡ª¡ªDocker Clientƪ¡£

Docker ClientÖ´ÐÐpullÇëÇóÏàÓ¦µÄ´¦Àíº¯Êý£¬Ô´ÂëλÓÚ./docker/api/client/command.go#L1183-L1244£¬ÓйØÌáÈ¡¾µÏñ²ÎÊýµÄÔ´ÂëÈçÏ£º

func (cli *DockerCli) CmdPull(args ...string) error {
cmd := cli.Subcmd("pull", "NAME[:TAG]", "Pull an image or a repository from the registry")
tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in a repository")
if err := cmd.Parse(args); err != nil {
return nil
}

if cmd.NArg() != 1 {
cmd.Usage()
return nil
}
var (
v = url.Values{}
remote = cmd.Arg(0)
)

v.Set("fromImage", remote)

if *tag == "" {
v.Set("tag", *tag)
}

remote, _ = parsers.ParseRepositoryTag(remote)
// Resolve the Repository name from fqn to hostname + name
hostname, _, err := registry.ResolveRepositoryName(remote)
if err != nil {
return err
}
¡­¡­
}

½áºÏÃüÁîdocker pull ubuntu:14.04£¬À´·ÖÎöCmdPullº¯ÊýµÄ¶¨Ò壬¿ÉÒÔ·¢ÏÖ£¬¸Ãº¯Êý´«ÈëµÄÐβÎΪargs£¬Êµ²ÎÖ»ÓÐÒ»¸ö×Ö·û´®ubuntu:14.04¡£ÁíÍ⣬×ݹÛÒÔÉÏÔ´Â룬¿ÉÒÔ·¢ÏÖDocker Client½âÎöµÄ¾µÏñ²ÎÊýÎÞÍâºõ4¸ö£ºtag¡¢remote¡¢vºÍhostname£¬ËÄÕ߸÷×ÔµÄ×÷ÓÃÈçÏ£º

  • tag£º´øÓÐDocker¾µÏñµÄ±êÇ©£»
  • remote£º´øÓÐDocker¾µÏñµÄÃû³ÆÓë±êÇ©£»
  • v£ºÀàÐÍΪurl.Values£¬ÊµÖÊÊÇÒ»¸ömapÀàÐÍ£¬ÓÃÓÚÅäÖÃÇëÇóÖÐURLµÄ²éѯ²ÎÊý£»
  • hostname£ºDocker RegistryµÄµØÖ·£¬´ú±íÓû§Ï£Íû´ÓÖ¸¶¨µÄDocker RegistryÏÂÔØDocker¾µÏñ¡£

4.1.1 ½âÎötag²ÎÊý

Docker¾µÏñµÄtag²ÎÊý£¬ÊǵÚÒ»¸ö±»Docker Client½âÎöµÄ¾µÏñ²ÎÊý£¬´ú±íÓû§ËùÐèÏÂÔØDocker¾µÏñµÄ±êÇ©ÐÅÏ¢£¬È磺docker pull ubuntu:14.04ÇëÇóÖоµÏñµÄtagÐÅϢΪ14.04£¬ÈôÓû§Ê¹ÓÃdocker pull ubuntuÇëÇóÏÂÔØ¾µÏñ£¬Ã»ÓÐÏÔÐÔÖ¸¶¨tagÐÅϢʱ£¬Docker Client»áĬÈϸþµÏñµÄtagÐÅϢΪlatest¡£

Docker 1.2.0°æ±¾³ýÁËÒÔÉϵÄtagÐÅÏ¢´«È뷽ʽ£¬ÒÀ¾É±£Áô×Å´ú±í¾µÏñ±êÇ©µÄflag²ÎÊýtag£¬¶øÕâ¸öflag²ÎÊýÔÚ1.2.0°æ±¾µÄʹÓùý³ÌÖÐÒѾ­±»ÒÅÆú£¬²¢»áÔÚÖ®ºóа汾µÄDockerÖб»ÒƳý£¬Òò´ËÔÚʹÓÃdocker 1.2.0°æ±¾ÏÂÔØDocker¾µÏñʱ£¬²»½¨ÒéʹÓÃflag²ÎÊýtag¡£´«ÈëtagÐÅÏ¢µÄ·½Ê½£¬½¨ÒéʹÓÃdocker pull NAME[:TAG]µÄÐÎʽ¡£

Docker 1.2.0°æ±¾ÒÀ¾É±£ÁôµÄflag²ÎÊýtag£¬Æä¶¨ÒåÓë½âÎöµÄÔ´ÂëλÓÚ£º./docker/api/client/commands.go#1185-L1188£¬ÈçÏ£º

tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in a repository")
if err := cmd.Parse(args); err != nil {
return nil
}

ÒÔÉϵÄÔ´Âë˵Ã÷£ºCmdPullº¯Êý½âÎötag²ÎÊýʱ£¬Docker ClientÊ×Ïȶ¨ÒåÒ»¸öflag²ÎÊý£¬flag²ÎÊýµÄÃû³ÆÎª¡±#t¡±»òÕß ¡°#-tag¡±£¬ÓÃ;Ϊ£ºÖ¸¶¨Docker¾µÏñµÄtag²ÎÊý£¬Ä¬ÈÏֵΪ¿Õ×Ö·û´®£»Ëæºóͨ¹ýcmd.Parse(args)µÄÖ´ÐУ¬½âÎöargsÖеÄtag²ÎÊý¡£

4.1.2 ½âÎöremote²ÎÊý

Docker Client½âÎöÍêtag²ÎÊýÖ®ºó£¬Í¬ÑùÐèÒª½âÎö³öDocker¾µÏñËùÊôµÄrepository£¬ÈçÇëÇódocker pull ubuntu:14.04ÖУ¬Docker¾µÏñΪubuntu:14.04£¬¾µÏñµÄrepositoryÐÅϢΪubuntu£¬¾µÏñµÄtagÐÅϢΪ14.04¡£

Docker Clientͨ¹ý½âÎöremote²ÎÊý£¬Ê¹µÃremote²ÎÊýЯ´ørepositoryÐÅÏ¢ºÍtagÐÅÏ¢¡£Docker Client½âÎöremote²ÎÊýµÄµÚÒ»¸ö²½Ö裬ԴÂëÈçÏ£º

remote = cmd.Arg(0)

ÆäÖУ¬cmdµÄµÚÒ»¸ö²ÎÊý¸³Öµ¸øremote£¬ÒÔdocker pull ubuntu:14.04ΪÀý£¬cmd.Arg(0)Ϊubuntu:14.04£¬Ôò¸³ÖµºóremoteֵΪubuntu:14.04¡£´Ëʱremote²ÎÊý¼´°üº¬Docker¾µÏñµÄrepositoryÐÅÏ¢Ò²°üº¬tagÐÅÏ¢¡£ÈôÓû§ÇëÇóÖдøÓÐDocker RegistryµÄÐÅÏ¢£¬Èçdocker pull localhost.localdomain:5000/docker/ubuntu:14.04£¬cmd.Arg(0)Ϊlocalhost.localdomain:5000/docker/ubuntu:14.04£¬Ôò¸³ÖµºóremoteֵΪlocalhost.localdomain:5000/docker/ubuntu:14.04£¬´Ëʱremote²ÎÊýͬʱ°üº¬repositoryÐÅÏ¢¡¢tagÐÅÏ¢ÒÔ¼°Docker RegistryÐÅÏ¢¡£

Ëæºó£¬ÔÚ½âÎöremote²ÎÊýµÄµÚ¶þ¸ö²½ÖèÖУ¬Docker Clientͨ¹ý½âÎö¸³ÖµÍê±ÏµÄremote²ÎÊý£¬´ÓÖнâÎöÖÐrepositoryÐÅÏ¢£¬²¢Ôٴθ²Ð´remote²ÎÊýµÄÖµ£¬Ô´ÂëÈçÏ£º

remote, _ = parsers.ParseRepositoryTag(remote)

ParseRepositoryTagµÄ×÷ÓÃÊÇ£º½âÎö³öremote²ÎÊýµÄrepositoryÐÅÏ¢ºÍtagÐÅÏ¢£¬¸Ãº¯ÊýµÄʵÏÖλÓÚ./docker/pkg/parsers/parsers.go#L72-L81£¬Ô´ÂëÈçÏÂ:

func ParseRepositoryTag(repos string) (string, string) {
n := strings.LastIndex(repos, ":")
if n < 0 {
return repos, ""
}
if tag := repos[n+1:]; !strings.Contains(tag, "/") {
return repos[:n], tag
}
return repos, ""
}

ÒÔÉϺ¯ÊýµÄʵÏÖ¹ý³Ì£¬³ä·Ö¿¼ÂÇÁ˶àÖÖ²»Í¬Docker RegistryµÄÇé¿ö£¬È磺ÇëÇódocker pull ubuntu:14.04ÖÐremote²ÎÊýΪubuntu:14.04£¬¶øÇëÇódocker pull localhost.localdomain:5000/docker/ubuntu:14.04ÖÐÓû§Ö¸¶¨ÁËDocker RegistryµÄµØÖ·localhost.localdomain:5000/docker£¬¹Êremote²ÎÊý»¹Ð¯´øÁËDocker RegistryÐÅÏ¢¡£

ParseRepositoryTagº¯ÊýÊ×ÏÈ´Órepos²ÎÊýµÄβ²¿ÍùǰѰÕÒ¡±:¡±£¬Èô²»´æÔÚ£¬Ôò˵Ã÷Óû§Ã»ÓÐÏÔÐÔÖ¸¶¨Docker¾µÏñµÄtag£¬·µ»ØÕû¸örepos×÷ΪDocker¾µÏñµÄrepository£»Èô¡±:¡±´æÔÚ£¬Ôò˵Ã÷Óû§ÏÔÐÔÖ¸¶¨ÁËDocker¾µÏñµÄtag£¬¡±:¡±Ç°µÄÄÚÈÝ×÷ΪrepositoryÐÅÏ¢£¬¡±:¡±ºóµÄÄÚÈÝ×÷ΪtagÐÅÏ¢£¬²¢·µ»ØÁ½Õß¡£

ParseRepositoryTagº¯ÊýÖ´ÐÐÍ꣬»Øµ½CmdPullº¯Êý£¬·µ»ØÄÚÈݵÄrepositoryÐÅÏ¢½«¸²Ð´remote²ÎÊý¡£¶ÔÓÚÇëÇódocker pull localhost.localdomain:5000/docker/ubuntu:14.04£¬remote²ÎÊý±»¸²Ð´ºó£¬ÖµÎªlocalhost.localdomain:5000/docker/ubuntu£¬Ð¯´øDocker RegistryÐÅÏ¢ÒÔ¼°repositoryÐÅÏ¢¡£

4.1.3 ÅäÖÃurl.Values

Docker Client·¢ËÍÇëÇó¸øDocker Serverʱ£¬ÐèҪΪÇëÇóÅäÖÃURLµÄ²éѯ²ÎÊý¡£CmdPullº¯ÊýµÄÖ´Ðйý³ÌÖд´½¨url.Value²¢ÅäÖõÄÔ´ÂëʵÏÖλÓÚ./docker/api/client/commands.go#L1194-L1203£¬ÈçÏ£º

var (
v = url.Values{}
remote = cmd.Arg(0)
)

v.Set("fromImage", remote)

if *tag == "" {
v.Set("tag", *tag)
}

ÆäÖУ¬±äÁ¿vµÄÀàÐÍurl.Values£¬ÅäÖõÄURL²éѯ²ÎÊýÓÐÁ½¸ö£¬·Ö±ðΪ¡±fromImage¡±Ó롱tag¡±£¬¡±fromImage¡±µÄÖµÊÇremote²ÎÊýûÓб»¸²Ð´Ê±Öµ£¬¡±tag¡±µÄÖµÒ»°ãΪ¿Õ£¬Ô­ÒòÊÇÒ»°ã²»Ê¹ÓÃflag²ÎÊýtag¡£

4.1.4 ½âÎöhostname²ÎÊý

Docker Client½âÎö¾µÏñ²ÎÊýʱ£¬»¹ÓÐÒ»¸öÖØÒªµÄ»·½Ú£¬ÄǾÍÊǽâÎöDocker RegistryµÄµØÖ·ÐÅÏ¢¡£ÕâÒâζ×ÅÓû§Ï£Íû´ÓÖ¸¶¨µÄDocker RegistryÖÐÏÂÔØDocker¾µÏñ¡£

½âÎöDocker RegistryµØÖ·µÄ´úÂëʵÏÖλÓÚ./docker/api/client/commands.go#L1207£¬ÈçÏ£º

hostname, _, err := registry.ResolveRepositoryName(remote)

Docker Clientͨ¹ý°üregistryÖеĺ¯ÊýResolveRepositoryNameÀ´½âÎöhostname²ÎÊý£¬´«ÈëµÄʵ²ÎΪremote£¬¼´È¥tag»¯µÄremote²ÎÊý¡£ResolveRepositoryNameº¯ÊýµÄʵÏÖλÓÚ./docker/registry/registry.go#L237-L259£¬ÈçÏ£º

func ResolveRepositoryName(reposName string) (string, string, error) {
if strings.Contains(reposName, "://") {
// It cannot contain a scheme!
return "", "", ErrInvalidRepositoryName
}
nameParts := strings.SplitN(reposName, "/", 2)
if len(nameParts) == 1
|| (!strings.Contains(nameParts[0], ".") && !strings.Contains(nameParts[0], ":") &&
nameParts[0] != "localhost") {
// This is a Docker Index repos (ex: samalba/hipache or ubuntu)
err := validateRepositoryName(reposName)
return IndexServerAddress(), reposName, err
}
hostname := nameParts[0]
reposName = nameParts[1]
if strings.Contains(hostname, "index.docker.io") {
return "", "", fmt.Errorf("Invalid repository name, try \"%s\" instead", reposName)
}
if err := validateRepositoryName(reposName); err != nil {
return "", "", err
}

return hostname, reposName, nil
}

ResolveRepositoryNameº¯ÊýÊ×ÏÈͨ¹ý¡±/¡±·Ö¸î×Ö·û´®reposName£¬ÈçÏ£º

nameParts := strings.SplitN(reposName, "/", 2)

Èç¹ûnamePartsµÄ³¤¶ÈΪ1£¬Ôò˵Ã÷reposNameÖв»º¬ÓÐ×Ö·û¡±/¡±£¬Òâζ×ÅÓû§Ã»ÓÐÖ¸¶¨Docker Registry¡£ÁíÍ⣬ÐÎÈ硱samalba/hipache¡±µÄreposNameͬÑù˵Ã÷Óû§²¢Ã»ÓÐÖ¸¶¨Docker Registry¡£µ±Óû§Ã»ÓÐÖ¸¶¨Docker Registryʱ£¬Docker ClientĬÈÏ·µ»ØIndexServerAddress()£¬¸Ãº¯Êý·µ»Ø³£Á¿INDEXSERVER£¬ÖµÎª¡±https://index.docker.io/v1¡±¡£Ò²¾ÍÊÇ˵£¬µ±Óû§ÏÂÔØDocker¾µÏñʱ£¬Èô²»Ö¸¶¨Docker Registry£¬Ä¬ÈÏÇé¿öÏ£¬Docker Client֪ͨDocker DaemonÈ¥Docker HubÉÏÏÂÔØ¾µÏñ¡£ÀýÈ磺ÇëÇódocker pull ubuntu:14.04£¬ÓÉÓÚûÓÐÖ¸¶¨Docker Registry£¬Docker ClientĬÈÏʹÓÃÈ«Çò×î´óµÄDocker Registry¡ª¡ªDocker Hub¡£

µ±²»Âú×ã·µ»ØÄ¬ÈÏDocker Registryʱ£¬Docker Clientͨ¹ý½âÎöreposNames£¬µÃ³öÓû§Ö¸¶¨µÄDocker RegistryµØÖ·¡£ÀýÈ磺ÇëÇódocker pull localhost.localdomain:5000/docker/ubuntu:14.04ÖУ¬½âÎö³öµÄDocker RegistryµØÖ·Îªlocalhost.localdomain:5000¡£

ÖÁ´Ë£¬ÓëDocker¾µÏñÏà¹ØµÄ²ÎÊýÒѾ­È«²¿½âÎöÍê±Ï£¬Docker Client½«Ð¯´øÕⲿ·ÖÖØÒªÐÅÏ¢£¬ÒÔ¼°Óû§µÄÈÏÖ¤ÐÅÏ¢£¬¹¹½¨RESTfulÇëÇ󣬷¢Ë͸øDocker Server¡£

4.2 ÅäÖÃÈÏÖ¤ÐÅÏ¢

Óû§ÏÂÔØDocker¾µÏñʱ£¬DockerͬÑùÖ§³ÖÓû§ÐÅÏ¢µÄÈÏÖ¤¡£Óû§ÈÏÖ¤ÐÅÏ¢ÓÉDocker ClientÅäÖã»Docker Client·¢ËÍÇëÇóÖÁDocker Serverʱ£¬Óû§ÈÏÖ¤ÐÅÏ¢Ò²±»Ò»²¢·¢ËÍ£»Ëæºó£¬Docker Daemon´¦ÀíÏÂÔØDocker¾µÏñÇëÇóʱ£¬Óû§ÈÏÖ¤ÐÅÏ¢ÔÚDocker Registry±»ÑéÖ¤¡£

Docker ClientÅäÖÃÓû§ÈÏÖ¤ÐÅÏ¢°üº¬Á½¸ö²½Ö裬ʵÏÖÔ´ÂëÈçÏ£º

cli.LoadConfigFile()
// Resolve the Auth config relevant for this server
authConfig := cli.configFile.ResolveAuthConfig(hostname)

¿É¼û£¬µÚÒ»¸ö²½ÖèÊÇʹcli£¨Docker Client£©¼ÓÔØConfigFile£¬ConfigFileÊÇDocker ClientÓÃÀ´´æ·ÅÓйØDocker RegistryµÄÓû§ÈÏÖ¤ÐÅÏ¢µÄ¶ÔÏó¡£DockerCli¡¢ConfigFileÒÔ¼°AuthConfigÈýÖÖÊý¾Ý½á¹¹Ö®¼äµÄ¹ØÏµÈçͼ4.1£º


ͼ4.1 DockerCli¡¢ConfigFileÒÔ¼°AuthConfig¹ØÏµÍ¼

DockerCli½á¹¹ÌåµÄÊôÐÔconfigFileΪһ¸öÖ¸Ïòregistry.ConfigFileµÄÖ¸Õ룬¶øConfigFile½á¹¹ÌåµÄÊôÐÔConfigsÊôÓÚmapÀàÐÍ£¬ÆäÖÐkeyΪstring£¬´ú±íDocker RegistryµÄµØÖ·£¬valueµÄÀàÐÍΪAuthConfig¡£AuthConfigÀàÐ;ßÌ庬ÒåΪÓû§ÔÚij¸öDocker RegistryÉϵÄÈÏÖ¤ÐÅÏ¢£¬°üº¬Óû§Ãû£¬ÃÜÂ룬ÈÏÖ¤ÐÅÏ¢£¬ÓÊÏ䵨ַµÈ¡£

¼ÓÔØÍêÓû§ËùÓеÄÈÏÖ¤ÐÅÏ¢Ö®ºó£¬Docker ClientµÚ¶þ¸ö²½ÖèÊÇ£ºÍ¨¹ýÓû§Ö¸¶¨µÄDocker Registry£¬¼´Ö®Ç°½âÎö³öµÄhostname²ÎÊý£¬´ÓÓû§ËùÓеÄÈÏÖ¤ÐÅÏ¢ÖÐÕÒ³öÓëÖ¸¶¨hostnameÏàÆ¥ÅäµÄÈÏÖ¤ÐÅÏ¢¡£Ð´´½¨µÄauthConfig£¬ÀàÐͼ´ÎªAuthConfig£¬½«»á×÷ΪÓû§ÔÚÖ¸¶¨Docker RegistryÉϵÄÈÏÖ¤ÐÅÏ¢£¬·¢ËÍÖÁDocker Server¡£

4.3 ·¢ËÍAPIÇëÇó

Docker Client½âÎöÍêËùÓеÄDocker¾µÏñ²ÎÊý£¬²¢ÇÒÅäÖÃÍê±ÏÓû§µÄÈÏÖ¤ÐÅÏ¢Ö®ºó£¬Docker ClientÐèҪʹÓÃÕâЩÐÅÏ¢Õýʽ·¢Ë;µÏñÏÂÔØµÄÇëÇóÖÁDocker Server¡£

Docker Client¶¨ÒåÁËpullº¯Êý£¬À´ÊµÏÖ·¢Ë;µÏñÏÂÔØÇëÇóÖÁDocker Server£¬Ô´ÂëλÓÚ./docker/api/client/commands.go#L1217-L1229£¬ÈçÏ£º

pull := func(authConfig registry.AuthConfig) error {
buf, err := json.Marshal(authConfig)
if err != nil {
return err
}
registryAuthHeader := []string{
base64.URLEncoding.EncodeToString(buf),
}

return cli.stream("POST", "/images/create?"+v.Encode(), nil, cli.out, map[string][]string{
"X-Registry-Auth": registryAuthHeader,
})
}

pullº¯ÊýµÄʵÏÖ½ÏΪ¼òµ¥£¬Ê×ÏÈͨ¹ýauthConfig¶ÔÏ󣬴´½¨registryAuthHeader£¬×îºó·¢ËÍPOSTÇëÇó£¬ÇëÇóµÄURLΪ"/images/create?"+v.Encode()£¬ÔÚURLÖд«Èë²éѯ²ÎÊý°üÀ¨¡±fromImage¡±Ó롱tag¡±£¬ÁíÍâÔÚÇëÇóµÄHTTP HeaderÖÐÌí¼ÓÈÏÖ¤ÐÅÏ¢registryAuthHeader£¬¡£

Ö´ÐÐÒÔÉϵÄpullº¯Êýʱ£¬Docker¾µÏñÏÂÔØÇëÇó±»·¢ËÍ£¬ËæºóDocker ClientµÈ´ýDocker ServerµÄ½ÓÊÕ¡¢´¦ÀíÓëÏìÓ¦¡£

5.Docker Server

Docker Server×÷ΪDocker DaemonµÄÈë¿Ú£¬ËùÓÐDocker Client·¢ËÍÇëÇó¶¼ÓÉDocker Server½ÓÊÕ¡£Docker Serverͨ¹ý½âÎöÇëÇóµÄURLÓëÇëÇó·½·¨£¬×îÖÕ·ÓÉ·Ö·¢ÖÁÏàÓ¦µÄhandlerÀ´´¦Àí¡£Docker ServerµÄ´´½¨ÓëÇëÇó´¦Àí£¬¿ÉÒԲο´¡¶DockerÔ´Âë·ÖÎö¡·ÏµÁÐÖ®Docker Serverƪ¡£

Docker Server½ÓÊÕµ½¾µÏñÏÂÔØÇëÇóÖ®ºó£¬Í¨¹ý·ÓÉ·Ö·¢×îÖÕÓɾßÌåµÄhandler¡ª¡ªpostImagesCreateÀ´´¦Àí¡£postImagesCreateµÄʵÏÖλÓÚ./docker/api/server/server.go#L466-L524£¬µÄ¡¢ÆäÖ´ÐÐÁ÷³ÌÖ÷Òª·ÖΪ3¸ö²¿·Ö£º

(1) ½âÎöHTTPÇëÇóÖаüº¬µÄÇëÇó²ÎÊý£¬°üÀ¨URLÖеIJéѯ²ÎÊý¡¢HTTP headerÖеÄÈÏÖ¤ÐÅÏ¢µÈ£»

(2) ´´½¨¾µÏñÏÂÔØjob£¬²¢Îª¸ÃjobÅäÖû·¾³±äÁ¿£»

(3) ´¥·¢Ö´ÐоµÏñÏÂÔØjob¡£

5.1 ½âÎöÇëÇó²ÎÊý

Docker Server½ÓÊÕµ½Docker Client·¢Ë͵ľµÏñÏÂÔØÇëÇóÖ®ºó£¬Ê×ÏȽâÎöÇëÇó²ÎÊý£¬²¢Î´ºóÐøjobµÄ´´½¨ÓëÔËÐÐÌṩ²ÎÊýÒÀ¾Ý¡£Docker Server½âÎöµÄÇëÇó²ÎÊý£¬Ö÷ÒªÓУºHTTPÇëÇóURLÖеIJéѯ²ÎÊý¡±fromImage¡±¡¢¡±repo¡±ÒÔ¼°¡±tag¡±£¬ÒÔ¼°ÓÐHTTPÇëÇóµÄheaderÖеġ±X-Registry-Auth¡±¡£

ÇëÇó²ÎÊý½âÎöµÄÔ´ÂëÈçÏ£º

var (
image = r.Form.Get("fromImage")
repo = r.Form.Get("repo")
tag = r.Form.Get("tag")
job *engine.Job
)
authEncoded := r.Header.Get("X-Registry-Auth")

ÐèÒªÌØ±ð˵Ã÷µÄÊÇ£ºÍ¨¹ý¡±fromImage¡±½âÎö³öµÄimage±äÁ¿°üº¬¾µÏñrepositoryÃû³ÆÓë¾µÏñtagÐÅÏ¢¡£ÀýÈçÓû§ÇëÇóΪdocker pull ubuntu:14.04£¬ÄÇôͨ¹ý¡±fromImage¡±½âÎö³öµÄimage±äÁ¿ÖµÎªubuntu:14.04£¬²¢·ÇÖ»ÓÐDocker¾µÏñµÄÃû³Æ¡£

ÁíÍ⣬Docker Serverͨ¹ýHTTP headerÖнâÎö³öauthEncoded£¬»¹Ô­³öÀàÐÍΪregistry.AuthConfigµÄ¶ÔÏóauthConfig£¬Ô´ÂëʵÏÖÈçÏ£º

authConfig := ?istry.AuthConfig{}
if authEncoded != "" {
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
authConfig = ?istry.AuthConfig{}
}
}

½âÎö³öHTTPÇëÇóÖеIJÎÊýÖ®ºó£¬Docker Server¶ÔÓÚimage²ÎÊý£¬ÔٴνøÐнâÎö£¬´ÓÖнâÎö³öÊôÓÚrepositoryÓëtagÐÅÏ¢£¬ÆäÖÐrepositoryÓпÉÄÜÔÝʱ°üº¬Docker RegistryÐÅÏ¢£¬Ô´ÂëʵÏÖÈçÏ£º

if tag == "" {
image, tag = parsers.ParseRepositoryTag(image)
}

Docker ServerµÄ²ÎÊý½âÎö¹¤×÷ÖÁ´ËÈ«²¿Íê³É£¬ÔÚÕâÖ®ºóDocker Server½«´´½¨¾µÏñÏÂÔØÈÎÎñ²¢¿ªÊ¼Ö´ÐС£

5.2 ´´½¨²¢ÅäÖÃjob

Docker ServerÖ»¸ºÔð½ÓÊÕDocker Client·¢Ë͵ÄÇëÇ󣬲¢½«Æä·ÓÉ·Ö·¢ÖÁÏàÓ¦µÄhandlerÀ´´¦Àí£¬×îÖÕµÄÇëÇóÖ´Ðл¹ÊÇÐèÒªDocker DaemonÀ´Ð­×÷Íê³É¡£Docker ServerÔÚhandlerÖУ¬Í¨¹ý´´½¨job²¢´¥·¢jobÖ´ÐеÄÐÎʽ£¬°Ñ¿ØÖÆÈ¨½»ÓÚDocker Daemon¡£

Docker Server´´½¨¾µÏñÏÂÔØjob²¢ÅäÖû·¾³±äÁ¿µÄÔ´ÂëʵÏÖÈçÏ£º

job = eng.Job("pull", image, tag)
job.SetenvBool("parallel", version.GreaterThan("1.3"))
job.SetenvJson("metaHeaders", metaHeaders)
job.SetenvJson("authConfig", authConfig)

ÆäÖУ¬´´½¨µÄjobÃûΪpull£¬º¬ÒåÊÇÏÂÔØDocker¾µÏñ£¬´«Èë²ÎÊýΪimageÓëtag£¬ÅäÖõĻ·¾³±äÁ¿ÓÐparallel¡¢metaHeadersÓëauthConfig¡£

5.3 ´¥·¢Ö´ÐÐjob

Docker Server´´½¨ÍêDocker¾µÏñÏÂÔØjobÖ®ºó£¬ÐèÒª´¥·¢Ö´ÐиÃjob£¬ÊµÏÖ½«¿ØÖÆÈ¨½»ÓÚDocker Daemon¡£

Docker Server´¥·¢Ö´ÐÐjobµÄÔ´ÂëÈçÏ£º

if err := job.Run(); err != nil {
if !job.Stdout.Used() {
return err
}
sf := utils.NewStreamFormatter(version.GreaterThan("1.0"))
w.Write(sf.FormatError(err))
}

ÓÉÓÚDocker DaemonÔÚÆô¶¯Ê±£¬ÒѾ­ÅäÖÃÁËÃûΪ¡±pull¡±µÄjobËù¶ÔÓ¦µÄhandler£¬Êµ¼ÊΪgraph°üÖеÄCmdPullº¯Êý£¬¹ÊÒ»µ©¸Ãjob±»´¥·¢Ö´ÐУ¬¿ØÖÆÈ¨½«Ö±½Ó½»ÓÚDocker DaemonµÄCmdPullº¯Êý¡£Docker DaemonÆô¶¯Ê±EngineµÄhandler×¢²á£¬¿ÉÒԲμû¡¶DockerÔ´Âë·ÖÎö¡·ÏµÁеĵÚÈýƪ¡ª¡ªDocker DaemonÆô¶¯Æª¡£

6.Docker Daemon

Docker DaemonÊÇÍê³ÉjobÖ´ÐеÄÖ÷ÒªÔØÌå¡£Docker ServerΪ¾µÏñÏÂÔØjob×¼±¸ºÃËùÓеIJÎÊýÅäÖÃÖ®ºó£¬Ö»µÈDocker DaemonÀ´Íê³ÉÖ´ÐУ¬²¢·µ»ØÏàÓ¦µÄÐÅÏ¢£¬Docker ServerÔÙ½«ÏìÓ¦ÐÅÏ¢·µ»ØÖÁDocker Client¡£Docker Daemon¶ÔÓÚ¾µÏñÏÂÔØjobµÄÖ´ÐУ¬Éæ¼°µÄÄÚÈݽ϶ࣺÊ×ÏȽâÎöjob²ÎÊý£¬»ñÈ¡Docker¾µÏñµÄrepository¡¢tag¡¢Docker RegistryÐÅÏ¢µÈ£»ËæºóÓëDocker Registry½¨Á¢session£»È»ºóͨ¹ýsessionÏÂÔØDocker¾µÏñ£»½Ó׎«Docker¾µÏñÏÂÔØÖÁ±¾µØ²¢´æ´¢ÓÚgraph£»×îºóÔÚTagStore±ê¼Ç¸Ã¾µÏñ¡£

Docker Daemon¶ÔÓÚ¾µÏñÏÂÔØjobµÄÖ´ÐÐÖ÷ÒªÒÀ¿¿CmdPullº¯Êý¡£Õâ¸öCmdPullº¯ÊýÓëDocker ClientµÄCmdPullº¯ÊýÍêÈ«²»Í¬£¬Ç°ÕßÊÇΪÁË´úÌæÓû§·¢Ë;µÏñÏÂÔØµÄÇëÇóÖÁDocker Daemon£¬¶øDocker DaemonµÄCmdPullº¯ÊýÔòÊÇʵÏÖ´úÌæÓû§ÕæÕýÍêÈ«¾µÏñÏÂÔØµÄÈÎÎñ¡£µ÷ÓÃCmdPullº¯ÊýµÄ¶ÔÏóÀàÐÍΪTagStore£¬ÆäÔ´ÂëʵÏÖλÓÚ./docker/graph/pull.go¡£

6.1 ½âÎöjob²ÎÊý

ÕýÈçDocker ClientÓëDocker Server£¬Docker DaemonÖ´ÐоµÏñÏÂÔØjobʱµÄµÚÒ»¸ö²½ÖèÒ²ÊǽâÎö²ÎÊý¡£½âÎö¹¤×÷Ò»·½ÃæÈ·±£´«Èë²ÎÊýÎÞÎó£¬ÁíÒ»·½Ãæ°´ÐèΪjobÌṩ²ÎÊýÒÀ¾Ý¡£±í6.1ÂÞÁÐDocker Daemon½âÎöµÄjob²ÎÊý£¬ÈçÏ£º

±í6.1 Docker Daemon½âÎöjob²ÎÊýÁбí

²ÎÊý½âÎö¹ý³ÌÖУ¬Docker Daemon»¹Ìí¼ÓÁËһЩ¾«ÃîµÄÉè¼Æ¡£È磺ÔÚTagStoreÀàÐÍÖÐÉè¼ÆÁËpullingPool¶ÔÏó£¬ÓÃÓÚ±£´æÕýÔÚ±»ÏÂÔØµÄDocker¾µÏñ£¬ÏÂÔØÍê±Ï֮ǰ½ûÖ¹ÆäËûDocker Client·¢ÆðÏàͬ¾µÏñµÄÏÂÔØÇëÇó£¬ÏÂÔØÍê±ÏÖ®ºópullingPoolÖеĸüǼ±»Çå³ý¡£Docker DaemonÒ»µ©½âÎö³ölocalNameÓëtagÁ½¸ö²ÎÊýÐÅÏ¢£¬ÔòÁ¢¼´¼ì²âpullingPool£¬ÊµÏÖÔ´ÂëλÓÚ./docker/graph/pull.go#L36-L46£¬ÈçÏ£º

c, err := s.poolAdd("pull", localName+":"+tag)
if err != nil {
if c != nil {
// Another pull of the same repository is already taking place;
just wait for it to finish
job.Stdout.Write(sf.FormatStatus("", "Repository %s already being pulled
by another client. Waiting.", localName))
<-c
return engine.StatusOK
}
return job.Error(err)
}
defer s.poolRemove("pull", localName+":"+tag)

6.2 ´´½¨session¶ÔÏó

ÏÂÔØDocker¾µÏñ£¬Docker DaemonÓëDocker RegistryÐèÒª½¨Á¢Í¨ÐÅ¡£ÎªÁ˱£ÕÏÁ½ÕßͨÐŵĿɿ¿ÐÔ£¬Docker Daemon²ÉÓÃÁËsession»úÖÆ¡£Docker DaemonÿÊÕµ½Ò»¸öDocker ClientµÄ¾µÏñÏÂÔØÇëÇ󣬶¼»á´´½¨Ò»¸öÓëÏàÓ¦Docker RegistryµÄsession£¬Ö®ºóËùÓеÄÍøÂçÊý¾Ý´«Êä¶¼ÔÚ¸ÃsessionÉÏÍê³É¡£°üregistry¶¨ÒåÁËsession£¬Î»ÓÚ./docker/registry/registry.go£¬ÈçÏ£º

type Session struct {
authConfig *AuthConfig
reqFactory *utils.HTTPRequestFactory
indexEndpoint string
jar *cookiejar.Jar
timeout TimeoutType
}

CmdPullº¯ÊýÖд´½¨sessionµÄÔ´ÂëʵÏÖÈçÏ£º

r, err := registry.NewSession(authConfig, registry.HTTPRequestFactory
(metaHeaders), endpoint, true)

´´½¨µÄsession¶ÔÏóΪr£¬ÔÚÏÂÒ»½×¶ÎµÄ¾µÏñÏÂÔØ¹ý³ÌÖУ¬¶àÊýÓë¾µÏñÏà¹ØµÄÊý¾Ý´«Êä¾ùÔÚrÕâ¸öseesionµÄ»ù´¡ÉÏÍê³É¡£

6.3 Ö´ÐоµÏñÏÂÔØ

Docker Daemon֮ǰËùÓеIJÙ×÷£¬¶¼ÊôÓÚÅäÖý׶Σ¬´Ó½âÎöjob²ÎÊý£¬µ½½¨Á¢session¶ÔÏ󣬶ø²¢Î´ÓëDocker Registry½¨Á¢Êµ¼ÊµÄÁ¬½Ó£¬²¢ÇÒÒ²»¹Î´ÕæÕý´«Êä¹ýÓйØDocker¾µÏñµÄÄÚÈÝ¡£

Íê³ÉËùÓеÄÅäÖÃÖ®ºó£¬Docker Daemon½øÈëDocker¾µÏñÏÂÔØ»·½Ú£¬ÊµÏÖDocker¾µÏñÏÂÔØµÄÔ´ÂëλÓÚ./docker/graph/pull.go#L69-L71£¬ÈçÏ£º

if err = s.pullRepository(r, job.Stdout, localName, remoteName, tag, sf, 
job.GetenvBool("parallel")); err != nil {
return job.Error(err)
}

ÒÔÉÏ´úÂëÖÐpullRepositoryº¯Êý°üº¬Á˾µÏñÏÂÔØÕû¸öÁ÷³ÌµÄÁÖÁÖ×Ü×Ü£¬¸ÃÁ÷³Ì¿ÉÒԲμûͼ6.1£º


ͼ6.1 pullRepositoryÁ÷³Ìͼ

¹ØÓÚÉÏͼµÄ¸÷¸ö»·½Ú£¬ÏÂ±í¸ø³ö¼òÒªµÄ¹¦ÄܽéÉÜ£º

±í6.2 pullRepository¸÷»·½Ú¹¦ÄܽéÉܱí

·ÖÎöpullRepositoryµÄÕû¸öÁ÷³Ì֮ǰ£¬ºÜÓбØÒªÁ˽âÏÂpullRepositoryº¯Êýµ÷ÓÃÕßµÄÀàÐÍTagStore¡£TagStoreÊÇDocker¾µÏñ·½Ã溭¸ÇÄÚÈÝ×î¶àµÄÊý¾Ý½á¹¹£ºÒ»·½ÃæTagStore¹ÜÀíDockerµÄGraph£¬ÁíÒ»·½ÃæTagStore»¹¹ÜÀíDockerµÄrepository¼Ç¼¡£³ý´ËÖ®Í⣬TagStore»¹¹ÜÀí×ÅÉÏÎÄÌáµ½µÄ¶ÔÏópullingPoolÒÔ¼°pushingPool£¬±£Ö¤Docker DaemonÔÚͬһʱ¿Ì£¬Ö»ÎªÒ»¸öDocker ClientÖ´ÐÐͬһ¾µÏñµÄÏÂÔØ»òÉÏ´«¡£TagStore½á¹¹ÌåµÄ¶¨ÒåλÓÚ./docker/graph/tags.go#L20-L29£¬ÈçÏ£º

type TagStore struct {
path string
graph *Graph
Repositories map[string]Repository
sync.Mutex
// FIXME: move push/pull-related fields
// to a helper type
pullingPool map[string]chan struct{}
pushingPool map[string]chan struct{}
}

ÒÔϽ«Öصã·ÖÎöpullRepositoryµÄÕû¸öÁ÷³Ì¡£

6.3.1 GetRepositoryData

ʹÓÃDockerÏÂÔØ¾µÏñʱ£¬Óû§ÍùÍùÖ¸¶¨µÄÊÇDocker¾µÏñµÄÃû³Æ£¬È磺ÇëÇódocker pull ubuntu:14.04ÖоµÏñÃû³ÆÎªubuntu¡£GetRepositoryDataµÄ×÷ÓÃÔòÊÇ»ñÈ¡¾µÏñÃû³ÆËùÔÚrepositoryÖÐËùÓÐimageµÄ idÐÅÏ¢¡£

GetRepositoryDataµÄÔ´ÂëʵÏÖλÓÚ./docker/registry/session.go#L255-L324¡£»ñÈ¡repositoryÖÐimageµÄIDÐÅÏ¢µÄÄ¿±êURLµØÖ·ÈçÒÔÏÂÔ´Â룺

repositoryTarget := fmt.Sprintf("%srepositories/%s/images", indexEp, remote)

Òò´Ë£¬docker pull ubuntu:14.04ÇëÇó±»Ö´ÐÐʱ£¬repositoryµÄÄ¿±êURLµØÖ·Îªhttps://index.docker.io/v1/repositories/ubuntu/images£¬·ÃÎʸÃURL¿ÉÒÔ»ñµÃÓйØubuntuÕâ¸örepositoryÖÐËùÓÐimageµÄ idÐÅÏ¢£¬²¿·ÖimageµÄidÐÅÏ¢ÈçÏ£º

[{"checksum": "", "id": "
2427658c75a1e3d0af0e7272317a8abfaee4c15729b6840e3c2fca342fe47bf1"},
{"checksum": "", "id":
"81fbd8fa918a14f4ebad9728df6785c537218279081c7a120d72399d3a5c94a5"
}, {"checksum": "", "id":
"ec69e8fd6b0236b67227869b6d6d119f033221dd0f01e0f569518edabef3b72c"
}, {"checksum": "", "id":
"9e8dc15b6d327eaac00e37de743865f45bee3e0ae763791a34b61e206dd5222e"
}, {"checksum": "", "id":
"78949b1e1cfdcd5db413c300023b178fc4b59c0e417221c0eb2ffbbd1a4725cc"
},¡­¡­]

»ñÈ¡ÒÔÉÏÐÅÏ¢Ö®ºó£¬Docker Daemonͨ¹ýRepositoryDataºÍImgDataÀàÐͶÔÏóÀ´´æ´¢ubuntuÕâ¸örepositoryÖÐËùÓÐimageµÄÐÅÏ¢£¬RepositoryDataºÍImgDataµÄÊý¾Ý½á¹¹¹ØÏµÈçͼ6.2£º


ͼ6.2 RepositoryDataºÍImgDataµÄÊý¾Ý½á¹¹¹ØÏµÍ¼

GetRepositoryDataÖ´Ðйý³ÌÖУ¬»áΪָ¶¨repositoryÖеÄÿһ¸öimage´´½¨Ò»¸öImgData¶ÔÏ󣬲¢×îÖÕ½«ËùÓÐImgData´æ·ÅÔÚRepositoryDataµÄImgListÊôÐÔÖУ¬ImgListµÄÀàÐÍΪmap£¬keyΪimageµÄID£¬valueÖ¸ÏòImgData¶ÔÏó¡£´ËʱImgData¶ÔÏóÖÐÖ»ÓÐÊôÐÔIDÓëChecksumÓÐÄÚÈÝ¡£

6.3.2 GetRemoteTags

ʹÓÃDockerÏÂÔØ¾µÏñʱ£¬Óû§³ýÁËÖ¸¶¨Docker¾µÏñµÄÃû³ÆÖ®Í⣬һ°ã»¹ÐèÒªÖ¸¶¨Docker¾µÏñµÄtag£¬È磺ÇëÇódocker pull ubuntu:14.04ÖоµÏñÃû³ÆÎªubuntu£¬¾µÏñtagΪ14.04£¬¼ÙÉèÓû§²»ÏÔÐÔÖ¸¶¨tag£¬ÔòĬÈÏtagΪlatest¡£GetRemoteTagsµÄ×÷ÓÃÔòÊÇ»ñÈ¡¾µÏñÃû³ÆËùÔÚrepositoryÖÐËùÓÐtagµÄÐÅÏ¢¡£

GetRemoteTagsµÄÔ´ÂëʵÏÖλÓÚ./docker/registry/session.go#L195-234¡£»ñÈ¡repositoryÖÐËùÓÐtagÐÅÏ¢µÄÄ¿±êURLµØÖ·ÈçÒÔÏÂÔ´Â룺

endpoint := fmt.Sprintf("%srepositories/%s/tags", host, repository)

»ñȡָ¶¨repositoryÖÐËùÓÐtagÐÅÏ¢Ö®ºó£¬Docker Daemon¸ù¾Ýtag¶ÔÓ¦layerµÄID£¬ÕÒµ½ImgData£¬²¢¶ÔÌî³äImgDataÖеÄTagÊôÐÔ¡£´Ëʱ£¬RepositoryDataµÄImgListÊôÐÔÖУ¬ÓеÄImgData¶ÔÏóÓÐTagÄÚÈÝ£¬ÓеÄImgData¶ÔÏóÖÐûÓÐTagÄÚÈÝ¡£ÕâÒ²ºÍʵ¼ÊÇé¿öÏà·û£¬ÈçÏÂÔØÒ»¸öubuntu:14.04¾µÏñ£¬¸Ã¾µÏñµÄrootfsÖÐÖ»ÓÐ×îÉϲãµÄlayer²ÅÓÐtagÐÅÏ¢£¬ÕâÒ»²ãlayerµÄparent Image²¢²»Ò»¶¨´æÔÚtagÐÅÏ¢¡£

6.3.3 pullImage

Docker DaemonÏÂÔØDocker¾µÏñʱÊÇͨ¹ýimage idÀ´Íê³É¡£GetRepositoryDataºÍGetRemoteTagsÔò³É¹¦Íê³ÉÁËÓû§´«ÈëµÄrepositoryºÍtagÐÅÏ¢Óëimage idµÄת»»¡£ÈçÇëÇódocker pull ubuntu:14.04ÖУ¬repositoryΪubuntu£¬tagΪ14.04£¬Ôò¶ÔÓ¦µÄimage idΪ2d24f826¡£

Docker Daemon»ñµÃÏÂÔØ¾µÏñµÄimage idÖ®ºó£¬Ê×ÏȲéÑépullingPool£¬ÅжÏÊÇ·ñÓÐÆäËûDocker ClientͬÑù·¢ÆðÁ˸þµÏñµÄÏÂÔØÇëÇó£¬Èç¹ûûÓеϰDocker Daemon²Å¼ÌÐøÏÂÔØÈÎÎñ¡£

Ö´ÐÐpullImageº¯ÊýµÄÔ´ÂëʵÏÖλÓÚ./docker/graph/pull.go#L159£¬ÈçÏ£º

s.pullImage(r, out, img.ID, ep, repoData.Tokens, sf)

¶øpullImageº¯ÊýµÄ¶¨ÒåλÓÚ./docker/graph/pull.go#L214-L301¡£Í¼6.1ÖУ¬¿ÉÒÔ¿´µ½pullImageº¯ÊýµÄÖ´ÐпÉÒÔ·ÖΪ4¸ö²½Ö裺GetRemoteHistory¡¢GetRemoteImageJson¡¢GetRemoteImageLayerÓës.graph.Register()¡£

GetRemoteHistoryµÄ×÷ÓúܺÃÀí½â£¬¼ÈÈ»Docker DaemonÒѾ­Í¨¹ýGetRepositoryDataºÍGetRemoteTagsÕÒ³öÁËÖ¸¶¨tagµÄimage id£¬ÄÇôDocker DaemonËùÐèÍê³ÉµÄ¹¤×÷ΪÏÂÔØ¸Ãimage ¼°ÆäËùÓеÄ׿ÏÈimage¡£GetRemoteHistoryÕýÊÇÓÃÓÚ»ñȡָ¶¨image¼°ÆäËùÓÐ׿ÏÈiamgeµÄid¡£

GetRemoteHistoryµÄÔ´ÂëʵÏÖλÓÚ./docker/registry/session.go#L72-L101¡£

»ñÈ¡ËùÓеÄimage idÖ®ºó£¬¶ÔÓÚÿһ¸öimage id£¬Docker Daemon¶¼¿ªÊ¼ÏÂÔØ¸ÃimageµÄÈ«²¿ÄÚÈÝ¡£Docker ImageµÄÈ«²¿ÄÚÈݰüÀ¨Á½¸ö·½Ã棺image jsonÐÅÏ¢ÒÔ¼°image layerÐÅÏ¢¡£DockerËùÓÐimageµÄjsonÐÅÏ¢¶¼Óɺ¯ÊýGetRemoteImageJSONÀ´Íê³É¡£·ÖÎöGetRemoteImageJSON֮ǰ£¬ÓбØÒª²ûÊöÇå³þʲôÊÇDocker ImageµÄjsonÐÅÏ¢¡£

Docker ImageµÄjsonÐÅÏ¢ÊÇÒ»¸ö·Ç³£ÖØÒªµÄ¸ÅÄî¡£Õⲿ·ÖjsonΨһµÄ±êÖ¾ÁËÒ»¸öimage£¬²»½ö±êÖ¾ÁËimageµÄid£¬Í¬Ê±Ò²±êÖ¾ÁËimageËùÔÚlayer¶ÔÓ¦µÄconfigÅäÖÃÐÅÏ¢¡£Àí½âÒÔÉÏÄÚÈÝ£¬¿ÉÒÔ¾ÙÒ»¸öÀý×Ó£ºdocker build¡£ÃüÁîdocker buildÓÃÒÔͨ¹ýÖ¸¶¨µÄDockerfileÀ´´´½¨Ò»¸öDocker¾µÏñ£»¶ÔÓÚDockerfileÖÐËùÓеÄÃüÁDocker Daemon¶¼»áΪÆä´´½¨Ò»¸öеÄimage£¬È磺RUN apt-get update, ENV path=/bin, WORKDIR /homeµÈ¡£¶ÔÓÚÃüÁîRUN apt-get update£¬Docker DaemonÐèÒªÖ´ÐÐapt-get update²Ù×÷£¬¶ÔÓ¦µÄrootfsÉϱض¨»áÓÐÄÚÈݸüУ¬µ¼ÖÂн¨µÄimageËù´ú±íµÄlayerÖÐÓÐÐÂÌí¼ÓµÄÄÚÈÝ¡£¶øÈçENV path=/bin, WORKDIR /homeÕâÑùµÄÃüÁ½ö½öÊÇÅäÖÃÁËһЩÈÝÆ÷ÔËÐеIJÎÊý£¬²¢Ã»ÓоµÏñÄÚÈݵĸüУ¬¶ÔÓÚÕâÖÖÇé¿ö£¬Docker DaemonͬÑù´´½¨Ò»²ãеÄlayer£¬²¢ÇÒÕâ²ãеÄlayerÖÐÄÚÈÝΪ¿Õ£¬¶øÃüÁîÄÚÈÝ»áÔÚÕâ²ãimageµÄjsonÐÅÏ¢ÖÐ×ö¸üС£×Ü½á¶øÑÔ£¬¿ÉÒÔÈÏΪDockerµÄimage°üº¬Á½²¿·ÖÄÚÈÝ£ºimageµÄjsonÐÅÏ¢¡¢layerÄÚÈÝ¡£µ±layerÄÚÈÝΪ¿Õʱ£¬imageµÄjsonÐÅÏ¢±»¸üС£

Çå³þÁËDocker imageµÄjsonÐÅÏ¢Ö®ºó£¬Àí½âGetRemoteImageJSONº¯ÊýµÄ×÷ÓþͱäµÃÊ®·ÖÈÝÒס£GetRemoteImageJSONµÄÖ´ÐдúÂëλÓÚ./docker/graph/pull.go#L243£¬ÈçÏ£º

imgJSON, imgSize, err = r.GetRemoteImageJSON(id, endpoint, token)

GetRemoteImageJSON·µ»ØµÄÁ½¸ö¶ÔÏóimgJSON´ú±íimageµÄjsonÐÅÏ¢£¬imgSize´ú±í¾µÏñµÄ´óС¡£Í¨¹ýimgJSON¶ÔÏó£¬Docker DaemonÁ¢¼´´´½¨Ò»¸öimage¶ÔÏ󣬴´½¨image¶ÔÏóµÄÔ´ÂëʵÏÖλÓÚ./docker/graph/pull.go#L251£¬ÈçÏ£º

img, err = image.NewImgJSON(imgJSON)

¶øNewImgJSONº¯ÊýλÓÚ°üimageÖУ¬º¯Êý·µ»ØÀàÐÍΪһ¸öImage¶ÔÏ󣬶øImageÀàÐ͵͍Òå¶øÏ£º

type Image struct {
ID string `json:"id"`
Parent string `json:"parent,omitempty"`
Comment string `json:"comment,omitempty"`
Created time.Time `json:"created"`
Container string `json:"container,omitempty"`
ContainerConfig runconfig.Config `json:"container_config,omitempty"`
DockerVersion string `json:"docker_version,omitempty"`
Author string `json:"author,omitempty"`
Config *runconfig.Config `json:"config,omitempty"`
Architecture string `json:"architecture,omitempty"`
OS string `json:"os,omitempty"`
Size int64

graph Graph
}

·µ»Øimg¶ÔÏó£¬Ôò˵Ã÷¹ØÓÚ¸ÃimageµÄËùÓÐÔªÊý¾ÝÒѾ­±£´æÍê±Ï£¬ÓÉÓÚ»¹È±ÉÙimageµÄlayerÖаüº¬µÄÄÚÈÝ£¬Òò´ËÏÂÒ»¸ö²½Ö輴ΪÏÂÔØ¾µÏñlayerµÄÄÚÈÝ£¬µ÷Óú¯ÊýΪGetRemoteImageLayer£¬º¯ÊýÖ´ÐÐλÓÚ./docker/graph/pull.go#L270£¬ÈçÏ£º

layer, err := r.GetRemoteImageLayer(img.ID, endpoint, token, int64(imgSize))

GetRemoteImageLayerº¯Êý·µ»Øµ±Ç°imageµÄlayerÄÚÈÝ¡£ImageµÄlayerÄÚÈÝÖ¸µÄÊÇ£º¸ÃimageÔÚparent imageÖ®ÉÏ×öµÄÎļþϵͳÄÚÈݸüУ¬°üÀ¨ÎļþµÄÔöÌí¡¢É¾³ý¡¢Ð޸ĵȡ£ÖÁ´Ë£¬imageµÄjsonÐÅÏ¢ÒÔ¼°layerÄÚÈݾù±»Docker Daemon»ñÈ¡£¬Òâζ×ÅÒ»¸öÍêÕûµÄimageÒѾ­ÏÂÔØÍê±Ï¡£ÏÂÔØimageÍê±ÏÖ®ºó£¬²¢²»Òâζ×ÅDocker Daemon¹ØÓÚDocker¾µÏñÏÂÔØµÄjob¾Í´Ë½áÊø£¬Docker DaemonÈÔÈ»ÐèÒª¶ÔÏÂÔØµÄimage½øÐд洢¹ÜÀí£¬ÒÔ±ãDocker DaemonÔÚÖ´ÐÐÆäËûÈç´´½¨ÈÝÆ÷µÈjobʱ£¬Äܹ»·½±ãʹÓÃÕâЩimage¡£

Docker DaemonÔÚgraphÖÐ×¢²áimageµÄÔ´ÂëʵÏÖλÓÚ./docker/graph/pull.go#L283-L285£¬ÈçÏ£º

err = s.graph.Register(imgJSON,utils.ProgressReader(layer, imgSize, 
out, sf, false, utils.TruncateID(id), "Downloading"),img)

Docker Daemonͨ¹ýgraph´æ´¢imageÊÇÒ»¸öºÜÖØÒªµÄ»·½Ú¡£DockerÔÚ1.2.0°æ±¾ÖпÉÒÔͨ¹ýAUFS¡¢DevMapperÒÔ¼°BTRFSÀ´½øÐÐimageµÄ´æ´¢¡£ÔÚLinux 3.18-rc2°æ±¾ÖУ¬OverlayFSÒѾ­±»Äں˺ϲ¢£¬¹Ê´Ó1.4.0°æ±¾¿ªÊ¼£¬Docker µÄimageÖ§³ÖOverlayFSµÄ´æ´¢·½Ê½¡£

Docker¾µÏñµÄ´æ´¢ÔÚDockerÖÐÊǽÏΪ¶ÀÁ¢ÇÒÖØÒªµÄÄÚÈÝ£¬¹Ê½«ÔÚ¡¶DockerÔ´Âë·ÖÎö¡·ÏµÁеĵÚʮһƪרÎÄ·ÖÎö¡£

6.3.4 ÅäÖÃTagStore

Docker¾µÏñÏÂÔØÍê±ÏÖ®ºó£¬Docker DaemonÐèÒªÔÚTagStoreÖÐÖ¸¶¨µÄrepositoryÖÐÌí¼ÓÏàÓ¦µÄtag¡£Ã¿µ±Óû§²é¿´±¾µØ¾µÏñʱ£¬¶¼¿ÉÒÔ´ÓTagStoreµÄrepositoryÖв鿴ËùÓк¬ÓÐtagÐÅÏ¢µÄimage¡£

Docker DaemonÅäÖÃTagStoreµÄÔ´ÂëʵÏÖλÓÚ./docker/graph/pull.go#L206£¬ÈçÏ£º

if err := s.Set(localName, tag, id, true); err != nil {
return err
}

TagStoreÀàÐ͵ÄSetº¯Êý¶¨ÒåλÓÚ./docker/graph/tags.go#L174-L205¡£Setº¯ÊýµÄÖ¸¶¨Á÷³ÌÓë¼òÒª½éÉÜÈçͼ6.3£º


ͼ6.3 TagStoreÖÐSetº¯ÊýÖ´ÐÐÁ÷³Ìͼ

µ±Docker Daemon½«ÒÑÏÂÔØµÄDocker¾µÏñÐÅϢͬ²½µ½repositoryÖ®ºó£¬DockerÏÂÔØ¾µÏñµÄjob¾ÍÈ«²¿Íê³É£¬Docker Daemon·µ»ØÏìÓ¦ÖÁDocker Server£¬Docker Server·µ»ØÏàÓ¦ÖÁDocker Client¡£×¢£º±¾µØµÄrepositoryÎļþλÓÚDockerµÄ¸ùĿ¼£¬¸ùĿ¼һ°ãΪ/var/lib/docker£¬Èç¹ûʹÓÃaufsµÄgraphdriver£¬ÔòrepositoryÎļþÃûΪrepositories-aufs¡£

7.×ܽá

Docker¾µÏñ¸øDockerÈÝÆ÷µÄÔËÐдøÀ´ÁËÎÞÏ޵ĿÉÄÜÐÔ£¬ÖîÈçDocker HubÖ®ÀàµÄDocker RegistryÓÖʹµÃDocker¾µÏñÔÚÈ«ÇòµÄ¿ª·¢ÕßÖ®¼ä¹²Ïí¡£Docker¾µÏñµÄÏÂÔØ£¬×÷ΪʹÓÃDockerµÄµÚÒ»¸ö²½Ö裬Docker°®ºÃÕßÈôÄÜÊìÁ·ÕÆÎÕÆäÖеÄÔ­Àí£¬±Ø¶¨ÄܶÔDockerµÄºÜ¶à¸ÅÄîÓиüΪÇåÎúµÄÈÏʶ£¬¶ÔDockerÈÝÆ÷µÄÔËÐС¢¹ÜÀíµÈ¾ùÊÇÓаÙÀû¶øÎÞÒ»º¦¡£

Docker¾µÏñµÄÏÂÔØÐèÒªDocker Client¡¢Docker Server¡¢Docker DaemonÒÔ¼°Docker RegistryËÄÕßЭͬºÏ×÷Íê³É¡£±¾ÎÄ´ÓÔ´ÂëµÄ½Ç¶È·ÖÎöÁËËÄÕ߸÷×ԵİçÑݵĽÇÉ«£¬·ÖÎö¹ý³ÌÖл¹Éæ¼°¶àÖÖDocker¸ÅÄÈçrepository¡¢tag¡¢TagStore¡¢session¡¢image¡¢layer¡¢image json¡¢graphµÈ¡£

8.×÷Õß½éÉÜ

ËïºêÁÁ£¬DaoCloud³õ´´ÍŶӳÉÔ±£¬Èí¼þ¹¤³Ìʦ£¬Õã½­´óѧVLISʵÑéÊÒÓ¦½ìÑо¿Éú¡£¶ÁÑÐÆÚ¼ä»îÔ¾ÔÚPaaSºÍDocker¿ªÔ´ÉçÇø£¬¶ÔCloud FoundryÓÐÉîÈëÑо¿ºÍ·á¸»Êµ¼ù£¬Éó¤µ×²ãƽ̨´úÂë·ÖÎö£¬¶Ô·Ö²¼Ê½Æ½Ì¨µÄ¼Ü¹¹ÓÐÒ»¶¨¾­Ñ飬׫дÁË´óÁ¿ÓÐÉî¶ÈµÄ¼¼Êõ²©¿Í¡£2014ÄêÄ©ÒԺϻïÈËÉí·Ý¼ÓÈëDaoCloudÍŶӣ¬ÖÂÁ¦ÓÚ´«²¥ÒÔDockerΪÖ÷µÄÈÝÆ÷µÄ¼¼Êõ£¬Íƶ¯»¥ÁªÍøÓ¦ÓõÄÈÝÆ÷»¯²½·¥¡£

   
4437 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

ÿÈÕ¹¹½¨½â¾ö·½°¸
ÈçºÎÖÆ¶¨ÓÐЧµÄÅäÖùÜÀíÁ÷³Ì
ÅäÖùÜÀíÖ÷Òª»î¶¯¼°ÊµÏÖ·½·¨
¹¹½¨¹ÜÀíÈëÃÅ
Ïà¹ØÎĵµ

ÅäÖùÜÀíÁ÷³Ì
ÅäÖùÜÀí°×ƤÊé
CM09_CÅäÖùÜÀí±ê×¼
ʹÓÃSVN½øÐа汾¿ØÖÆ
Ïà¹Ø¿Î³Ì

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

Èí¼þÅäÖùÜÀíµÄÎÊÌ⡢ĿµÄ
Èí¼þÅäÖùÜÀí¹æ·¶
CQWeb 7.1ÐÔÄܲâÊÔÓëµ÷ÓÅÖ¸ÄÏ
ΪʲôÐèҪʹÓÃClearCase
ClearCaseÓëRTCµÄ¼¯³É
ÀûÓÃClearQuest ½øÐвâÊÔ¹ÜÀí


²úÆ··¢²¼¹ÜÀí
ÅäÖùÜÀí·½·¨¡¢Êµ¼ù¡¢¹¤¾ß
¶à²ã´Î¼¯³ÉÅäÖùÜÀí
ʹÓÃCCÓëCQ½øÐÐÏîĿʵ¼ù
CVSÓëÅäÖùÜÀí
Subversion¹ÜÀíÔ±


ÅäÖùÜÀíʵ¼ù£¨´Ó×éÖ¯¼¶µ½ÏîÄ¿¼¶£©
ͨºÅÔº ÅäÖùÜÀí¹æ·¶ÓëÓ¦ÓÃ
ÅäÖùÜÀíÈÕ¹¹½¨¼°³ÖÐø¼¯³É
µ¤·ð˹ ClearCaseÓëÅäÖùÜÀí
ÖйúÒÆ¶¯ Èí¼þÅäÖùÜÀí
ÖйúÒøÐÐ Èí¼þÅäÖùÜÀí
Ìì½ò»ªÒíÀ¶Ìì¿Æ¼¼ ÅäÖùÜÀíÓëPvcs