docker - 容器刪除後,主機映射給容器的連接埠為何並立即未回收?
阿神
阿神 2017-04-21 10:55:34
0
1
929

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

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主機上做實驗都是如此,貌似不是我配置的問題,不知大家的環境如何?求解!

阿神
阿神

闭关修行中......

全部回覆(1)
Peter_Zhu

透過查看源碼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後,就只能重啟Docker了

參考: https://github.com/dotcloud/docker/pull/4949

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板