Description
According to the "publish" (-P) section of Docker run docs (https://docs.docker.com/engine/reference/run/):
"Docker binds each exposed port to a random port on the host. The range of ports are within an ephemeral port range defined by /proc/sys/net/ipv4/ip_local_port_range."
In Docker versions pre-20, this was correct and working in our environment. However, since upgrading to Docker versions 20+, the kernel ip_local_port_range value is ignored, and Docker instead assigns a port from 49153 through 65535. This actually affects both the -P option where one publishes all exposed ports, and the -p option where one publishes a single port and does not provide a host port.
I have tested this on Ubuntu Focal, and Flatcar and both exhibit the same behaviour.
Steps to reproduce the issue:
- Set ip_local_port_range value
sudo sysctl -w net.ipv4.ip_local_port_range="32678 40000"
- Make sure docker is stopped and then install docker-ce/docker-ce-cli packages, any 19.X version
- Start a test container publishing all exposed ports or with a single published port, without providing a host port/host port range. (eg
docker run -d -p :80 nginxor docker run -d -P nginx)
- Check the host port assigned with
docker ps or docker port. It will be within 32678-40000 range.
- Remove container. Stop docker
- Install docker-ce/docker-ce-cli packages, any 20.X version. Start docker
- Start a test container publishing all exposed ports or with a single published port, without providing a host port/host port range. (eg.
docker run -d -p :80 nginx or docker run -d -P nginx)
- Check the host port assigned with
docker ps or docker port. It will be within 49153-65535 range.
Describe the results you received:
A port is assigned from 49153-65535 ephemeral range
Describe the results you expected:
A port is assigned from the ephemeral range set by the kernel parameter /proc/sys/net/ipv4/ip_local_port_range
Additional information you deem important (e.g. issue happens only occasionally):
Our use case here is, we are running many containers on AWS ECS. We would like to control the ports assigned to containers so we can specifically allow these ports through security groups. This is more desirable for us than allowing the whole ephemeral range 32678-65535.
Output of docker version:
Tested on Ubuntu Focal (I provided minimum 20.10 version, but 20.10.11 also affected)
Client: Docker Engine - Community
Version: 20.10.0
API version: 1.41
Go version: go1.13.15
Git commit: 7287ab3
Built: Tue Dec 8 18:59:40 2020
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.0
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: eeddea2
Built: Tue Dec 8 18:57:45 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.12
GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc:
Version: 1.0.2
GitCommit: v1.0.2-0-g52b36a2
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Output of docker info:
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Build with BuildKit (Docker Inc., v0.4.2-docker)
scan: Docker Scan (Docker Inc., v0.9.0)
Server:
Containers: 24
Running: 3
Paused: 0
Stopped: 21
Images: 42
Server Version: 20.10.0
Storage Driver: zfs
Zpool: xpool
Zpool Health: ONLINE
Parent Dataset: xpool/docker
Space Used By Parent: 3931974144
Space Available: 131577568768
Parent Quota: no
Compression: lz4
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc version: v1.0.2-0-g52b36a2
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 5.11.0-27-generic
Operating System: Ubuntu 20.04.3 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 22.97GiB
Name: ds0377
ID: 4LGQ:IJGY:AFAY:XS6R:AD6D:JRIE:QX42:D5CD:U74W:34MN:VA7E:G5PV
Docker Root Dir: /var/lib/docker
Debug Mode: true
File Descriptors: 40
Goroutines: 46
System Time: 2021-12-01T13:49:21.851318574Z
EventsListeners: 0
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: No blkio weight support
WARNING: No blkio weight_device support
Additional environment details (AWS, VirtualBox, physical, etc.):
Both AWS ECS (running Flatcar 2983.2.1/docker - 20.10.11) and physical laptop Ubuntu Focal.
Description
According to the "publish" (-P) section of Docker run docs (https://docs.docker.com/engine/reference/run/):
"Docker binds each exposed port to a random port on the host. The range of ports are within an ephemeral port range defined by /proc/sys/net/ipv4/ip_local_port_range."
In Docker versions pre-20, this was correct and working in our environment. However, since upgrading to Docker versions 20+, the kernel ip_local_port_range value is ignored, and Docker instead assigns a port from 49153 through 65535. This actually affects both the -P option where one publishes all exposed ports, and the -p option where one publishes a single port and does not provide a host port.
I have tested this on Ubuntu Focal, and Flatcar and both exhibit the same behaviour.
Steps to reproduce the issue:
sudo sysctl -w net.ipv4.ip_local_port_range="32678 40000"docker run -d -p :80 nginxordocker run -d -P nginx)docker psordocker port. It will be within 32678-40000 range.docker run -d -p :80 nginxordocker run -d -P nginx)docker psordocker port. It will be within 49153-65535 range.Describe the results you received:
A port is assigned from 49153-65535 ephemeral range
Describe the results you expected:
A port is assigned from the ephemeral range set by the kernel parameter
/proc/sys/net/ipv4/ip_local_port_rangeAdditional information you deem important (e.g. issue happens only occasionally):
Our use case here is, we are running many containers on AWS ECS. We would like to control the ports assigned to containers so we can specifically allow these ports through security groups. This is more desirable for us than allowing the whole ephemeral range 32678-65535.
Output of
docker version:Tested on Ubuntu Focal (I provided minimum 20.10 version, but 20.10.11 also affected)
Output of
docker info:Additional environment details (AWS, VirtualBox, physical, etc.):
Both AWS ECS (running Flatcar 2983.2.1/docker - 20.10.11) and physical laptop Ubuntu Focal.