入口层:

cmd/podman/containers/create.go create
-> cmd/podman/containers/create.go pullImage
—> registry.ImageEngine().Pull
—-> �github.com/containers/common/libimage/pull.go copyFromRegistry 用的还是镜像名
——> copySingleImageFromRegistry:Attempting to pull candidate;Pulled candidate %s successfully
——-> �github.com/containers/image/v5/storage/storage_transport.go ParseStoreReference: parsed reference into “[overlay@/var/lib/containers/storage+/var/run/containers/storage:overlay.mountopt=nodev,metacopy=on]docker.io/library/ubuntu:20”
——-> �github.com/containers/common/libimage/copier.go copy:Copying source image //ubuntu:20 to destination image [overlay@/var/lib/containers/storage+/var/run/containers/storage:overlay.mountopt=nodev,metacopy=on]docker.io/library/ubuntu:20
———> �github.com/containers/image/v5/copy/copy.go Image

github.com/containers/image/v5/image/sourced.go FromUnparsedImage 解析image信息
-> github.com/containers/image/v5/image/unparsed.go UnparsedImage.Manifest
-> github.com/containers/image/v5/image/manifest.go manifestInstanceFromBlob
�—> github.com/containers/image/v5/docker/docker_image_src.go dockerImageSource.GetManifest

image层开始:

github.com/containers/image/v5/copy/copy.go Image
-> github.com/containers/image/v5/copy/copy.go copyOneImage
—> github.com/containers/image/v5/image/sourced.go FromUnparsedImage 解析image信息
—> github.com/containers/image/v5/copy/copy.go copyLayers
—-> github.com/containers/image/v5/copy/copy.go copyLayer

  1. 尝试复用已经下载的Blob

——> github.com/containers/image/v5/storage/storage_image.go TryReusingBlobWithOptions
——-> github.com/containers/image/v5/storage/storage_image.go tryReusingBlobWithSrcRef:如果提供了ref参数,会首先尝试从AdditionalLayer获取layer
———> github.com/containers/storage/store.go LookupAdditionalLayer 返回 AdditionalLayer 对象
———-> github.com/containers/storage/drivers/overlay/overlay.go LookupAdditionalLayer
————> �github.com/containers/storage/drivers/overlay/overlay.go getAdditionalLayerPath 返回layder的目录: (/xxxx/base64镜像名/digest) 通过确认这个目录下diff和info文件是否存在来判断是否存在AdditionalLayer。(这个通过类似stargz的fuse来实现diff和info文件)

  1. 如果没有已经下载的Blob,则执行下载

——> github.com/containers/image/v5/docker/docker_image_src.go GetBlob 返回stream: Downloading /v2/library/ubuntu/blobs/sha256:c29284518f497b8c5f49933e74e43ca5221e69c8251e780427f7d12f716625ff
——> �github.com/containers/image/v5/copy/copy.go � �copyLayerFromStream
——-> �github.com/containers/image/v5/copy/copy.go � �copyBlobFromStream

———> github.com/containers/image/v5/storage/storage_image.go PutBlobWithOptions
�———-> github.com/containers/image/v5/storage/storage_image.go PutBlob 写入磁盘
———-> github.com/containers/image/v5/storage/storage_image.go queueOrCommit
————> github.com/containers/image/v5/storage/storage_image.go commitLayer

————-> github.com/containers/storage/store.go PutLayer 如果是正常镜像,则通过这个链路
—————> github.com/containers/storage/layers.go Put 创建layer目录和run目录

—> github.com/containers/image/v5/copy/copy.go copyUpdatedConfigAndManifest 下载镜像config和manifest。Copying config c5dcc7d437 ;doneWriting manifest to image destination ;Storing signatures

-> github.com/containers/image/v5/storage/storage_image.go Commit
—> github.com/containers/image/v5/storage/storage_image.go commitLayer
—-> github.com/containers/storage/store.go PutAs 如果是AdditionalLayer,则通过这个链路
——> github.com/containers/storage/layers.go PutAdditionalLayer
——-> github.com/containers/storage/drivers/driver.go CreateAs 创建diff、work、merged目录,然后删除diff目录,软连接到AdditionalLayer的diff目录
——-> github.com/containers/storage/layers.go save 保存layers.json

notifyUseAdditionalLayer:在layer目录下创建”use“文件,用于通知外部服务

AdditionalLayer是storage层和image层交互的对象:

  1. type AdditionalLayer interface {
  2. // PutAs creates layer based on this handler, using diff contents from the additional
  3. // layer store.
  4. PutAs(id, parent string, names []string) (*Layer, error)
  5. // UncompressedDigest returns the uncompressed digest of this layer
  6. UncompressedDigest() digest.Digest
  7. // CompressedSize returns the compressed size of this layer
  8. CompressedSize() int64
  9. // Release tells the additional layer store that we don't use this handler.
  10. Release()
  11. }