検索

ホームページ  >  に質問  >  本文

docker - 容器删除后,主机映射给容器的端口为何并立即未回收利用?

新建容器时映射某些端口,如下:

docker run -d -p 22 -p 80 ubuntu /usr/sbin/sshd -D

主机将自动给容器的22和80映射两个端口,如:
0.0.0.0:49155->22/tcp, 0.0.0.0:49156->80/tcp
当该容器停止并且删除后,49155和49156这两个主机端口应该被释放,留给新的容器使用,但实际此时再新建容器映射端口发现,这两并未使用,而是系统自动分配这俩端口后面新的端口,比如49157...
只有docker服务重启后原来空出来的端口才会被分配。在三台不同的docker主机上做实验都是如此,貌似不是我配置的问题,不知大家的环境如何?求解!

阿神阿神2774日前889

全員に返信(1)返信します

  • 天蓬老师

    天蓬老师2017-04-21 10:57:34

    ソース コード docker/runtime/networkdriver/portallocator/portallocator.go を見るとわかります
    Docker のダイナミック レンジ ポートは 49153-65535 ですdocker / runtime / networkdriver / portallocator / portallocator.go可以知道
    docker的动态范围端口从 49153-65535

    const (
        BeginPortRange = 49153
        EndPortRange   = 65535
    )
    

    分配端口的方式顺序递增,到最大值后,从头开始循环

    func nextPort(proto string) int {
        c := currentDynamicPort[proto] + 1
        if c > EndPortRange {
            c = BeginPortRange
        }
        currentDynamicPort[proto] = c
        return c
    }
    

    container销毁时,会释放端口

    func ReleasePort(ip net.IP, proto string, port int) error {
        .......
    
        allocated := defaultAllocatedPorts[proto]
        allocated.Remove(port)
    
        .......
    }
    

    findNextPort方法从nexPort方法返回的值中,挑一个没被使用的,如果找一圈没找到,抛出ErrAllPortsAllocated异常。

    func findNextPort(proto string, allocated *collections.OrderedIntSet) (int, error) {
        port := nextPort(proto)
        startSearchPort := port
        for allocated.Exists(port) {
            port = nextPort(proto)
            if startSearchPort == port {
                return 0, ErrAllPortsAllocated
            }
        }
        return port, nil
    }
    

    综上,端口实际上已经释放,但不会马上再使用,除非端口资源非常紧张。
    所以你看到的是正常情况,不用但心(前提是你需要用v0.10以上版本)。
    循环使用端口这个特性是v0.10版本加上的。 如果低于这个版本,端口号到EndPortRange リーリー

    ポートを割り当てる方法は昇順です。最大値に達すると、サイクルは最初から始まります。 リーリー

    コンテナが破壊されるとポートが解放されます

    リーリー 🎜 findNextPort メソッドは、nexPort メソッドによって返された値から未使用の値を選択します。しばらく検索しても見つからない場合は、ErrAllPortsAllocated< をスローします。 /コード> 例外。 🎜 リーリー 🎜 要約すると、ポートは実際には解放されましたが、ポートのリソースが非常に逼迫していない限り、すぐに再使用されることはありません。
    したがって、表示される内容は正常です。心配する必要はありません (バージョン v0.10 以降を使用する必要がある場合)。
    ポートをリサイクルする機能はバージョン v0.10 で追加されました。 このバージョンより前の場合は、ポート番号が EndPortRange に達した後、Docker を再起動することしかできません🎜 🎜参考: https://github.com/dotcloud/docker/pull/4949🎜

    返事
    0
  • キャンセル返事