Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コードを読んで理解するko build

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for bells17 bells17
February 19, 2025

コードを読んで理解するko build

Avatar for bells17

bells17

February 19, 2025
Tweet

More Decks by bells17

Other Decks in Programming

Transcript

  1. ▶ @bells 1 7 ▶ Software Engineer@ 3 -shake inc.

    ▶ CNCF Ambassadors ▶ Kubernetes Novice Tokyo Organizer ▶ X(Twitter): @bells 1 7 _ ▶ GitHub: @bells 1 7
  2. ko ▶ GoアプリケーションをDocker fi le無しでコンテナ化してくれるツール ▶ Googleが開発→現在はCNCF Sandboxプロジェクト化 ▶ cgoやOSパッケージの依存関係がない単

    一 の Go アプリケーションが対象 ▶ Dockerなどのコンテナランタイム不要でイメージビルドが可能 ▶ Goアプリケーションのビルドは 手 元環境のgoコマンドに依存 ▶ ko本体に加えて、GitHub ActionsとTerraform Providerを提供 今回の検証バージョンは0.17.1となります
  3. $ gcloud auth con fi gure-docker asia-northeast 1 -docker.pkg.dev {

    "credHelpers": { "asia-northeast 1 -docker.pkg.dev": "gcloud" } } Adding credentials for: asia-northeast 1 -docker.pkg.dev gcloud credential helpers already registered correctly. 事前にレジストリの認証を 行 う
  4. $ KO_DOCKER_REPO=asia-northeast 1 -docker.pkg.dev/xxx/ko-sample ko build . 2 0 2

    5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Using base cgr.dev/chainguard/ static:latest@sha 2 5 6 : 8 5 3 bfd 4 4 9 5 abb 4 b 6 5 ede 8 fc 9 3 3 2 5 1 3 ca 2 6 2 6 2 3 5 5 8 9 c 2 cef 5 9 b 4 fce 5 0 8 2 d 0 8 3 6 d for ko-sample 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 git doesn't contain any tags. Tag info will not be available git is in a dirty state Please check in your pipeline what can be changing the following fi les: M main.go 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Building ko-sample for linux/amd 6 4 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Publishing asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample- 0 e 7 4 e 5 a 8 7 2 2 1 dc 7 fa 8 3 7 ed 7 da 0 8 8 dd 4 c:latest … 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Published SBOM asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample- 0 e 7 4 e 5 a 8 7 2 2 1 dc 7 fa 8 3 7 ed 7 da 0 8 8 dd 4 c:sha 2 5 6 - eae 3 0 b 0 0 dae 2 b 2 fee 4 d 0 c 9 6 7 e 9 ece 7 0 c 5 f 0 d 6 c 8 6 6 b 6 e 2 9 f 7 bda 5 c 3 4 9 cf 6 3 3 0 6 b.sbom 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Published asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample- 0 e 7 4 e 5 a 8 7 2 2 1 dc 7 fa 8 3 7 ed 7 da 0 8 8 dd 4 c@sha 2 5 6 :eae 3 0 b 0 0 dae 2 b 2 fee 4 d 0 c 9 6 7 e 9 ece 7 0 c 5 f 0 d 6 c 8 6 6 b 6 e 2 9 f 7 bda 5 c 3 4 9 cf 6 3 3 0 6 b asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample- 0 e 7 4 e 5 a 8 7 2 2 1 dc 7 fa 8 3 7 ed 7 da 0 8 8 dd 4 c@sha 2 5 6 :eae 3 0 b 0 0 dae 2 b 2 fee 4 d 0 c 9 6 7 e 9 ece 7 0 c 5 f 0 d 6 c 8 6 6 b 6 e 2 9 f 7 bda 5 c 3 4 9 cf 6 3 3 0 6 b KO_DOCKER_REPOでレジストリを指定して ko build を実 行 してイメージビルド & push buildサブコマンドだけどデフォルトでpushするしSBOM情報もpushする
  5. $ KO_DOCKER_REPO=asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample \ ko build --bare --tags v

    1 . 0 . 0 ,latest . ... asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample@sha 2 5 6 :eae 3 0 b 0 0 dae 2 b 2 fee 4 d 0 c 9 6 7 e 9 ece 7 0 c 5 f 0 d 6 c 8 6 6 b 6 e 2 9 f 7 bda 5 c 3 4 9 cf 6 3 3 0 6 b イメージ名を固定したい場合は --bare オプションを使 用 ここでは --tags も指定してる
  6. $ KO_DEFAULTBASEIMAGE=gcr.io/distroless/static \ KO_DOCKER_REPO=asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample \ ko build --bare

    --tags v 1 . 0 . 0 ,latest . 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Using base gcr.io/distroless/ static@sha 2 5 6 : 3 f 2 b 6 4 ef 9 7 bd 2 8 5 e 3 6 1 3 2 c 6 8 4 e 6 b 2 ae 8 f 2 7 2 3 2 9 3 d 0 9 aae 0 4 6 1 9 6 cca 6 4 2 5 1 acac for ko-sample 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 git doesn't contain any tags. Tag info will not be available git is in a dirty state Please check in your pipeline what can be changing the following fi les: M main.go ... asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample@sha 2 5 6 :c 2 bdbc 2 3 0 2 a 4 3 c 1 4 6 5 d 1 6 d 8 2 4 9 fae 6 9 9 b 7 b 8 f 1 1 9 2 d 8 b 0 d 2 5 9 9 9 9 4 5 7 3 e 1 ae 6 b 1 8 ベースイメージを変えたい場合はKO_DEFAULTBASEIMAGEを使 用
  7. $ cosign download sbom asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample:v 1 . 0

    . 0 { "SPDXID": "SPDXRef-DOCUMENT", "name": "sbom- sha 2 5 6 :c 2 bdbc 2 3 0 2 a 4 3 c 1 4 6 5 d 1 6 d 8 2 4 9 fae 6 9 9 b 7 b 8 f 1 1 9 2 d 8 b 0 d 2 5 9 9 9 9 4 5 7 3 e 1 ae 6 b 1 8 ", "spdxVersion": "SPDX- 2 . 3 ", "creationInfo": { "created": " 0 0 0 1 - 0 1 - 0 1 T 0 0 : 0 0 : 0 0 Z", "creators": [ "Tool: ko 0 . 1 7 . 1 " ] }, ... cosign download sbomでSBOM情報を確認する Cosignはsigstoreプロジェクトが提供するコマンドラインツール(主にイメージ署名 用 のツール)
  8. $ KO_DEFAULTBASEIMAGE=gcr.io/distroless/static KO_DEFAULTPLATFORMS=darwin/arm 6 4 \ KO_DOCKER_REPO=asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample \

    ko build --bare --local --tags v 1 . 0 . 0 ,latest . 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Using base gcr.io/distroless/ static@sha 2 5 6 : 3 f 2 b 6 4 ef 9 7 bd 2 8 5 e 3 6 1 3 2 c 6 8 4 e 6 b 2 ae 8 f 2 7 2 3 2 9 3 d 0 9 aae 0 4 6 1 9 6 cca 6 4 2 5 1 acac for ko-sample … 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Building ko-sample for darwin/arm 6 4 /v 8 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Loading asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample: 0 2 6 8 2 5 d 4 b 4 3 8 f 0 ce 0 c 4 7 1 d 9 d 2 0 0 8 1 6 2 c 9 ea 7 8 e 2 7 e 5 0 8 9 3 cfbbdee 5 7 6 6 0 8 b 8 2 4 4 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Loaded asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample: 0 2 6 8 2 5 d 4 b 4 3 8 f 0 ce 0 c 4 7 1 d 9 d 2 0 0 8 1 6 2 c 9 ea 7 8 e 2 7 e 5 0 8 9 3 cfbbdee 5 7 6 6 0 8 b 8 2 4 4 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Adding tag v 1 . 0 . 0 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Added tag v 1 . 0 . 0 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Adding tag latest 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Added tag latest asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample: 0 2 6 8 2 5 d 4 b 4 3 8 f 0 ce 0 c 4 7 1 d 9 d 2 0 0 8 1 6 2 c 9 ea 7 8 e 2 7 e 5 0 8 9 3 cfbbdee 5 7 6 6 0 8 b 8 2 4 4 --localオプションを付けるとイメージをローカルに保存してくれる Arm系のMacで動くようにこちらも指定: KO_DEFAULTPLATFORMS=linux/arm 6 4
  9. $ docker images asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample REPOSITORY TAG IMAGE ID

    CREATED SIZE asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample 0 2 6 8 2 5 d 4 b 4 3 8 f 0 ce 0 c 4 7 1 d 9 d 2 0 0 8 1 6 2 c 9 ea 7 8 e 2 7 e 5 0 8 9 3 cfbbdee 5 7 6 6 0 8 b 8 2 4 4 ec 4 6 c 4 6 c 6 5 1 0 N/A 3 . 9 3 MB asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample latest ec 4 6 c 4 6 c 6 5 1 0 N/A 3 . 9 3 MB asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko-sample v 1 . 0 . 0 ec 4 6 c 4 6 c 6 5 1 0 N/A 3 . 9 3 MB $ docker run --rm asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample:v 1 . 0 . 0 Hello World! イメージがローカルにあることが確認できる
  10. cat << EOF > .ko.yaml defaultBaseImage: gcr.io/distroless/static EOF KO_DOCKER_REPO=asia-northeast 1

    -docker.pkg.dev/xxx/ko-sample/ko-sample \ ko build . --bare --tags v 2 . 0 . 0 2 0 2 5 / 0 1 / 0 1 0 0 : 0 0 : 0 0 Using base gcr.io/distroless/ static@sha 2 5 6 : 3 f 2 b 6 4 ef 9 7 bd 2 8 5 e 3 6 1 3 2 c 6 8 4 e 6 b 2 ae 8 f 2 7 2 3 2 9 3 d 0 9 aae 0 4 6 1 9 6 cca 6 4 2 5 1 acac for ko-sample ... asia-northeast 1 -docker.pkg.dev/xxx/ko-sample/ko- sample:v 2 . 0 . 0 @sha 2 5 6 :c 2 bdbc 2 3 0 2 a 4 3 c 1 4 6 5 d 1 6 d 8 2 4 9 fae 6 9 9 b 7 b 8 f 1 1 9 2 d 8 b 0 d 2 5 9 9 9 9 4 5 7 3 e 1 ae 6 b 1 8 .ko.yaml でオプションを設定ファイル化することも可能 KO_DOCKER_REPO は設定ファイル化できない模様
  11. defaultBaseImage: gcr.io/distroless/static defaultPlatforms: - linux/arm 6 4 - linux/amd 6

    4 - darwin/arm 6 4 - darwin/amd 6 4 defaultEnv: - FOO=foo defaultLd fl ags: - -s 結構いろんなオプションを設定することが可能 ちなみにコンテナ内のENVを設定する 方 法はなさそうだった(個 人 的にはこれが気になる)
  12. ko buildでできること 下記のようにコンテナイメージを build & pushしてくれる ▶ cgr.dev/chainguard/static イメージを利 用

    (変更可能) ▶ Goのアプリケーションのビルド時のフラグや環境変数を設定可能 ▶ (KO_DATA_PATHを設定することで)static fi leをコンテナに設定可能 ▶ Multi Platformなイメージビルドをサポート(デフォルトはlinux/amd 6 4 ) ▶ SBOMを 生 成~レジストリにpushしてくれる(—sbom=noneで無効化可能) ▶ ローカルにもビルドしたイメージを保存可能(—localを使 用 ) ▶ Goのデバッガをプログラムに設定可能(—debugを使 用 ) ▶ 生 成するイメージのmetadataを設定可能(—image-xxxを使 用 ) 主要な設定はこのあたり
  13. $ cd /path/to/dir $ git clone [email protected]:ko-build/ko.git $ git checkout

    v 0 . 1 7 . 1 cloneして指定バージョンに切り替え
  14. まず全体像を掴むためにpublishImagesの中 身 から pkg/commands/publisher.go やってること ▶ ビルドなどを実 行 するパス単位で 処理を実

    行 (for) ▶ 対象ディレクトリのパッケージ チェック ▶ イメージのビルド ▶ イメージのpush
  15. 再掲 pkg/commands/publisher.go やってること ▶ ビルドなどを実 行 するパス単位で 処理を実 行 (for)

    ▶ 対象ディレクトリのパッケージ チェック ▶ イメージのビルド ▶ イメージのpush
  16. *Cacheing.Build pkg/build/shared.go ざっくり説明 newFeatureの引数に渡した関数を goroutineで 非 同期に実 行 して その結果をchannelで受け取れる形で

    c.inner.Buildを実 行 してる ↓ この中でc.inner.Buildを実 行 してる ↓ c.inner.Buildがビルド処理の実体
  17. *gobuild.Build pkg/build/gobuild.go (わかりやすさのため 一 部コードを削ってます) ざっくり説明 ▶ ベースイメージを取得 (デフォルトはcgr.dev/chainguard/static) ▶

    マルチプラットフォーム向けビルド かどうかで処理分岐 ▶ 今回は簡単にするために単 一 プラット フォームだった場合で話を進めます → g.buildOneが実 行 される場合 (g.buildAllもループして中でg.buildOneを 実 行 してるだけ)
  18. build編まとめ 主に下記のようなことを 行 いイメージを作成している ▶ Goアプリケーションのビルド設定を整える(環境変数やGoの fl agなど) ▶ 手

    元のgoバイナリを使 用 してアプリケーションをビルド ▶ KO_DATA_PATHで設定したstatic assetsをレイヤーとして追加 ▶ ビルドしたバイナリをレイヤーとして追加 ▶ (Optional)デバッガーをレイヤーとして追加 ▶ entrypointなどのmetadataをイメージに追加 ▶ (Optional)SBOM情報を追加 ということでコンテナのデフォルト環境変数などを設定する余地はなさそうだった(ベースイメージで設定するしかなさそう)
  19. 再掲 pkg/commands/publisher.go やってること ▶ ビルドなどを実 行 するパス単位で 処理を実 行 (for)

    ▶ 対象ディレクトリのパッケージ チェック ▶ イメージのビルド ▶ イメージのpush
  20. 今回調べてみての感想 ▶ Buildpackとかもそうだけど、Docker fi le無しでどうやってコンテナイメージを作ってるの か気になっていたけど中 身 をみたら意外と愚直にgo buildしたりしてて「ですよね」とい う気持ちになった(それも含めて勉強になった)

    ▶ google/go-containerregistryを使 用 してコンテナランタイム無しでコンテナイメージを 作っていくのが 面白 かった koのコードを 見 て頭に 入 る部分が増えたので、これをきっかけに改めて opencontainers/image-spec を眺めてみたい ▶ 簡単に使えて便利な 一方 で、設定できる項 目 は結構限られているなという印象だった (Goアプリケーションのビルド設定以外はあまり 自 由度が無い)
  21. 参考リンク ・ 画像など引 用 元 一 覧 ▶ https://ko.build/ ▶

    https://github.com/ko-build/ko ▶ https://github.com/google/go-containerregistry ▶ https://github.com/sigstore/cosign ▶ https://github.com/opencontainers/image-spec ▶ https://github.com/cncf/sandbox/issues/ 1 7 ▶ https://github.com/ko-build/ko/issues/ 7 9 1 ▶ https://github.com/cncf/sandbox/issues/ 1 6 3 ▶ https://github.com/cncf/artwork/blob/main/projects/ko/stacked/color/ko-stacked- color.png ▶ https://github.com/cncf/artwork/blob/main/projects/ko/icon/color/ko-icon-color.png