1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Containerd 中的 Snapshot 到底是個(gè)什么鬼?

        共 5895字,需瀏覽 12分鐘

         ·

        2020-12-27 21:08


        更多奇技淫巧歡迎訂閱博客:https://fuckcloudnative.io

        先問大家問題,containerd 的 snapshot 是什么鬼?難道是給容器做快照的嗎?

        答案是:是也不是

        為什么說是呢?它的確可以實(shí)現(xiàn)部分快照的功能,但他和常規(guī)意義的虛擬機(jī)快照又不是一回事。


        我們先看一下 containerd 是干嘛的?譬如我們拉鏡像

        可以看到 snapshot 的服務(wù)作用是準(zhǔn)備 rootfs 的,就是通過 mount 各個(gè)層,提供容器的 rootfs。所有。content 只是保存 tar 和 mainfest 和 config 文件的,是 OCI 那套東西,我們需要將他們逐一解壓、mount 后提供給容器。

        所以 push 操作就和 snapshot 沒有毛關(guān)系了。如下所示:

        當(dāng)我們理解 snapshot 是干嘛的以后,可以通過源碼看一下 containerd 目前的 snapshot 有哪些實(shí)現(xiàn):

        那么大家可能又有疑惑了,為啥他們可以加入 snapshot,因?yàn)檫@些文件系統(tǒng)都有一個(gè)共同的特性就是:支持快照。這就是這個(gè)模塊的名稱叫做 snapshot 了。每個(gè)文件系統(tǒng)的接入就需要實(shí)現(xiàn)下面的接口。

        type?Snapshotter?interface?{
        ?//?Stat?returns?the?info?for?an?active?or?committed?snapshot?by?name?or
        ?//?key.
        ?//
        ?//?Should?be?used?for?parent?resolution,?existence?checks?and?to?discern
        ?//?the?kind?of?snapshot.
        ?Stat(ctx?context.Context,?key?string)?(Info,?error)

        ?//?Update?updates?the?info?for?a?snapshot.
        ?//
        ?//?Only?mutable?properties?of?a?snapshot?may?be?updated.
        ?Update(ctx?context.Context,?info?Info,?fieldpaths?...string)?(Info,?error)

        ?//?Usage?returns?the?resource?usage?of?an?active?or?committed?snapshot
        ?//?excluding?the?usage?of?parent?snapshots.
        ?//
        ?//?The?running?time?of?this?call?for?active?snapshots?is?dependent?on
        ?//?implementation,?but?may?be?proportional?to?the?size?of?the?resource.
        ?//?Callers?should?take?this?into?consideration.?Implementations?should
        ?//?attempt?to?honer?context?cancellation?and?avoid?taking?locks?when?making
        ?//?the?calculation.
        ?Usage(ctx?context.Context,?key?string)?(Usage,?error)

        ?//?Mounts?returns?the?mounts?for?the?active?snapshot?transaction?identified
        ?//?by?key.?Can?be?called?on?an?read-write?or?readonly?transaction.?This?is
        ?//?available?only?for?active?snapshots.
        ?//
        ?//?This?can?be?used?to?recover?mounts?after?calling?View?or?Prepare.
        ?Mounts(ctx?context.Context,?key?string)?([]mount.Mount,?error)

        ?//?Prepare?creates?an?active?snapshot?identified?by?key?descending?from?the
        ?//?provided?parent.??The?returned?mounts?can?be?used?to?mount?the?snapshot
        ?//?to?capture?changes.
        ?//
        ?//?If?a?parent?is?provided,?after?performing?the?mounts,?the?destination
        ?//?will?start?with?the?content?of?the?parent.?The?parent?must?be?a
        ?//?committed?snapshot.?Changes?to?the?mounted?destination?will?be?captured
        ?//?in?relation?to?the?parent.?The?default?parent,?"",?is?an?empty
        ?//?directory.
        ?//
        ?//?The?changes?may?be?saved?to?a?committed?snapshot?by?calling?Commit.?When
        ?//?one?is?done?with?the?transaction,?Remove?should?be?called?on?the?key.
        ?//
        ?//?Multiple?calls?to?Prepare?or?View?with?the?same?key?should?fail.
        ?Prepare(ctx?context.Context,?key,?parent?string,?opts?...Opt)?([]mount.Mount,?error)

        ?//?View?behaves?identically?to?Prepare?except?the?result?may?not?be
        ?//?committed?back?to?the?snapshot?snapshotter.?View?returns?a?readonly?view?on
        ?//?the?parent,?with?the?active?snapshot?being?tracked?by?the?given?key.
        ?//
        ?//?This?method?operates?identically?to?Prepare,?except?that?Mounts?returned
        ?//?may?have?the?readonly?flag?set.?Any?modifications?to?the?underlying
        ?//?filesystem?will?be?ignored.?Implementations?may?perform?this?in?a?more
        ?//?efficient?manner?that?differs?from?what?would?be?attempted?with
        ?//?`Prepare`.
        ?//
        ?//?Commit?may?not?be?called?on?the?provided?key?and?will?return?an?error.
        ?//?To?collect?the?resources?associated?with?key,?Remove?must?be?called?with
        ?//?key?as?the?argument.
        ?View(ctx?context.Context,?key,?parent?string,?opts?...Opt)?([]mount.Mount,?error)

        ?//?Commit?captures?the?changes?between?key?and?its?parent?into?a?snapshot
        ?//?identified?by?name.??The?name?can?then?be?used?with?the?snapshotter's?other
        ?//?methods?to?create?subsequent?snapshots.
        ?//
        ?//?A?committed?snapshot?will?be?created?under?name?with?the?parent?of?the
        ?//?active?snapshot.
        ?//
        ?//?After?commit,?the?snapshot?identified?by?key?is?removed.
        ?Commit(ctx?context.Context,?name,?key?string,?opts?...Opt)?error

        ?//?Remove?the?committed?or?active?snapshot?by?the?provided?key.
        ?//
        ?//?All?resources?associated?with?the?key?will?be?removed.
        ?//
        ?//?If?the?snapshot?is?a?parent?of?another?snapshot,?its?children?must?be
        ?//?removed?before?proceeding.
        ?Remove(ctx?context.Context,?key?string)?error

        ?//?Walk?will?call?the?provided?function?for?each?snapshot?in?the
        ?//?snapshotter?which?match?the?provided?filters.?If?no?filters?are
        ?//?given?all?items?will?be?walked.
        ?//?Filters:
        ?//??name
        ?//??parent
        ?//??kind?(active,view,committed)
        ?//??labels.(label)
        ?Walk(ctx?context.Context,?fn?WalkFunc,?filters?...string)?error

        ?//?Close?releases?the?internal?resources.
        ?//
        ?//?Close?is?expected?to?be?called?on?the?end?of?the?lifecycle?of?the?snapshotter,
        ?//?but?not?mandatory.
        ?//
        ?//?Close?returns?nil?when?it?is?already?closed.
        ?Close()?error
        }

        當(dāng)我們通過 pull 下載鏡像的時(shí)候就會(huì) apply 每一層:

        func?applyLayers(ctx?context.Context,?layers?[]Layer,?chain?[]digest.Digest,?sn?snapshots.Snapshotter,?a?diff.Applier,?opts?[]snapshots.Opt,?applyOpts?[]diff.ApplyOpt)?error?{

        ??mounts,?err?=?sn.Prepare(ctx,?key,?parent.String(),?opts...)

        ?diff,?err?=?a.Apply(ctx,?layer.Blob,?mounts,?applyOpts...)


        ?if?err?=?sn.Commit(ctx,?chainID.String(),?key,?opts...);?err?!=?nil?{
        ??err?=?errors.Wrapf(err,?"failed?to?commit?snapshot?%s",?key)
        ??return?err
        ?}

        ?return?nil
        }

        通過 prepare --> apply --> commit 三步完成 layer 的構(gòu)建。其中 prepare 只返回了具體 mount 列表,并不做具體的 mount 擦著,具體實(shí)現(xiàn)在 apply 這個(gè)方法:

        func?apply(ctx?context.Context,?mounts?[]mount.Mount,?r?io.Reader)?error?{
        ?return?mount.WithTempMount(ctx,?mounts,?func(root?string)?error?{
        ??_,?err?:=?archive.Apply(ctx,?root,?r)
        ??return?err
        ?})
        }

        其中 archive.Apply 就是解壓 tar 包寫層的”archive/tar.go“

        func?applyNaive(ctx?context.Context,?root?string,?tr?*tar.Reader,?options?ApplyOptions)?(size?int64,?err?error)?{
        .?.?.

        總結(jié)一下,snapshot 目的是為了給容器的提供 rootfs,通過實(shí)現(xiàn) snapshot 的接口,就可以接入不同的具有快照功能的文件系統(tǒng)。


        原文鏈接:https://blog.csdn.net/u010278923/article/details/111721116



        你可能還喜歡

        點(diǎn)擊下方圖片即可閱讀

        WireGuard 真的很香嗎?香個(gè)屁!

        云原生是一種信仰??



        碼關(guān)注公眾號(hào)

        后臺(tái)回復(fù)?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!



        點(diǎn)擊?"閱讀原文"?獲取更好的閱讀體驗(yàn)!

        ??給個(gè)「在看」,是對(duì)我最大的支持??
        瀏覽 54
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            我和公疯狂做的过程 | 很操逼| 美女操逼网站免费 | 翔田千里中文字幕 | 伊人大香蕉精品 | 亚洲五区| 成人网站视频在线观看 | 欧美三级毛片 | 澳门无码视频 | 日韩免费精品一区二区三区色欲AV |