Skip to content

Commit

Permalink
libpod,netavark: correctly populate /etc/resolv.conf with custom dns …
Browse files Browse the repository at this point in the history
…server

After containers/netavark#452 `netavark` is
incharge of deciding `custom_dns_servers` if any so lets honor that and
libpod should not set these manually.

This also ensures docker parity
Podman populates container's `/etc/resolv.conf` with custom DNS servers ( specified via `--dns` or `dns_server` in containers.conf )
even when container is connected to a network where `dns_enabled` is `true`.

Current behavior does not matches with docker, hence following commit ensures that podman only populates custom DNS server when container is not connected to any network where DNS is enabled and for the cases where `dns_enabled` is `true`
the resolution for custom DNS server will happen via ( `aardvark-dns` or `dnsname` ).

Reference: https://docs.docker.com/config/containers/container-networking/#dns-services
Closes: #16172

Signed-off-by: Aditya R <[email protected]>
  • Loading branch information
flouthoc committed Jan 22, 2023
1 parent 366e168 commit 0624107
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
17 changes: 14 additions & 3 deletions libpod/container_internal_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 31 additions & 0 deletions test/e2e/run_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"})
Expand Down

0 comments on commit 0624107

Please sign in to comment.