Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minikube cache doesn't work with crio runtime #8554

Closed
MOZGIII opened this issue Jun 25, 2020 · 14 comments · Fixed by #9536
Closed

minikube cache doesn't work with crio runtime #8554

MOZGIII opened this issue Jun 25, 2020 · 14 comments · Fixed by #9536
Assignees
Labels
cmd/cache Issues with the "cache" command co/runtime/crio CRIO related issues kind/bug Categorizes issue or PR as related to a bug. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete.

Comments

@MOZGIII
Copy link

MOZGIII commented Jun 25, 2020

Images added to minikube via minikube cache add aren't accessible to the nodes when crio runtime is used.

Steps to reproduce the issue:

  1. minikube start --container-runtime=crio
  2. docker pull busybox && docker tag busybox my-local-image
  3. minikube cache add my-local-image
  4. kubectl run --image my-local-image bug --image-pull-policy=IfNotPresent -- echo "hello world"

Full output of failed command:

$ kubectl describe pod bug
Name:         bug
Namespace:    default
Priority:     0
Node:         minikube/172.17.0.2
Start Time:   Thu, 25 Jun 2020 07:31:00 +0300
Labels:       run=bug
Annotations:  <none>
Status:       Pending
IP:           10.1.0.6
IPs:
  IP:  10.1.0.6
