Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6 port mapping broken with docker 20.10.2 #70

Closed
seblu opened this issue Jan 19, 2021 · 6 comments · Fixed by #71
Closed

IPv6 port mapping broken with docker 20.10.2 #70

seblu opened this issue Jan 19, 2021 · 6 comments · Fixed by #71
Labels
docker-plain plain Docker (no swarm, no compose, no stack)

Comments

@seblu
Copy link

seblu commented Jan 19, 2021

SUMMARY

The docker_container module set an IPv4 as default host for published_ports.
Since the last version of docker (20.10.2) and recent changes (see here), 0.0.0.0 doesn't bind on IPv6 anymore.

So, containers defined like the following loose their dual stack binding when upgrading to docker 20.10.2. If containers were defined with the docker cli, upgrade would be transparent.

- docker_container:
    image: nginx
    name: foo
    published_ports:
    - 8080:80

A user side workaround could to be force definition of a listening IPv6 host like the following.
This require to known if host is supporting IPv6 instead of having it configured automatically depending of the host support of an IPv6 stack.
N.B: I didn't find a way to push an empty string as host in published_ports.

    published_ports:
    - "0.0.0.0:8080:80"
    - "[::]:8080:80"

The difference between containers can be seen with the following commands:

# create a bar container from cli
$ docker run --publish 8081:80 --name bar -d nginx

$ docker inspect bar -f='{{.HostConfig.PortBindings}}'        
map[80/tcp:[{ 8081}]]

$ docker inspect foo -f='{{.HostConfig.PortBindings}}'
map[80/tcp:[{0.0.0.0 8080}]]
SOLUTION

I suggest to mimic the docker cli behavior and change the default Host to an empty string.
This way, when users doesn't set an host for published_ports, dockerd chooses the correct binding.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

docker_container

ANSIBLE VERSION
ansible 2.10.4
  config file = /home/seblu/scm/infra/ansible.cfg
  configured module search path = ['/home/seblu/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.9.1 (default, Dec 13 2020, 11:55:53) [GCC 10.2.0]
OS / ENVIRONMENT

Arch Linux

STEPS TO REPRODUCE
  • Have an IPv6 host
  • Upgrade to docker > 20.10

A simple container like this is enough.

- docker_container:
    image: nginx
    name: foo
    published_ports:
    - 8080:80
EXPECTED RESULTS

Docker container should be bound to IPv6 host addresses.

$ ss -tulpn|grep docker-proxy
tcp   LISTEN 0      4096                            0.0.0.0:8080       0.0.0.0:*    users:(("docker-proxy",pid=678243,fd=4))                                                                                                           
tcp   LISTEN 0      4096                               [::]:8080          [::]:*    users:(("docker-proxy",pid=678248,fd=4))

$ curl http://[2001:ac1d:bee:face:beef::1]:8080
<!DOCTYPE html>
<html>
...

This ouput is with docker > 20.10. With older version the binding is on *:8080.

ACTUAL RESULTS
$ ss -tulpn|grep docker-proxy
tcp   LISTEN 0      4096                            0.0.0.0:8080       0.0.0.0:*    users:(("docker-proxy",pid=682889,fd=4))                                                                                                           
                                                                                     
$ curl http://[2001:ac1d:bee:face:beef::1]:8080
curl: (7) Failed to connect to 2001:ac1d:bee:face:beef::1 port 8080: Connection refused


@felixfontein felixfontein added the docker-plain plain Docker (no swarm, no compose, no stack) label Jan 19, 2021
@felixfontein
Copy link
Collaborator

Simply switching the default IP to '' breaks backwards compatibility: containers started with a version which used an IP address (like 0.0.0.0) will be restarted. But what we could do is offer to set the default IP as a module option, and allow an empty string as a possible choice.

@seblu
Copy link
Author

seblu commented Jan 19, 2021

Restarting a container is a backward compatibility breakage/issue?

Adding a default host binding string looks good too, except it will introduce a new difference between the cli and the module.

@felixfontein
Copy link
Collaborator

Yes, the module must not suddenly restart containers. That could destroy production data.

@felixfontein
Copy link
Collaborator

I created PR #71 which adds an option default_host_ip. If you use that and set it to "" (empty string), it should work for you.

@Henkhogan
Copy link

@felixfontein could default_host_ip be also added to the docker_swarm_service_module? I really miss a solution there to bind to the host IPv6

@felixfontein
Copy link
Collaborator

@Henkhogan the docker_container module works totally different from the docker_swarm_service module. The latter does not do magic string transformations for idempotency checks. So something like a global option default_host_ip doesn't make sense for docker_swarm_service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docker-plain plain Docker (no swarm, no compose, no stack)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants