Repository: GoogleContainerTools/skaffold
Pull request #7142 (2022-02-23 09:33:43)

feat: cross-platform support with kaniko builder
<!-- Thank you for your contribution! -->

<!-- Include if applicable: -->
Related: #6120 <!-- tracking issues that this PR will close -->


codecov[bot]: # [Codecov](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) Report
> Merging [#7142](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) (41e32d1) into [main](https://codecov.io/gh/GoogleContainerTools/skaffold/commit/290280e8c6c19231e9ed5b5c027f2c01d22f75be?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) (290280e) will **decrease** coverage by `2.13%`.
> The diff coverage is `56.96%`.

[![Impacted file tree graph](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/graphs/tree.svg?width=650&height=150&src=pr&token=mVPJs21wYu&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools)](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools)

```diff
@@            Coverage Diff             @@
##             main    #7142      +/-   ##
==========================================
- Coverage   70.48%   68.34%   -2.14%     
==========================================
  Files         515      560      +45     
  Lines       23150    26255    +3105     
==========================================
+ Hits        16317    17944    +1627     
- Misses       5776     7069    +1293     
- Partials     1057     1242     +185     
```


| [Impacted Files](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) | Coverage Δ | |
|---|---|---|
| [cmd/skaffold/app/cmd/deploy.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvZGVwbG95Lmdv) | `52.00% <ø> (-1.85%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/dev.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvZGV2Lmdv) | `84.61% <0.00%> (ø)` | |
| [cmd/skaffold/app/cmd/render.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvcmVuZGVyLmdv) | `36.66% <0.00%> (-4.72%)` | :arrow_down: |
| [cmd/skaffold/skaffold.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL3NrYWZmb2xkLmdv) | `0.00% <0.00%> (ø)` | |
| [cmd/skaffold/app/cmd/inspect\_tests.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvaW5zcGVjdF90ZXN0cy5nbw==) | `62.50% <14.28%> (-1.14%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/lsp.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvbHNwLmdv) | `28.12% <28.12%> (ø)` | |
| [cmd/skaffold/app/cmd/fix.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvZml4Lmdv) | `68.85% <40.00%> (-7.62%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/lint.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvbGludC5nbw==) | `42.85% <42.85%> (ø)` | |
| [cmd/skaffold/app/cmd/find\_configs.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvZmluZF9jb25maWdzLmdv) | `48.88% <50.00%> (+0.24%)` | :arrow_up: |
| [cmd/skaffold/app/skaffold.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9za2FmZm9sZC5nbw==) | `76.19% <70.00%> (-8.43%)` | :arrow_down: |
| ... and [214 more](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools). Last update [b5bc250...41e32d1](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7142?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools).


Patch:
diff --git a/docs/content/en/docs/pipeline-stages/builders/_index.md b/docs/content/en/docs/pipeline-stages/builders/_index.md
index 3c0f71e13..9be23b86f 100644
--- a/docs/content/en/docs/pipeline-stages/builders/_index.md
+++ b/docs/content/en/docs/pipeline-stages/builders/_index.md
@@ -184,13 +184,13 @@ The final list of target platforms need to ultimately be supported by the target
 
 |    | Local Build | In Cluster Build | Remote on Google Cloud Build |
 |----|:-----------:|:----------------:|:----------------------------:|
-| **Dockerfile** | Cross platform supported | Cross platform supported but platform should match cluster node running the pod. Not yet implemented | Cross platform supported |
+| **Dockerfile** | Cross platform supported | Cross platform supported but platform should match cluster node running the pod. | Cross platform supported |
 | **Jib Maven and Gradle** | Cross platform supported | - | Cross platform supported |
 | **Cloud Native Buildpacks** | Only supports `linux/amd64` | - | Only supports `linux/amd64` |
 | **Bazel** | Cross platform supported but requires explicit platform specific rules. Not yet implemented | - | - |
 | **ko** | Cross platform supported | - | - |
-| **Custom Script** | Cross platform supported but requires user to implement it in the build script | Can support. Not yet implemented | - |
+| **Custom Script** | Cross platform supported but requires user to implement it in the build script | Cross platform supported but requires user to implement it in the build script | - |
 
 {{< alert title="Note" >}}
-Multi-arch image build is not yet supported for any builders other than the [jib builder]({{<relref "/docs/pipeline-stages/builders/jib" >}}) and [custom builder]({{<relref "/docs/pipeline-stages/builders/custom" >}}) in Skaffold 
+Multi-arch image build is not yet supported for any builders other than the [jib builder]({{<relref "/docs/pipeline-stages/builders/jib" >}}), the [ko builder]({{<relref "/docs/pipeline-stages/builders/ko">}}) and the [custom builder]({{<relref "/docs/pipeline-stages/builders/custom" >}}) in Skaffold. 
 {{< /alert >}}
\ No newline at end of file
diff --git a/docs/content/en/docs/pipeline-stages/init.md b/docs/content/en/docs/pipeline-stages/init.md
index a6939f4ea..91223a23f 100644
--- a/docs/content/en/docs/pipeline-stages/init.md
+++ b/docs/content/en/docs/pipeline-stages/init.md
@@ -16,8 +16,8 @@ and [deploy](#deploy-config-initialization) config.
 `skaffold init` currently supports build detection for those builders:
 
 1. [Docker]({{<relref "/docs/pipeline-stages/builders/docker">}})
-2. [Jib]({{<relref "/docs/pipeline-stages/builders/jib">}}) (with `--XXenableJibInit` flag)
-2. [Buildpacks]({{<relref "/docs/pipeline-stages/builders/buildpacks">}}) (with `--XXenableBuildpacksInit` flag)
+2. [Jib]({{<relref "/docs/pipeline-stages/builders/jib">}})
+2. [Buildpacks]({{<relref "/docs/pipeline-stages/builders/buildpacks">}})
 
 `skaffold init` walks your project directory and looks for any build configuration files such as `Dockerfile`,
 `build.gradle/pom.xml`, `package.json`, `requirements.txt` or `go.mod`. `init` skips files that are larger
@@ -35,18 +35,17 @@ skaffold init
 
 
 {{< alert title="Note" >}}
-You can choose <code>None (image not built from these sources)</code> if none of the suggested 
+You can choose <code>None (image not built from these sources)</code> if none of the suggested
 options are correct, or this image is not built by any of your source code.<br>
 If this image is one you want Skaffold to build, you'll need to manually set up the build configuration for this artifact.
 {{</alert>}}
 
 `skaffold` init also recognizes Maven and Gradle projects, and will auto-suggest the [`jib`]({{<relref "/docs/pipeline-stages/builders#/local#jib-maven-and-gradle">}}) builder.
-Currently `jib` artifact detection is disabled by default, but can be enabled using the flag `--XXenableJibInit`.
 
 You can try this out on our example [jib project](https://github.com/GoogleContainerTools/skaffold/tree/main/examples/jib-multimodule)
 
 ```bash
-skaffold init --XXenableJibInit
+skaffold init
 ```
 
 ![jib-multimodule](/images/jib-multimodule-init-flow.png)
@@ -71,7 +70,7 @@ deploy:
 
 ### kustomize
 For projects deploying with `kustomize`, Skaffold will scan your project and look for `kustomization.yaml`s as well as Kubernetes manifests.
-It will attempt to infer the project structure based on the recommended project structure from the Kustomize project: thus, 
+It will attempt to infer the project structure based on the recommended project structure from the Kustomize project: thus,
 **it is highly recommended to match your project structure to the recommended base/ and overlay/ structure from Kustomize!**
 
 This generally looks like this:
@@ -99,9 +98,9 @@ When overlay directories are found, these will be listed in the generated Skaffo
 
 *Note: order is guaranteed, since Skaffold's directory parsing is always deterministic.*
 
-## `--generate-manifests` Flag 
+## `--generate-manifests` Flag
 {{< maturity "init.generate_manifests" >}}
-`skaffold init` allows for use of a `--generate-manifests` flag, which will try to generate basic kubernetes manifests for a user's project to help get things up and running. 
+`skaffold init` allows for use of a `--generate-manifests` flag, which will try to generate basic kubernetes manifests for a user's project to help get things up and running.
 
 If bringing a project to skaffold that has no kubernetes manifests yet, it may be helpful to run `skaffold init` with this flag.
 
@@ -116,9 +115,9 @@ In a situation where one image is detected, but multiple possible builders are d
 ## Init API
 `skaffold init` also exposes an API which tools like IDEs can integrate with via flags.
 
-This API can be used to 
+This API can be used to
 
-1. Analyze a project workspace and discover all build definitions (e.g. `Dockerfile`s) and artifacts (image names from the Kubernetes manifests) - this then provides an ability for tools to ask the user to pair the artifacts with Dockerfiles interactively. 
+1. Analyze a project workspace and discover all build definitions (e.g. `Dockerfile`s) and artifacts (image names from the Kubernetes manifests) - this then provides an ability for tools to ask the user to pair the artifacts with Dockerfiles interactively.
 2. Given a pairing between the image names (artifacts) and build definitions (e.g. Dockerfiles), generate Skaffold `build` config for a given artifact.
 
 The resulting `skaffold.yaml` will look something like this:
@@ -142,12 +141,12 @@ profiles:
 
 | API | flag | input/output |
 | ---- | --- | --- |
-| Analyze | `--analyze` | json encoded output of builders and images|  
+| Analyze | `--analyze` | json encoded output of builders and images|
 | Generate | `--artifact`| "`=` delimited" build definition/image pair (for example: `=path1/Dockerfile=artifact1`) or <br>JSON string (for example: `{"builder":"Docker","payload":{"path":"Dockerfile"},"image":"artifact")`|
 
 
 ### Analyze API
-Analyze API walks through all files in your project workspace and looks for 
+Analyze API walks through all files in your project workspace and looks for
 `Dockerfile` files.
 
 To get all image names and dockerfiles, run
diff --git a/docs/content/en/schemas/v2beta28.json b/docs/content/en/schemas/v2beta28.json
index 9c954cc65..d04c42f08 100755
--- a/docs/content/en/schemas/v2beta28.json
+++ b/docs/content/en/schemas/v2beta28.json
@@ -1526,8 +1526,8 @@
         },
         "noCache": {
           "type": "boolean",
-          "description": "used to pass in --no-cache to docker build to prevent caching.",
-          "x-intellij-html-description": "used to pass in --no-cache to docker build to prevent caching.",
+          "description": "set to true to pass in --no-cache to docker build, which will prevent caching.",
+          "x-intellij-html-description": "set to true to pass in --no-cache to docker build, which will prevent caching.",
           "default": "false"
         },
         "pullParent": {
diff --git a/pkg/skaffold/build/cluster/cluster.go b/pkg/skaffold/build/cluster/cluster.go
index fbd45ad33..c265307d8 100644
--- a/pkg/skaffold/build/cluster/cluster.go
+++ b/pkg/skaffold/build/cluster/cluster.go
@@ -26,7 +26,6 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/misc"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
-	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
 	latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v1"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
@@ -63,11 +62,6 @@ func (b *Builder) PostBuild(_ context.Context, _ io.Writer) error {
 }
 
 func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, artifact *latestV1.Artifact, tag string, m platform.Matcher) (string, error) {
-	// TODO: Implement building multiplatform images for cluster builder
-	if m.IsMultiPlatform() {
-		log.Entry(ctx).Println("skaffold doesn't yet support multi platform builds for the cluster builder")
-	}
-
 	digest, err := b.runBuildForArtifact(ctx, out, artifact, tag, m)
 	if err != nil {
 		return "", err
@@ -85,7 +79,7 @@ func (b *Builder) runBuildForArtifact(ctx context.Context, out io.Writer, a *lat
 	requiredImages := docker.ResolveDependencyImages(a.Dependencies, b.artifactStore, true)
 	switch {
 	case a.KanikoArtifact != nil:
-		return b.buildWithKaniko(ctx, out, a.Workspace, a.ImageName, a.KanikoArtifact, tag, requiredImages)
+		return b.buildWithKaniko(ctx, out, a.Workspace, a.ImageName, a.KanikoArtifact, tag, requiredImages, platforms)
 
 	case a.CustomArtifact != nil:
 		return custom.NewArtifactBuilder(nil, b.cfg, true, b.skipTests, append(b.retrieveExtraEnv(), util.EnvPtrMapToSlice(requiredImages, "=")...)).Build(ctx, out, a, tag, platforms)
diff --git a/pkg/skaffold/build/cluster/kaniko.go b/pkg/skaffold/build/cluster/kaniko.go
index 24b03c68a..57f58179c 100644
--- a/pkg/skaffold/build/cluster/kaniko.go
+++ b/pkg/skaffold/build/cluster/kaniko.go
@@ -31,13 +31,19 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes"
 	kubernetesclient "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
 	latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v1"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
 )
 
 const initContainer = "kaniko-init-container"
 
-func (b *Builder) buildWithKaniko(ctx context.Context, out io.Writer, workspace string, artifactName string, artifact *latestV1.KanikoArtifact, tag string, requiredImages map[string]*string) (string, error) {
+func (b *Builder) buildWithKaniko(ctx context.Context, out io.Writer, workspace string, artifactName string, artifact *latestV1.KanikoArtifact, tag string, requiredImages map[string]*string, platforms platform.Matcher) (string, error) {
+	// TODO: Implement building multi-platform images for cluster builder
+	if platforms.IsMultiPlatform() {
+		log.Entry(ctx).Warnf("Multiple target platforms %q found for artifact %q. Skaffold doesn't yet support multi-platform builds for the cluster builder.", platforms.String(), artifactName)
+	}
+
 	generatedEnvs, err := generateEnvFromImage(tag)
 	if err != nil {
 		return "", fmt.Errorf("error processing generated env variables from image uri: %w", err)
@@ -60,7 +66,7 @@ func (b *Builder) buildWithKaniko(ctx context.Context, out io.Writer, workspace
 	}
 	pods := client.CoreV1().Pods(b.Namespace)
 
-	podSpec, err := b.kanikoPodSpec(artifact, tag)
+	podSpec, err := b.kanikoPodSpec(artifact, tag, platforms)
 	if err != nil {
 		return "", err
 	}
diff --git a/pkg/skaffold/build/cluster/pod.go b/pkg/skaffold/build/cluster/pod.go
index 1089d70e7..76d1dbad8 100644
--- a/pkg/skaffold/build/cluster/pod.go
+++ b/pkg/skaffold/build/cluster/pod.go
@@ -27,11 +27,18 @@ import (
 
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/kaniko"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
 	latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v1"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/version"
 )
 
-func (b *Builder) kanikoPodSpec(artifact *latestV1.KanikoArtifact, tag string) (*v1.Pod, error) {
+const (
+	// kubernetes.io/arch and kubernetes.io/os are known node labels. See https://kubernetes.io/docs/reference/labels-annotations-taints/
+	nodeOperatingSystemLabel = "kubernetes.io/os"
+	nodeArchitectureLabel    = "kubernetes.io/arch"
+)
+
+func (b *Builder) kanikoPodSpec(artifact *latestV1.KanikoArtifact, tag string, platforms platform.Matcher) (*v1.Pod, error) {
 	args, err := kanikoArgs(artifact, tag, b.cfg.GetInsecureRegistries())
 	if err != nil {
 		return nil, fmt.Errorf("building args list: %w", err)
@@ -115,6 +122,20 @@ func (b *Builder) kanikoPodSpec(artifact *latestV1.KanikoArtifact, tag string) (
 		pod.Spec.NodeSelector = b.ClusterDetails.NodeSelector
 	}
 
+	// Add nodeSelector for image target platform.
+	// Kaniko doesn't support building cross platform images, so the pod platform needs to match the image target platform.
+	if len(platforms.Platforms) == 1 {
+		if pod.Spec.NodeSelector == nil {
+			pod.Spec.NodeSelector = make(map[string]string)
+		}
+		if _, found := pod.Spec.NodeSelector[nodeArchitectureLabel]; !found {
+			pod.Spec.NodeSelector[nodeArchitectureLabel] = platforms.Platforms[0].Architecture
+		}
+		if _, found := pod.Spec.NodeSelector[nodeOperatingSystemLabel]; !found {
+			pod.Spec.NodeSelector[nodeOperatingSystemLabel] = platforms.Platforms[0].OS
+		}
+	}
+
 	// Add used-defines Volumes
 	pod.Spec.Volumes = append(pod.Spec.Volumes, b.Volumes...)
 


Test patch:
diff --git a/pkg/skaffold/build/cluster/pod_test.go b/pkg/skaffold/build/cluster/pod_test.go
index ab0b636ff..ce35f4cf0 100644
--- a/pkg/skaffold/build/cluster/pod_test.go
+++ b/pkg/skaffold/build/cluster/pod_test.go
@@ -19,11 +19,13 @@ package cluster
 import (
 	"testing"
 
+	specs "github.com/opencontainers/image-spec/specs-go/v1"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/kaniko"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
 	latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v1"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
 	"github.com/GoogleContainerTools/skaffold/testutil"
@@ -241,7 +243,8 @@ func TestKanikoPodSpec(t *testing.T) {
 			NodeSelector: map[string]string{"kubernetes.io/os": "linux"},
 		},
 	}
-	pod, _ := builder.kanikoPodSpec(artifact, "tag")
+	matcher := platform.Matcher{Platforms: []specs.Platform{{OS: "linux", Architecture: "arm64"}}}
+	pod, _ := builder.kanikoPodSpec(artifact, "tag", matcher)
 
 	expectedPod := &v1.Pod{
 		ObjectMeta: metav1.ObjectMeta{
@@ -378,7 +381,7 @@ func TestKanikoPodSpec(t *testing.T) {
 					TolerationSeconds: nil,
 				},
 			},
-			NodeSelector: map[string]string{"kubernetes.io/os": "linux"},
+			NodeSelector: map[string]string{"kubernetes.io/os": "linux", "kubernetes.io/arch": "arm64"},
 		},
 	}
 
diff --git a/pkg/skaffold/schema/latest/v1/config.go b/pkg/skaffold/schema/latest/v1/config.go
index 59889d4bf..47822ec8c 100644
--- a/pkg/skaffold/schema/latest/v1/config.go
+++ b/pkg/skaffold/schema/latest/v1/config.go
@@ -1327,7 +1327,7 @@ type DockerArtifact struct {
 	// PullParent is used to attempt pulling the parent image even if an older image exists locally.
 	PullParent bool `yaml:"pullParent,omitempty"`
 
-	// NoCache used to pass in --no-cache to docker build to prevent caching.
+	// NoCache set to true to pass in --no-cache to docker build, which will prevent caching.
 	NoCache bool `yaml:"noCache,omitempty"`
 
 	// Squash is used to pass in --squash to docker build to squash docker image layers into single layer.