更新到 docker 版本 19.03.2 后,Go net.Listen() 无法绑定到 docker 服务端口
Go net.Listen() cannot bind to a docker service port after updating to docker version 19.03.2
我正在使用 docker-compose 在我的 windows 10 机器上公开一个 docker 服务。
另外,使用golang中的函数检查服务是否完全启动:
package main
import (
"fmt"
"net"
)
func main() {
err := ping(9800)
fmt.Println(err)
}
func ping(port uint16) (err error) {
fmt.Println("checking port:", port)
conn, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
if err != nil {
return
}
conn.Close()
return
}
Docker 和现在使用的 Go 版本是:
C:\>docker version
Client: Docker Engine - Community
Version: 19.03.2
API version: 1.40
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:26:49 2019
OS/Arch: windows/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.2
API version: 1.40 (minimum version 1.12)
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:32:21 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.2.6
GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc:
Version: 1.0.0-rc8
GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f
docker-init:
Version: 0.18.0
GitCommit: fec3683
C:\>go version
go version go1.13.1 windows/amd64
容器已启动,服务已通过 hostPort 50014 公开:
C:\>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48eeb27f5ddc d.reg.io/adata "/usr/local/bin/adat…" 7 seconds ago Up 4seconds 0.0.0.0:50014->50014/tcp desktop_adata_1
当运行go脚本绑定到50014端口时,returns错误:
C:\>go run ping.go
checking port: 50014
listen tcp 127.0.0.1:50014: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
这仅在更新到 docker-for-windows 版本 19.03.2 后才会发生。
有人可以帮我解决这个问题吗?
更新:
有问题:
端口 50014 确实在管理的端口排除范围内。
我认为从该排除列表中删除该端口或使用任何其他端口都可以。但是我用主机端口80、8080、50014、9800一个一个暴露服务,尝试绑定。但是每次都失败了。
端口 80 和 8080 是非排除端口。容器已启动,服务正在监听端口。但是在尝试使用 go 函数进行绑定时出错:
checking port: 80
listen tcp 127.0.0.1:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
端口 50014 在管理端口排除范围内。容器已启动,服务正在监听端口。尝试绑定时也会出现相同的错误:
checking port: 80
listen tcp 127.0.0.1:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
9800端口在正常端口排除范围内。不同的是,这次容器不会起来。 Docker 无法使用该主机端口公开服务。当 运行 docker-compose up -d
:
时会报错
Creating desktop_adata_1 ... error
ERROR: for desktop_adata_1 Cannot start service adata: driver failed programming external connectivity on endpoint desktop_adata_1 (1a5978c5fbf35cb08fce14c8d5192756b3de8a77bd815f490e3e8ce542abaeaa): Error starting userland proxy: listen tcp 0.0.0.0:9800: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
这意味着,在我的例子中,错误的原因是 net.Listen() 无法绑定到用于 docker 容器服务的端口。
docker 更新后,net.Listen()
无法 ping 到已用于公开 Docker 容器服务的端口。
作为解决方法,我在 go 代码中使用 net.Dial()
而不是 net.Listen()
。
它按预期工作。
我正在使用 docker-compose 在我的 windows 10 机器上公开一个 docker 服务。
另外,使用golang中的函数检查服务是否完全启动:
package main
import (
"fmt"
"net"
)
func main() {
err := ping(9800)
fmt.Println(err)
}
func ping(port uint16) (err error) {
fmt.Println("checking port:", port)
conn, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
if err != nil {
return
}
conn.Close()
return
}
Docker 和现在使用的 Go 版本是:
C:\>docker version
Client: Docker Engine - Community
Version: 19.03.2
API version: 1.40
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:26:49 2019
OS/Arch: windows/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.2
API version: 1.40 (minimum version 1.12)
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:32:21 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.2.6
GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc:
Version: 1.0.0-rc8
GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f
docker-init:
Version: 0.18.0
GitCommit: fec3683
C:\>go version
go version go1.13.1 windows/amd64
容器已启动,服务已通过 hostPort 50014 公开:
C:\>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48eeb27f5ddc d.reg.io/adata "/usr/local/bin/adat…" 7 seconds ago Up 4seconds 0.0.0.0:50014->50014/tcp desktop_adata_1
当运行go脚本绑定到50014端口时,returns错误:
C:\>go run ping.go
checking port: 50014
listen tcp 127.0.0.1:50014: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
这仅在更新到 docker-for-windows 版本 19.03.2 后才会发生。
有人可以帮我解决这个问题吗?
更新:
有问题:
端口 50014 确实在管理的端口排除范围内。
我认为从该排除列表中删除该端口或使用任何其他端口都可以。但是我用主机端口80、8080、50014、9800一个一个暴露服务,尝试绑定。但是每次都失败了。
端口 80 和 8080 是非排除端口。容器已启动,服务正在监听端口。但是在尝试使用 go 函数进行绑定时出错:
checking port: 80
listen tcp 127.0.0.1:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
端口 50014 在管理端口排除范围内。容器已启动,服务正在监听端口。尝试绑定时也会出现相同的错误:
checking port: 80
listen tcp 127.0.0.1:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
9800端口在正常端口排除范围内。不同的是,这次容器不会起来。 Docker 无法使用该主机端口公开服务。当 运行 docker-compose up -d
:
Creating desktop_adata_1 ... error
ERROR: for desktop_adata_1 Cannot start service adata: driver failed programming external connectivity on endpoint desktop_adata_1 (1a5978c5fbf35cb08fce14c8d5192756b3de8a77bd815f490e3e8ce542abaeaa): Error starting userland proxy: listen tcp 0.0.0.0:9800: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
这意味着,在我的例子中,错误的原因是 net.Listen() 无法绑定到用于 docker 容器服务的端口。
docker 更新后,net.Listen()
无法 ping 到已用于公开 Docker 容器服务的端口。
作为解决方法,我在 go 代码中使用 net.Dial()
而不是 net.Listen()
。
它按预期工作。