Skip to content

Commit

Permalink
libpod: propogate custom DNS server to /etc/resolv.conf only when dns…
Browse files Browse the repository at this point in the history
…_enabled

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: containers#16172

```release-note
container: `--dns` and `dns_server` behavior for containers connected to network matches with docker now
```

Signed-off-by: Aditya R <[email protected]>
  • Loading branch information
flouthoc committed Oct 14, 2022
1 parent 0321165 commit 01915ad
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
32 changes: 29 additions & 3 deletions libpod/container_internal_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -1901,10 +1901,36 @@ func (c *Container) generateResolvConf() error {
return err
}

foundNetworkWithDNSEnabled := false
// get all the networks this container is attached to
networkInfo, err := c.getContainerNetworkInfo()
if err != nil {
return err
}
for networkName := range networkInfo.Networks {
netInfo, err := c.runtime.Network().NetworkInspect(networkName)
if err != nil {
return err
}
if netInfo.DNSEnabled {
foundNetworkWithDNSEnabled = true
break
}
}
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())
// Docker parity: If container is connected to any network
// where dns_enabled is `true` then do not populate `/etc/resolv.conf`
// with custom dns server since DNS resolver ( aardvark-dns, dnsname )
// will take care of using custom dns server.
if !foundNetworkWithDNSEnabled {
// Docker parity: If foundNetworkWithDNSEnabled is `false`
// means no network was found where DNS is enabled, is such
// case honor `--dns` or `dns_servers` from config and populate
// `/etc/resolv.conf` inside container.
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
28 changes: 28 additions & 0 deletions test/e2e/run_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,34 @@ EXPOSE 2004-2005/tcp`, ALPINE)
pingTest("--net=private")
})

It("podman verify resolv.conf with --dns + --network", func() {
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 check dnsname plugin with CNI", func() {
SkipIfNetavark(podmanTest)
pod := "testpod"
Expand Down

0 comments on commit 01915ad

Please sign in to comment.