Docker镜像服务image.Store

来源:互联网 发布:淘宝宝贝分类 编辑:程序博客网 时间:2024/06/15 01:02

镜像服务是镜像操作的抽象接口,实际上对镜像的操作包含两部分,镜像信息和镜像数据;镜像服务基于镜像持久化服务image.StoreBackend提供的接口实现镜像信息的操作,通过镜像层服务image.LayerGetReleaser提供的镜像层操作的的操作,因为镜像都是由镜像层组成,也就是实际操作镜像数据。他们之间的关系大概如下:
这里写图片描述
接着我们先看下镜像服务,镜像持久化服务和镜像层服务的接口定义
在文件docker\image\store.go的镜像服务和镜像层服务接口:

// Store is an interface for creating and accessing imagestype Store interface {    Create(config []byte) (ID, error)    Get(id ID) (*Image, error)    Delete(id ID) ([]layer.Metadata, error)    Search(partialID string) (ID, error)    SetParent(id ID, parent ID) error    GetParent(id ID) (ID, error)    Children(id ID) []ID    Map() map[ID]*Image    Heads() map[ID]*Image}// LayerGetReleaser is a minimal interface for getting and releasing images.//实现在docker/layer/layer_store.gotype LayerGetReleaser interface {    Get(layer.ChainID) (layer.Layer, error)    Release(layer.Layer) ([]layer.Metadata, error)}

在文件docker\image\fs.go的镜像持久化服务接口:

type StoreBackend interface {    Walk(f DigestWalkFunc) error    Get(id digest.Digest) ([]byte, error)    Set(data []byte) (digest.Digest, error)    Delete(id digest.Digest) error    SetMetadata(id digest.Digest, key string, data []byte) error    GetMetadata(id digest.Digest, key string) ([]byte, error)    DeleteMetadata(id digest.Digest, key string) error}

基本上就是增删改查之类的功能,再看下镜像服务的实现类store和返回该类对象的工厂函数NewImageStore:

type imageMeta struct {    layer    layer.Layer    children map[ID]struct{}}type store struct {    sync.Mutex    ls        LayerGetReleaser    images    map[ID]*imageMeta    fs        StoreBackend    digestSet *digest.Set}// NewImageStore returns new store object for given layer storefunc NewImageStore(fs StoreBackend, ls LayerGetReleaser) (Store, error) {    is := &store{        //实现在/docker/layer/layer_store.go        ls:        ls,        images:    make(map[ID]*imageMeta),        fs:        fs,        digestSet: digest.NewSet(),    }    // load all current images and retain layers    if err := is.restore(); err != nil {        return nil, err    }    return is, nil}

可以看到镜像服务实现类store成员中包含了镜像持久化服务image.StoreBackend和镜像层服务image.LayerGetReleaser,在而且两者是工厂函数的参数,工厂函数利用两个阐述参数传入的对象实现两个成员的初始化。所以我们还需要看下,镜像持久化服务image.StoreBackend和镜像层服务image.LayerGetReleaser的实现类。
镜像持久化服务image.StoreBackend实现类以及工厂函数,在docker\image\fs.go:

// fs implements StoreBackend using the filesystem.type fs struct {    sync.RWMutex    root string}const (    contentDirName  = "content"    metadataDirName = "metadata")// NewFSStoreBackend returns new filesystem based backend for image.Storefunc NewFSStoreBackend(root string) (StoreBackend, error) {    //传入镜像的存储位置  "/var/lib/docker/image/(graphDriver名)/imagedb"    return newFSStore(root)}func newFSStore(root string) (*fs, error) {    s := &fs{        root: root,    }    if err := os.MkdirAll(filepath.Join(root, contentDirName, string(digest.Canonical)), 0700); err != nil {        return nil, err    }    if err := os.MkdirAll(filepath.Join(root, metadataDirName, string(digest.Canonical)), 0700); err != nil {        return nil, err    }    return s, nil}

镜像层服务image.LayerGetReleaser实现类以及工厂函数,实现在docker\layer\layer_store.go:

type layerStore struct {    store  MetadataStore    driver graphdriver.Driver    layerMap map[ChainID]*roLayer    layerL   sync.Mutex    mounts map[string]*mountedLayer    mountL sync.Mutex}// StoreOptions are the options used to create a new Store instancetype StoreOptions struct {    StorePath                 string    MetadataStorePathTemplate string    GraphDriver               string    GraphDriverOptions        []string    UIDMaps                   []idtools.IDMap    GIDMaps                   []idtools.IDMap    PluginGetter              getter.PluginGetter}// NewStoreFromOptions creates a new Store instance//没有实现RegisterWithDescriptor接口func NewStoreFromOptions(options StoreOptions) (Store, error) {    driver, err := graphdriver.New(        options.StorePath,        options.GraphDriver,        options.GraphDriverOptions,        options.UIDMaps,        options.GIDMaps,        options.PluginGetter)    if err != nil {        return nil, fmt.Errorf("error initializing graphdriver: %v", err)    }    logrus.Debugf("Using graph driver %s", driver)    logrus.Debugf("StorePath :%s", options.StorePath)    fms, err := NewFSMetadataStore(fmt.Sprintf(options.MetadataStorePathTemplate, driver))    if err != nil {        return nil, err    }    return NewStoreFromGraphDriver(fms, driver)}// NewStoreFromGraphDriver creates a new Store instance using the provided// metadata store and graph driver. The metadata store will be used to restore// the Store.

看下他们是如何联系在一起的,这都是在docker\daemon\daemon.go的NewDaemon函数中处理的,看下函数调用过程:
这里写图片描述
看NewDaemon函数的代码片段:

    graphDriver := d.layerStore.DriverName()    //镜像的存储位置"/var/lib/docker/image/(graphDriver名)"    imageRoot := filepath.Join(config.Root, "image", graphDriver)    // Configure and validate the kernels security support    if err := configureKernelSecuritySupport(config, graphDriver); err != nil {        return nil, err    }    logrus.Debugf("Max Concurrent Downloads: %d", *config.MaxConcurrentDownloads)    d.downloadManager = xfer.NewLayerDownloadManager(d.layerStore, *config.MaxConcurrentDownloads)    logrus.Debugf("Max Concurrent Uploads: %d", *config.MaxConcurrentUploads)    d.uploadManager = xfer.NewLayerUploadManager(*config.MaxConcurrentUploads)        //传入镜像的存储位置  "/var/lib/docker/image/(graphDriver名)/imagedb"    ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))    if err != nil {        return nil, err    }

在执行NewFSStoreBackend时,传入镜像信息的存储位置config.Root+/image/(graphDriver名)/imagedb,config.Root默认为/var/lib/docker,也就是镜像信息存储位置为”/var/lib/docker/image/(graphDriver名)/imagedb”:
在文件docker\daemon\config.go的InstallCommonFlags函数:

flags.StringVarP(&config.Root, "graph", "g", defaultGraph, "Root of the Docker runtime")

以及docker\daemon\config_unix.go:

var (    defaultPidFile  = "/var/run/docker.pid"    defaultGraph    = "/var/lib/docker"    defaultExecRoot = "/var/run/docker")

如我启用的存储驱动为overlay,存储位置为”/var/lib/docker/image/overlay/imagedb”:
这里写图片描述

0 0
原创粉丝点击