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£¬¾µÏñÃû³ÆÎª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²ÎÊýµÄµÚÒ»¸ö²½Ö裬ԴÂëÈçÏ£º
ÆäÖУ¬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ΪÖ÷µÄÈÝÆ÷µÄ¼¼Êõ£¬Íƶ¯»¥ÁªÍøÓ¦ÓõÄÈÝÆ÷»¯²½·¥¡£ |