skaffold: Skipping deploy due to sync error: copying files: didn't sync any files

TL;DR

Skaffold Sync depends on the current namespace in $KUBECONFIG. When you develop locally with skaffold dev and switch the current namespace in $KUBECONFIG as part of the dev flow, Skaffold Sync becomes unreliable.

This issue has been reported earlier but issues were just closed without a fix:

Details and a workaround: https://github.com/GoogleContainerTools/skaffold/issues/1668#issuecomment-595752550

Expected behavior

Skaffold Sync should be able to copy files regardless of what happens to be the current namespace in $KUBECONFIG.

Actual behavior

Skaffold Sync will fail if artefact is deployed in a different namespace than which is defined in $KUBECONFIG as the current namespace.

Information

  • Skaffold version: 1.10.1 (and older)
  • Operating system: MacOS
  • Contents of skaffold.yaml:
apiVersion: skaffold/v2alpha2
kind: Config
build:
  local:
    push: false
  artifacts:
    - image: lolcat
      context: lolcat
      sync:
        manual:
          - src: "app/**/*"
            dest: /

PROBLEM: Namespace in $KUBECONFIG affects Skaffold Sync

Skaffold sync will only work when the Kubernetes namespace in $KUBECONFIG, at the time of starting Skaffold, matches the namespace of the artifact (application) being deployed.

The critical moment is when Skaffold starts. After Skaffold is running, I can change my current namespace in $KUBECONFIG and Skaffold sync works neatly. But, if the namespace in $KUBECONFIG is different from the hot-sync-artifact’s namespace when Skaffold starts, then sync will fail with error WARN[0032] Skipping deploy due to sync error: copying files: didn't sync any files .

For Skaffold Sync to work, the namespace in $KUBECONFIG must either be undefined or it must equal to the hot-sync-artifact’s namespace.

Steps to reproduce the behavior

EXAMPLE: Namespace undefined

Without namespace being defined, Skaffold Sync works for artifacts in any namespace:

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /Users/pre/.minikube/ca.crt
    server: https://192.168.64.100:8443
  name: rex
contexts:
- context:
    cluster: rex
    user: rex
  name: rex
current-context: rex
kind: Config
preferences: {}
users:
- name: rex
  user:
    client-certificate: /Users/pre/.minikube/client.crt
    client-key: /Users/pre/.minikube/client.key

EXAMPLE: Namespace defined

Here namespace is defined and Skaffold Sync will fail for all artifacts (applications) which are not deployed in dev namespace:

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /Users/pre/.minikube/ca.crt
    server: https://192.168.64.100:8443
  name: rex
contexts:
- context:
    cluster: rex
    namespace: dev
    user: rex
  name: rex
current-context: rex
kind: Config
preferences: {}
users:
- name: rex
  user:
    client-certificate: /Users/pre/.minikube/client.crt
    client-key: /Users/pre/.minikube/client.key

Workaround

  1. Reset the current namespace in $KUBECONFIG
  2. Run skaffold dev without a namespace being defined in $KUBECONFIG
  3. Create a subshell which switches back to the original namepace after Skaffold has started.
_dev() {
  local current_ns; current_ns="$(kubectl config view --minify --output 'jsonpath={..namespace}')"
  kubectl config set-context --current --namespace=
  (sleep 3 && kubectl config set-context --current --namespace="${current_ns}" ) &
    
  skaffold dev
}

Best things are achieved with a decent amount of sleep.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 9
  • Comments: 17 (6 by maintainers)

Most upvoted comments

I’ve made a PR to (hopefully) address this. However, in case the PR gets rejected—it is a bit shabby—here is a more permanent workaround for minikube users that doesn’t require hacking/wrapping/aliasing anything.

When starting minikube (for the first time or consecutively) you can pass it --namespace=. This has a similar effect as the workaround mentioned in https://github.com/GoogleContainerTools/skaffold/issues/4246#issue-623203593.

The added benefit of doing it this way is that minikube remember this for future invocations of minikube start, since it will update the profile config (it sets .KubernetesConfig.Namespace in ~/.minikube/profiles/{profile}/config.json to ""). So next time you run it, it will still attempt to patch the kubeconfig, but it will not set the namespace (or it will remove it if it’s there).

Thanks @omninonsense I started my minikube cluster with minikube start --namespace=<my_namespace> and it worked. I had been banging my head on this issue for 2 days.

@pre Sorry for the delay in any updates.

The current behaviour of skaffold dev in unexpected and causes a lot of wasted working hours in the long run.

Totally agree. I was wondering what we could do to fix this issue. Skaffold uses kubectl cp <pod>--namespace <podNs> -c command to copy the sync file. Ideally, if even you switch context within skaffold dev iterations, --namepsace flag should still point the pod in the deployed namespace. I saw an old bug where if kubectl context namespace is set, --namespace value is not respected https://github.com/kubernetes/client-go/issues/288 and kubernetes/kubernetes#46299 However, this bug got fixed in 2017. I am wondering if this could be related.

I tested passing --kube-context and --kubeconfig to Skaffold. They have no effect in this problem (Skaffold was already using the correct Kubeconfig with the correct kubecontext).

  • $KUBECONFIG points to correct file and is set by the script which runs Skaffold.
  • Both examples above represent a full Kubeconfig.
  • $KUBECONFIG has only one context which is defined by Minikube (full example above).

Skaffold Sync not being able to sync files in multiple namespaces is caused solely by context.namespace being defined in $KUBECONFIG when Skaffold starts.

When context.namespace is undefined when Skaffold starts,

  • Skaffold Sync can copy any files in any namespace.
  • Skaffold Sync works even if you change context.namespace when Skaffold is running.

When context.namespace is defined when Skaffold starts,

  • Skaffold Sync can copy files only in this namespace.
  • If context.namespace is changed while Skaffold is running, Skaffold Sync can copy files only in the current context.namespace.

The last behaviour is unexpected: if you develop with skaffold dev having resources in multiple namespaces and switch current context.namespace while Skaffold is running, you get different behaviour when A) context.namespace was undefined when Skaffold started: Sync works and never breaks. B) context.namespace was defined when Skaffold started: Sync suddenly stops working when context.namespace changes while Skaffold is running.