Skip to content

The Iptables of the published port are not cleaned when the container is killed (not removed) #2699

@yankay

Description

@yankay

Description

The Iptables of the published port are not cleaned when the container is killed (not removed)
So, if another container starts with the same published port, it cannot be accessed correctly.
It may cause:

Steps to reproduce the issue

  1. Choose a random port
# PUBLISH_PORT=$((8000 + $RANDOM % 2000))
# echo $PUBLISH_PORT
8905 
  1. Run the 1st container with $PUBLISH_PORT, and kill it
root@kay201:~# nerdctl run --name ngx1 -d -p $PUBLISH_PORT:80 docker.m.daocloud.io/nginx:alpine
root@kay201:~# nerdctl kill ngx1
root@kay201:~# iptables-save  |grep $PUBLISH_PORT

The iptables rule still exists

-A CNI-DN-f9fd857ff3d57680c6bc2 -s 10.4.0.0/24 -p tcp -m tcp --dport 8905 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-f9fd857ff3d57680c6bc2 -s 127.0.0.1/32 -p tcp -m tcp --dport 8905 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-f9fd857ff3d57680c6bc2 -p tcp -m tcp --dport 8905 -j DNAT --to-destination 10.4.0.47:80
-A CNI-HOSTPORT-DNAT -p tcp -m comment --comment "dnat name: \"bridge\" id: \"k8s.io-ea6bc8469fbe0c245c9893f14ac5a652d464df7f38932053d2c1cd940c97d7a8\"" -m multiport --dports 8905 -j CNI-DN-f9fd857ff3d57680c6bc2
  1. Run the 2rd container with $PUBLISH_PORT, and try to access it.
root@kay202:~# nerdctl run --name ngx2 -d -p $PUBLISH_PORT:80 docker.m.daocloud.io/nginx:alpine
root@kay202~# curl 127.0.0.1:$PUBLISH_PORT
curl: (7) Failed to connect to 127.0.0.1 port 8905 after 3075 ms: No route to host

It cannot access, because There are two port-mapping in the iptables rule

root@kay201:~#  iptables-save  |grep $PUBLISH_PORT
-A CNI-DN-eeade65af7cda4d8daf03 -s 10.4.0.0/24 -p tcp -m tcp --dport 8905 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-eeade65af7cda4d8daf03 -s 127.0.0.1/32 -p tcp -m tcp --dport 8905 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-eeade65af7cda4d8daf03 -p tcp -m tcp --dport 8905 -j DNAT --to-destination 10.4.0.48:80
-A CNI-DN-f9fd857ff3d57680c6bc2 -s 10.4.0.0/24 -p tcp -m tcp --dport 8905 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-f9fd857ff3d57680c6bc2 -s 127.0.0.1/32 -p tcp -m tcp --dport 8905 -j CNI-HOSTPORT-SETMARK
-A CNI-DN-f9fd857ff3d57680c6bc2 -p tcp -m tcp --dport 8905 -j DNAT --to-destination 10.4.0.47:80
-A CNI-HOSTPORT-DNAT -p tcp -m comment --comment "dnat name: \"bridge\" id: \"k8s.io-ea6bc8469fbe0c245c9893f14ac5a652d464df7f38932053d2c1cd940c97d7a8\"" -m multiport --dports 8905 -j CNI-DN-f9fd857ff3d57680c6bc2
-A CNI-HOSTPORT-DNAT -p tcp -m comment --comment "dnat name: \"bridge\" id: \"k8s.io-0e68aa46d713a89030af74d16b95e9c44fa30190366e4444031a5d155c1cecb7\"" -m multiport --dports 8905 -j CNI-DN-eeade65af7cda4d8daf03
  1. Remove the 1st container, the 2rd container can be accessed.
root@kay201:~# nerdctl rm -f ngx1
root@kay201:~# curl 127.0.0.1:$PUBLISH_PORT
OK

Describe the results you received and expected

The Iptables of the published port are not cleaned when the container is killed like docker.

What version of nerdctl are you using?

root@kay201:~# nerdctl version
Client:
Version: v1.7.0
OS/Arch: linux/amd64
Git commit: e674fe7
buildctl:
Version: v0.12.3
GitCommit: 438f47256f0decd64cc96084e22d3357da494c27

Server:
containerd:
Version: v1.7.8
GitCommit: 8e4b0bde866788eec76735cc77c4720144248fb7
runc:
Version: 1.1.10
GitCommit: v1.1.10-0-g18a0cb0f

Are you using a variant of nerdctl? (e.g., Rancher Desktop)

None

Host information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions