Hello there,
I’m trying to push an image localhost:32000/pain-webapp:registry to the built-in microk8s registry.
microk8s and docker are running on the same machine (Ubuntu 24.04)
docker info prints this:
This is the response from curl -vs http://localhost:32000/v2/_catalog
repositories array is empty. When the push succedes (in rootful mode) repositories array contains the pushed image
* Host localhost:32000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:32000...
* connect to ::1 port 32000 from ::1 port 44848 failed: Connection refused
* Trying 127.0.0.1:32000...
* Connected to localhost (127.0.0.1) port 32000
> GET /v2/_catalog HTTP/1.1
> Host: localhost:32000
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Docker-Distribution-Api-Version: registry/2.0
< X-Content-Type-Options: nosniff
< Date: Mon, 12 Aug 2024 09:15:50 GMT
< Content-Length: 20
<
{"repositories":[]}
* Connection #0 to host localhost left intact
Thank you! Got it! It’s weird that, even when docker is running in rootless mode, pushing image is working fine when microk8s is running inside multipass. The only difference is in tagging docker image using the IP showed by multipass list and not localhost.
Since I’m developing on a linux machine and since I’m still in dev mode I find stupid to have the overhead of a VM, even though I have enough RAM. Multipass will be useful in a next stage when testing CLOUD INIT
Thank you again
I was wondering why this could happen, as localhost should be available in both mode, but I realized that rootless Docker is using rootlesskit, which isolates itself from the host. So even when you run something like:
docker run --rm -it --net host nicolaka/netshoot curl localhost:32000
it will not be able to access the API. If the docker daemon is in such an isolated environment, it will not be able to access the registry either.
I installed podman just for a test. Podman is rootless by default and it works. It’s been just for test since I don’t like it. Compose doesn’t work like docker and I find many intermediate images when running native build that I don’t see in docker
Podman works differently. It doesn’t have a daemon as far as I know. The Docker daemon is running in the namespace created by rootlesskit. I just tested it. I knew about it, but didn’t remember.
dockerd_pid=$(rootlesskit pidof dockerd | tr ' ' '\n' | sort | head -n1)
sudo nsenter --all -t "$dockerd_pid" ip a
And the output is something like this:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UP group default qlen 1000
link/ether 6a:e4:56:0b:31:7c brd ff:ff:ff:ff:ff:ff
inet 10.0.2.100/24 scope global tap0
valid_lft forever preferred_lft forever
inet6 fe80::68e4:56ff:fe0b:317c/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:ec:ab:40:49 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:ecff:feab:4049/64 scope link
valid_lft forever preferred_lft forever
I have much more interfaces on the host. So indeed, the docker daemon has no access to the localhost of the real host.
EDIT:
My example might not work on your machine and the rootlesskit command was not really needed as the process IDs are the same with or without rootlesskit.