GoogleContainerTools / skaffold

Easy and Repeatable Kubernetes Development
https://skaffold.dev/
Apache License 2.0
15.08k stars 1.63k forks source link

Skaffold Docs Re. Tags #6278

Open kahunacohen opened 3 years ago

kahunacohen commented 3 years ago

I think the documentation is very unclear about the tagging process, unless I am missing something. I am happy to issue PRs for docs; I am also a technical writer. E.g. in the quickstart:

skaffold dev watches your local source code and executes your Skaffold pipeline every time a change is detected. skaffold.yaml provides specifications of the workflow - in this example, the pipeline is

  • Building a Docker image from the source using the Dockerfile
  • Tagging the Docker image with the sha256 hash of its contents
  • Updating the Kubernetes manifest, k8s-pod.yaml, to use the image built previously
  • Deploying the Kubernetes manifest using kubectl apply -f
  • Streaming the logs back from the deployed app

If I do $ skaffold build --tag='0.1.0'

and then I do docker image ls I don't see my tagged image. I also don't see that it pushed to dockerhub.

Also, this from the docs:

Updating the Kubernetes manifest, k8s-pod.yaml, to use the image built previously."

In my case I don't have a pod.yaml, just deployment.yaml. Should I expect skaffold to update my manifest files? In my case it doesn't. Again, I'd love to improve the docs, but I need to understand what is the expected behavior first.

Furthermore, I'm a bit unclear, even after reading the docs several times, what the workflow is like. I do skaffold dev in order to "hot reload" my k8s local cluster while developing...fine, but then what's the tagging for? Wouldn't I only tag when I was ready to create a new version of my app?

Here is my skaffold.yaml:

apiVersion: skaffold/v2beta19
kind: Config
metadata:
  name: hello-k8s
build:
  artifacts:
  - image: kahunacohen/hello-k8s
    docker:
      dockerfile: Dockerfile
deploy:
  kubectl:
    manifests:
    - manifests/web-configmap.yaml
    - manifests/web-service.yaml
    - manifests/web-deployment.yaml

My web-configmap.yaml

apiVersion: v1
data:
  MY_NON_SECRET: foo
  MY_OTHER_NON_SECRET: bar
kind: ConfigMap
metadata:
  name: web-configmap
  namespace: default

My web-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web-pod
  ports:
    # This maps incoming traffic on port 80 to port 3000 where the containers are running on, as defined in the deployment.
    - port: 80
      targetPort: 3000
      protocol: TCP
      name: foo

and my web-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-pod
  template:
    metadata:
      labels:
        app: web-pod
    spec:
      containers:
      - name: web
        image: kahunacohen/hello-k8s
        imagePullPolicy: IfNotPresent
        envFrom:
          - configMapRef:
              name: web-configmap
        ports:
        - containerPort: 3000
          protocol: TCP

and:

$ skaffold config list
skaffold config: 
kube-context: minikube
default-repo: index.docker.io
briandealwis commented 3 years ago

Hi @kahunacohen! We welcome all improvements, particularly to the docs!

If I do $ skaffold build --tag='0.1.0' and then I do docker image ls I don't see my tagged image. I also don't see that it pushed to dockerhub.

Ah this is confusing. Minikube has its own Docker Daemon that it uses for its cluster. Skaffold has special support for configuring that daemon for the builds as it results in much faster builds and deployments. You should be able to see your properly tagged image with:

(eval $(minikube docker-env); docker image ls)

Should I expect skaffold to update my manifest files?

No: Skaffold transforms in-memory representations of the files as it deploys the resources. The on-disk files are never touched.

but then what's the tagging for? Wouldn't I only tag when I was ready to create a new version of my app?

All images need to have a tag. Skaffold generates tags using a tagging policy which is normally configured in the skaffold.yaml. If a tagging policy is not specified then we default to our git-based tagger. But someone might want to explicitly tag images if they were deploying to a shared cluster, for example (skaffold dev --tag $USER).

kahunacohen commented 3 years ago

I see, boy that is confusing and now I see the mention of getting the tags in the minikube section, but it's buried a bit. I'll see if I can make that more obvious in the docs, because a lot of people are running minikube. Still some more questions:

Tags

All images need to have a tag.

I don't understand this. We tag images for the same reason we do git tag, right? In order to "freeze" and label an image. We can pull it down and be assured it is a pointer to known state. Why does running skaffold dev require tagging the image?

In-memory Artifacts

Skaffold transforms in-memory representations of the files as it deploys the resources. The on-disk files are never touched.

OK, so why do the docs say when enumerating what happens when we do skaffold build/dev: "Updating the Kubernetes manifest, k8s-pod.yaml"?

Is this in-memory version of your pod manifest somehow useful outside of skaffold's run-context?

Pushing Built Images

I then struggled with why the tags weren't getting pushed to dockerhub until I realized that unless build.local.push is true the images won't get pushed unless you are in a remote build, which makes sense, but I think I can make this more obvious in up front in the docs.

Once I set push to true skaffold does try to push my tags to docker hub, but I get an error even if I am logged in to docker hub.

docker info gives me: Registry: https://index.docker.io/v1/

Then

skaffold config set default-repo index.docker.io/v1 or skaffold config set default-repo index.docker.io

...But my build still fails to push with: Build Failed. No push access to specified image repository. Check your default-repo setting in skaffold config or trydocker login`.

Am I not setting the default repo correctly?

Again, I'll be happy to work on the docs a bit, but want to make sure skaffold will work for my needs. Thanks for what seems like a great project!

kahunacohen commented 3 years ago

When I took kaunacohen/ out of skaffold.yaml and set the default repo to include my user name that seemed to work.

ahmetb commented 3 years ago

@kahunacohen were you getting this warning line while building the image:

local images can't be referenced by digest. They are tagged and referenced by a unique ID instead

Once I set push to true skaffold does try to push my tags to docker hub, but I get an error even if I am logged in to docker hub.

This is probably related to #4780 or #5601. I think the default repo should not end with /v1.

tejal29 commented 3 years ago

@kahunacohen you are right a lot of users do have their images configured wrongly. Feel free to suggest any improvements to our error messages as well,

Build Failed. No push access to specified image repository. Check your default-repo setting in skaffold config or try docker login`

Does it make sense to include the image repository here as well ?

e.g.

Build Failed. No push access to specified image repository <index.docker.io/v1/kahunacohen>. Check your default-repo setting in skaffold config or try docker login`

Like Brian said, we will be delighted to get help from open source technical writers like yourself!