Search code examples
dockerdocker-composepodman

Podman containers can't see eachother via host name


I'm trying to get two containers to talk via host name. However, the host names don't seem to resolve. They can ping each other happily via IP. I'm using a user created network which I understand is required for automatic host name resolution.

I haven't used Podman before. Is there some additional setup required for container name resolution?

Simplified docker-compose.yml which demonstrates the issue

---
version: "3"

services:
  app1:
    image: docker.io/wbitt/network-multitool:latest
    container_name: app1
    networks:
      - internal-network

  app2:
    image: docker.io/wbitt/network-multitool:latest
    container_name: app2
    networks:
      - internal-network

networks:
  internal-network:
    driver: bridge

Inspecting each container does show that they are connected to the user defined network.

App1

"Networks": {
    "network-issue_internal-network": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": [
            "4d2425e5c3e5",
            "app1"
        ],
        "NetworkID": "network-issue_internal-network",
        "EndpointID": "",
        "Gateway": "10.88.4.1",
        "IPAddress": "10.88.4.27",
        "IPPrefixLen": 24,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "86:d1:52:53:84:b3",
        "DriverOpts": null
    }
}

App2

"Networks": {
    "network-issue_internal-network": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": [
            "3f6ed535b139",
            "app2"
        ],
        "NetworkID": "network-issue_internal-network",
        "EndpointID": "",
        "Gateway": "10.88.4.1",
        "IPAddress": "10.88.4.26",
        "IPPrefixLen": 24,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "fe:1f:cf:e7:80:52",
        "DriverOpts": null
    }
}

Oddly, when I inspect the user defined network it doesn't list any containers.

[
    {
        "args": {
            "podman_labels": {
                "com.docker.compose.network": "internal-network",
                "com.docker.compose.project": "network-issue",
                "com.docker.compose.version": "1.25.0"
            }
        },
        "cniVersion": "0.4.0",
        "name": "network-issue_internal-network",
        "plugins": [
            {
                "bridge": "cni-podman2",
                "hairpinMode": true,
                "ipMasq": true,
                "ipam": {
                    "ranges": [
                        [
                            {
                                "gateway": "10.88.4.1",
                                "subnet": "10.88.4.0/24"
                            }
                        ]
                    ],
                    "routes": [
                        {
                            "dst": "0.0.0.0/0"
                        }
                    ],
                    "type": "host-local"
                },
                "isGateway": true,
                "type": "bridge"
            },
            {
                "capabilities": {
                    "portMappings": true
                },
                "type": "portmap"
            },
            {
                "backend": "",
                "type": "firewall"
            },
            {
                "type": "tuning"
            }
        ]
    }
]

Dig output from app2 looking up app1

# dig app1

; <<>> DiG 9.16.22 <<>> app1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 3565
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;app1.                          IN      A

;; AUTHORITY SECTION:
.                       1356    IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2022100302 1800 900 604800 86400

;; Query time: 0 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Tue Oct 04 00:12:49 UTC 2022
;; MSG SIZE  rcvd: 108

Other details

  • Distro: Raspbian GNU/Linux 11
  • Podman Version: 3.0.1

Solution

  • It looks like the Podman package on Raspbian 11 does not ship with the dnsname plugin. It's relatively easy to install.

    1. Clone the repository:

      git clone https://github.com/containers/dnsname.git
      
    2. Build the plugin. You'll need to install the golang package first:

      sudo apt -y install golang
      

      And then:

      cd dnsname
      make
      
    3. Copy the plugin into the directory with the other CNI plugins:

      sudo cp bin/dnsname /usr/lib/cni/
      
    4. Add support for dnsname to one or more podman networks. That means adding a stanza like this to the plugins list of the appropriate file under /etc/cni/net.d:

       {
          "type": "dnsname",
          "domainName": "dns.podman",
          "capabilities": {
             "aliases": true
          }
       }
      

    With these changes in place, I can successfully start up two containers on a user-defined network and have them communicate by name:

    podman run -d --name node0 --network mynetwork docker.io/alpine:latest sleep inf
    podman run -d --name node1 --network mynetwork docker.io/alpine:latest sleep inf
    podman exec -it node0 ping -c2 node1
    

    Running the above commands (as root) produces:

    PING node1 (10.88.2.4): 56 data bytes
    64 bytes from 10.88.2.4: seq=0 ttl=42 time=0.308 ms
    64 bytes from 10.88.2.4: seq=1 ttl=42 time=0.543 ms
    
    --- node1 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.308/0.425/0.543 ms