kaniko源碼走讀

kaniko是一個通過Dockerfile構(gòu)建鏡像的工具浑彰,是OCI image標(biāo)準(zhǔn)的一個實現(xiàn)拯辙、功能單一郭变、代碼量相對較少颜价,了解kaniko源碼實現(xiàn)可以更好的理解容器鏡像的構(gòu)建方法和構(gòu)建流程。

基本流程

主程序入口kaniko/cmd/root.go诉濒,實現(xiàn)基于Cobra的命令行(cli)交互接口周伦,解析命令行輸入構(gòu)建參數(shù),傳入executor.DoBuild(opts)方法并執(zhí)行鏡像構(gòu)建過程未荒,然后執(zhí)行executor.DoPush(image, opts)將構(gòu)建好的鏡像push到鏡像倉庫专挪。

鏡像構(gòu)建核心方法

DoBuild方法是構(gòu)建核心方法:

func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
        // 調(diào)用buildkit的stage docker-file解析代碼,方法解析得到buildkit的stages
    stages, metaArgs, err := dockerfile.ParseStages(opts)
       // 轉(zhuǎn)化為kaniko內(nèi)部config.KanikoStage結(jié)構(gòu)
    kanikoStages, err := dockerfile.MakeKanikoStages(opts, stages, metaArgs)
        ...
        ...
    for index, stage := range kanikoStages {
        // 構(gòu)建 stageBuilder
        sb, err := newStageBuilder(opts, stage, crossStageDependencies, digestToCacheKey, stageIdxToDigest, stageNameToIdx, fileContext)
        // 執(zhí)行build
        sb.build()
    }
    ....
}
func (s *stageBuilder) build() error {
    // Take initial snapshot if command does not expect to return
    // a list of files.
    // 對 RunCommand (對應(yīng)docker-file中run)無法直接得到變化的文件要執(zhí)行全局Snapshot對比掃描來獲取變化的文件(change-sets)片排。
    s.initSnapshotWithTimings()
    // 對于其他類型的command寨腔,執(zhí)行命令
    if err := command.ExecuteCommand(&s.cf.Config, s.args); err != nil {
        return errors.Wrap(err, "failed to execute command")
    }
      // 得到要執(zhí)行快照的文件
    files = command.FilesToSnapshot()
    // 通過Snapshotter對這些文件執(zhí)行Snapshot,將變化的文件通過tarball寫入tar文件
    tarPath, err := s.takeSnapshot(files, command.ShouldDetectDeletedFiles())
    // 通過tar文件構(gòu)建鏡像率寡。
    s.saveSnapshotToImage(command.String(), tarPath);
}
func (s *stageBuilder) saveSnapshotToImage(createdBy string, tarPath string) error {
    layer, err := s.saveSnapshotToLayer(tarPath)
        ...
        ...
    return s.saveLayerToImage(layer, createdBy)
}

func (s *stageBuilder) saveSnapshotToLayer(tarPath string) (v1.Layer, error) {
       
    layer, err := tarball.LayerFromFile(tarPath, tarball.WithCompressedCaching)

    return layer, nil
}

func (s *stageBuilder) saveLayerToImage(layer v1.Layer, createdBy string) error {
    var err error
    s.image, err = mutate.Append(s.image,
        mutate.Addendum{
            Layer: layer,
            History: v1.History{
                Author:    constants.Author,
                CreatedBy: createdBy,
            },
        },
    )
    return err
}

基本數(shù)據(jù)結(jié)構(gòu)

一個muti-stage的docker-file,會被轉(zhuǎn)成對應(yīng)的Stage列表,Stage則是由多個由docker-file中的命令解析轉(zhuǎn)化而成Command結(jié)構(gòu)組成。

type Stage struct {
    Name       string
    Commands   []Command
    BaseName   string
    SourceCode string
    Platform   string
}

文件列表快照實現(xiàn)

kaniko是通過計算文件的hash值來判斷當(dāng)前文件是否變化,核心是計算hash的算法法結(jié)構(gòu)

func getHasher(snapshotMode string) (func(string) (string, error), error) {
    switch snapshotMode {
    case constants.SnapshotModeTime:
        logrus.Info("Only file modification time will be considered when snapshotting")
        return util.MtimeHasher(), nil
    case constants.SnapshotModeFull:
        return util.Hasher(), nil
    case constants.SnapshotModeRedo:
        return util.RedoHasher(), nil
    default:
        return nil, fmt.Errorf("%s is not a valid snapshot mode", snapshotMode)
    }
}

通過工廠方法獲取對應(yīng)算法的Hasher伊佃,然后通過計算比較hash值來比較文件是否被修改,如果被修改就存入NewLayeredMap

type LayeredMap struct {
    layers         []map[string]string
    whiteouts      []map[string]struct{}
    layerHashCache map[string]string
    hasher         func(string) (string, error)
    // cacheHasher doesn't include mtime in it's hash so that filesystem cache keys are stable
    cacheHasher func(string) (string, error)
}

為鏡像的邏輯結(jié)構(gòu),方便得到文件變化列表(change-sets)斯议。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恋昼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辟宗,更是在濱河造成了極大的恐慌容客,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芥丧,死亡現(xiàn)場離奇詭異,居然都是意外死亡物遇,警方通過查閱死者的電腦和手機起趾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門冷蚂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隆夯,“玉大人厘肮,你說我怎么就攤上這事耍属【た蓿” “怎么了煮仇?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵夹姥,是天一觀的道長。 經(jīng)常有香客問我旦部,道長,這世上最難降的妖魔是什么蝗茁? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任柑肴,我火速辦了婚禮硕舆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己叼架,他們只是感情好贴届,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布牲距。 她就那樣靜靜地躺著难述,像睡著了一般。 火紅的嫁衣襯著肌膚如雪择葡。 梳的紋絲不亂的頭發(fā)上妥箕,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天黍瞧,我揣著相機與錄音,去河邊找鬼脑溢。 笑死壶谒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捌木,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拥峦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起玄柠,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤这弧,失蹤者是張志新(化名)和其女友劉穎匾浪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡托酸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年拴鸵,在試婚紗的時候發(fā)現(xiàn)自己被綠了聘芜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秕重。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖厉膀,靈堂內(nèi)的尸體忽然破棺而出溶耘,到底是詐尸還是另有隱情,我是刑警寧澤服鹅,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布凳兵,位于F島的核電站,受9級特大地震影響企软,放射性物質(zhì)發(fā)生泄漏庐扫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望形庭。 院中可真熱鬧铅辞,春花似錦、人聲如沸萨醒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽富纸。三九已至囤踩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晓褪,已是汗流浹背堵漱。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涣仿,地道東北人勤庐。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像好港,于是被迫代替她去往敵國和親埃元。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容