diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index 05a36e49b8..9e93188fd3 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -1993,10 +1993,21 @@ func (c *Container) generateResolvConf() error { return err } + networkBackend := c.runtime.config.Network.NetworkBackend nameservers := make([]string, 0, len(c.runtime.config.Containers.DNSServers)+len(c.config.DNSServer)) - nameservers = append(nameservers, c.runtime.config.Containers.DNSServers...) - for _, ip := range c.config.DNSServer { - nameservers = append(nameservers, ip.String()) + + // If NetworkBackend is `netavark` do not populate `/etc/resolv.conf` + // with custom dns server since after https://github.com/containers/netavark/pull/452 + // netavark will always set required `nameservers` in statsBlock and libpod + // will correctly populate `networkNameServers`. Also see https://github.com/containers/podman/issues/16172 + + // Exception: Populate `/etc/resolv.conf` if container is not connected to any network + // ( i.e len(netStatus)==0 ) since in such case netavark is not invoked at all. + if networkBackend != string(types.Netavark) || len(netStatus) == 0 { + nameservers = append(nameservers, c.runtime.config.Containers.DNSServers...) + for _, ip := range c.config.DNSServer { + nameservers = append(nameservers, ip.String()) + } } // If the user provided dns, it trumps all; then dns masq; then resolv.conf var search []string diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 3880fbc5b5..9bb2eac3c7 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -126,6 +126,37 @@ var _ = Describe("Podman run networking", func() { Expect(session).Should(Exit(0)) }) + It("podman verify resolv.conf with --dns + --network", func() { + // Following test is only functional with netavark and aardvark + // since new behaviour depends upon output from of statusBlock + SkipIfCNI(podmanTest) + net := createNetworkName("IntTest") + session := podmanTest.Podman([]string{"network", "create", net}) + session.WaitWithDefaultTimeout() + defer podmanTest.removeNetwork(net) + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"run", "--name", "con1", "--dns", "1.1.1.1", "--network", net, ALPINE, "cat", "/etc/resolv.conf"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + // Must not contain custom dns server in containers + // `/etc/resolv.conf` since custom dns-server is + // already expected to be present and processed by + // Podman's DNS resolver i.e ( aarvark-dns or dnsname ). + Expect(session.OutputToString()).ToNot(ContainSubstring("nameserver 1.1.1.1")) + // But /etc/resolve.conf must contain othe nameserver + // i.e dns server configured for network. + Expect(session.OutputToString()).To(ContainSubstring("nameserver")) + + session = podmanTest.Podman([]string{"run", "--name", "con2", "--dns", "1.1.1.1", ALPINE, "cat", "/etc/resolv.conf"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + // All the networks being used by following container + // don't have dns_enabled in such scenario `/etc/resolv.conf` + // must contain nameserver which were specified via `--dns`. + Expect(session.OutputToString()).To(ContainSubstring("nameserver 1.1.1.1")) + }) + It("podman run network expose port 222", func() { SkipIfRootless("iptables is not supported for rootless users") session := podmanTest.Podman([]string{"run", "-dt", "--expose", "222-223", "-P", ALPINE, "/bin/sh"})