Containers:
  bug:
    Container ID:  
    Image:         my-local-image
    Image ID:      
    Port:          <none>
    Host Port:     <none>
    Args:
      echo
      hello world
    State:          Waiting
      Reason:       ErrImagePull
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-c66kl (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  default-token-c66kl:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-c66kl
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age   From               Message
  ----     ------     ----  ----               -------
  Normal   Scheduled  8s    default-scheduler  Successfully assigned default/bug to minikube
  Normal   Pulling    7s    kubelet, minikube  Pulling image "my-local-image"
  Warning  Failed     1s    kubelet, minikube  Failed to pull image "my-local-image": rpc error: code = Unknown desc = Error reading manifest latest in quay.io/my-local-image: error parsing HTTP 404 response body: invalid character '<' looking for beginning of value: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n<title>404 Not Found</title>\n<h1>Not Found</h1>\n<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>\n"
  Warning  Failed     1s    kubelet, minikube  Error: ErrImagePull
  Normal   BackOff    0s    kubelet, minikube  Back-off pulling image "my-local-image"
  Warning  Failed     0s    kubelet, minikube  Error: ImagePullBackOff

As can be seen here, k8s tries to pull the image instead of just using it from the cache.

The expected behaviour is that the image will just be available instantly without pulling. It works as expected with docker and containerd runtimes, but not with crio.

Full output of minikube start command used, if not already included:

😄  minikube v1.11.0 on Ubuntu 20.04
    ▪ KUBECONFIG=/home/mozgiii/.kube/config:/home/mozgiii/.kube/config.d/qwe
✨  Automatically selected the docker driver
👍  Starting control plane node minikube in cluster minikube
🔥  Creating docker container (CPUs=2, Memory=16000MB) ...
🎁  Preparing Kubernetes v1.18.3 on CRI-O 1.17.3 ...
    ▪ kubeadm.pod-network-cidr=10.244.0.0/16
🔎  Verifying Kubernetes components...
🌟  Enabled addons: default-storageclass, storage-provisioner
🏄  Done! kubectl is now configured to use "minikube"
@afbjorklund
Copy link
Collaborator

Can you confirm if the image was loaded OK, with minikube ssh sudo crictl images

@afbjorklund afbjorklund added the co/runtime/crio CRIO related issues label Jun 25, 2020
@afbjorklund
Copy link
Collaborator

afbjorklund commented Jun 25, 2020

Looks it is the usual quirk of podman/cri-o, that it loads them with a prefix:

IMAGE                                     TAG                 IMAGE ID            SIZE
gcr.io/k8s-minikube/storage-provisioner   v1.8.1              4689081edb103       80.8MB
k8s.gcr.io/coredns                        1.6.7               67da37a9a360e       43.9MB
k8s.gcr.io/etcd                           3.4.3-0             303ce5db0e90d       290MB
k8s.gcr.io/kube-apiserver                 v1.18.3             7e28efa976bd1       175MB
k8s.gcr.io/kube-controller-manager        v1.18.3             da26705ccb4b5       164MB
k8s.gcr.io/kube-proxy                     v1.18.3             3439b7546f29b       119MB
k8s.gcr.io/kube-scheduler                 v1.18.3             76216c34ed0c7       96.8MB
k8s.gcr.io/pause                          3.2                 80d28bedfe5de       686kB
localhost/kubernetesui/dashboard          v2.0.0              8b32422733b3a       225MB
docker.io/kubernetesui/dashboard          v2.0.0              8b32422733b3a       225MB
localhost/kubernetesui/metrics-scraper    v1.0.2              3b08661dc379d       40.1MB
docker.io/kubernetesui/metrics-scraper    v1.0.2              3b08661dc379d       40.1MB
localhost/my-local-image                  latest              1c35c44120825       1.44MB

You can see here that it pulled the dashboard again, even though cached.

@afbjorklund
Copy link
Collaborator

Assuming that you don't want to rewrite all your images, this is upstream.

 minikube kubectl -- run --image localhost/my-local-image bug --image-pull-policy=IfNotPresent -- echo "hello world"
pod/bug created
 minikube kubectl -- logs bug
hello world

There was containers/podman#1103 for it, but it was closed years ago ?

@MOZGIII
Copy link
Author

MOZGIII commented Jun 25, 2020

The workaround with prefixing the image name with localhost/ works for me! 🎉
Won't work for everyone though.
skaffold in the default configuration will most likely be broken by this.

@medyagh medyagh added the cmd/cache Issues with the "cache" command label Jun 25, 2020
@medyagh
Copy link
Member

medyagh commented Jun 25, 2020

n't work for everyone though.
interesting, that makes sense I think crio uses a namespace for the image name different that others.

btw skaffold doesnt use CRIO by default .

I say we could add a solution message to the user to add the prefix or add it to the docs

@afbjorklund
Copy link
Collaborator

afbjorklund commented Jun 26, 2020

If this isn't fixed upstream, we need to workaround it for our cruntime loader...

At first glance, it seems that only images from a registry have been "fixed".
And it is still adding that extra docker.io, that you don't need when pulling.

We add docker.io to our registries.conf, even if upstream prefers quay.io.

@@ -346,8 +346,9 @@
 # List of registries to be used when pulling an unqualified image (e.g.,
 # "alpine:latest"). By default, registries is set to "docker.io" for
 # compatibility reasons. Depending on your workload and usecase you may add more
 # registries (e.g., "quay.io", "registry.fedoraproject.org",
 # "registry.opensuse.org", etc.).
-#registries = [
-# ]
+registries = [
+	"docker.io"
+]
 

The assumption here is that all the commands should render the same image.
So it should not add any any extra prefix like docker.io or localhost (even if true)

docker pull
docker load

podman pull
podman load

crictl pull
#crictl load (if it had actually existed)

Having users add a bogus "localhost/" in their manifest is an ugly workaround.

@afbjorklund
Copy link
Collaborator

btw skaffold doesnt use CRIO by default .

Every tool should use the CRI (in the ideal world). Hardcoding stuff to docker doesn't help anyone.

@afbjorklund
Copy link
Collaborator

Here is the main difference:

 docker pull kubernetesui/dashboard:v2.0.0
v2.0.0: Pulling from kubernetesui/dashboard
Digest: sha256:06868692fb9a7f2ede1a06de1b7b32afabc40ec739c1181d83b5ed3eb147ec6e
Status: Image is up to date for kubernetesui/dashboard:v2.0.0
docker.io/kubernetesui/dashboard:v2.0.0
 docker images kubernetesui/dashboard
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
kubernetesui/dashboard   v2.0.0              8b32422733b3        2 months ago        222MB
 sudo podman pull kubernetesui/dashboard:v2.0.0
Trying to pull docker.io/kubernetesui/dashboard:v2.0.0...
Getting image source signatures
Copying blob 2a43ce254c7f [--------------------------------------] 0.0b / 0.0b
Copying config 8b32422733 done  
Writing manifest to image destination
Storing signatures
8b32422733b3aec1c29b9d5798efa65feee5fe212039f9b7f377eb4cc82f1ab4
 sudo podman images kubernetesui/dashboard
REPOSITORY                        TAG     IMAGE ID      CREATED       SIZE
docker.io/kubernetesui/dashboard  v2.0.0  8b32422733b3  2 months ago  225 MB

For the registry images, it is not the end of the world. It will just pull manifest again.
(keeping all the image layers from the cached image, just a small JSON download)

But for the local images (like in this ticket), this prefix behaviour becomes an issue.
Since the image can't be found in any default registry, as it was just built locally.

@afbjorklund
Copy link
Collaborator

afbjorklund commented Jun 26, 2020

Another interesting feature is the nasty warning you get when loading:

Loaded image: kubernetesui/dashboard:v2.0.0

ERRO[0000] the image kubernetesui/dashboard:v2.0.0 already exists, renaming the old one with ID 8b32422733b3aec1c29b9d5798efa65feee5fe212039f9b7f377eb4cc82f1ab4 to empty string

It also gets a different (localhost) digest, instead of the empty one you get when loading with docker.

[
    {
        "Id": "sha256:8b32422733b3aec1c29b9d5798efa65feee5fe212039f9b7f377eb4cc82f1ab4",
        "RepoTags": [
            "kubernetesui/dashboard:v2.0.0"
        ],
        "RepoDigests": [],
[
    {
        "Id": "8b32422733b3aec1c29b9d5798efa65feee5fe212039f9b7f377eb4cc82f1ab4",
        "Digest": "sha256:0081340cd865e9f426650db15fe4c21abfcd0f7da03061955c967e0c266e6f03",
        "RepoTags": [
            "localhost/kubernetesui/dashboard:v2.0.0"
        ],
        "RepoDigests": [
            "localhost/kubernetesui/dashboard@sha256:0081340cd865e9f426650db15fe4c21abfcd0f7da03061955c967e0c266e6f03"
        ],

Which is a surprise, if you expect 06868692fb9a7f2ede1a06de1b7b32afabc40ec739c1181d83b5ed3eb147ec6e

@afbjorklund
Copy link
Collaborator

afbjorklund commented Jun 26, 2020

Workaround

docker save foo > foo.tar
sudo podman load -i foo.tar
sudo podman tag localhost/foo foo
sudo podman rmi localhost/foo

The problem is that we only have "foo.tar" (file) in the API, not "foo" (name)

So need either scrape the output from load (eww), or add another API call...

EDIT: As usual, also need to expand "foo" to "foo:latest" (if not having a tag)

@afbjorklund
Copy link
Collaborator

Still have a lot of unconditional calls to Docker, around the code base.

DigestByDockerLib

WriteImageToDaemon

Usually these fail since we stop dockerd, but should be conditionalized.

@afbjorklund afbjorklund added kind/bug Categorizes issue or PR as related to a bug. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. labels Jun 26, 2020
@priyawadhwa
Copy link

@afbjorklund on cache add, if using crio runtime, after loading the image could we just run through all of the images and retag the ones prepended with localhost/?

From what I understand, it's nontrivial to get the name of the image that's been loaded in from a tarball, and this could be a workaround.

@afbjorklund
Copy link
Collaborator

I guess it needs some kind of horrible workaround like that, as long as the behaviour continues.

Could file a bug about it upstream, but I'm not even sure where. Is it in podman, or is it cri-o ?

@afbjorklund afbjorklund self-assigned this Aug 30, 2020
@afbjorklund
Copy link
Collaborator

afbjorklund commented Aug 30, 2020

@priyawadhwa : it seems like the only way out of this, is to add the "docker.io" prefix to the images in the cache.
That will fix the dashboard case, by saving the manifest with the full name (docker doesn't care) in the cache tar.

For the local images, I'm not sure it is possible. It seems to be adding the prefix anyway, even if re-tagging them.

 sudo podman tag localhost/kubernetesui/dashboard:v2.0.0 kubernetesui/dashboard:v2.0.0
 sudo podman images kubernetesui/dashboard
REPOSITORY                        TAG     IMAGE ID      CREATED       SIZE
localhost/kubernetesui/dashboard  v2.0.0  8b32422733b3  4 months ago  225 MB
docker.io/kubernetesui/dashboard  v2.0.0  8b32422733b3  4 months ago  225 MB

Upstream seems to be hacking the localhost/ prefix into crictl instead, so that it can be used always (in cri-o)

cri-o/cri-o#3309 (1.19+)
cri-o/cri-o#3396 (1.18)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cmd/cache Issues with the "cache" command co/runtime/crio CRIO related issues kind/bug Categorizes issue or PR as related to a bug. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants