CURL在Docker映像中不工作[无法访问Docker映像中的主机]

CURL在Docker映像中不工作[无法访问Docker映像中的主机],docker,go,curl,docker-compose,handshake,Docker,Go,Curl,Docker Compose,Handshake,Docker文件 # Start from the latest golang base image FROM golang:latest # Add Maintainer Info LABEL maintainer="Sumit Thakur <sumitthakur@yahoo.com>" # Set the Current Working Directory inside the container WORKDIR /app # Copy go mod and sum f

Docker文件

# Start from the latest golang base image
FROM golang:latest

# Add Maintainer Info
LABEL maintainer="Sumit Thakur <sumitthakur@yahoo.com>"

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY . .

# Build the Go app
RUN go build -o testapp myapplication.go testapp.go

# Expose port 50051 / for internal comunication 

ENV PORT 50051
RUN echo $PORT

EXPOSE ${PORT}

# Command to run the executable
CMD ["./testapp"]
这是完美的工作

运行Docker文件

docker run -d -p 50051:50051 testapp
这也很好用

我检查运行的容器

docker-ps
这会给我

[
    {
        "Name": "bridge",
        "Id": "30850a823d3040e7d8eaf804c122ce3d26b35650f6f792cf1f4ce77d66167eeb",
        "Created": "2020-02-19T07:34:24.993299775Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "57cd3c01bcda3fbf7d0bf67136ebbb8afb312c4f6ca70eeee15cda6e10fff4e2": {
                "Name": "gracious_bhaskara",
                "EndpointID": "2a42056609e8140d190f1efde41320138867d3905053e7f381bd91b1f053c251",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]
CONTAINER ID IMAGE命令创建的状态端口名称
57cd3c01bcda testapp.“/testapp”2秒前上升2秒0.0.0.0:50051->50051/tcp gracious_bhaskara
当我检查网络时,用

docker网络检查网桥
这会给我

[
    {
        "Name": "bridge",
        "Id": "30850a823d3040e7d8eaf804c122ce3d26b35650f6f792cf1f4ce77d66167eeb",
        "Created": "2020-02-19T07:34:24.993299775Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "57cd3c01bcda3fbf7d0bf67136ebbb8afb312c4f6ca70eeee15cda6e10fff4e2": {
                "Name": "gracious_bhaskara",
                "EndpointID": "2a42056609e8140d190f1efde41320138867d3905053e7f381bd91b1f053c251",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]
一切正常 除非我尝试连接docker主机

curl-H“内容类型:application/json”-X GET”https://localhost:50051/testapp/v1/order'
或
curl-H“内容类型:application/json”-X GET”https://172.17.0.2:50051/testapp/v1/order'
它给了我

注意:不必要地使用-X或--request,GET已经推断出来。
*正在尝试0.0.0.0。。。
*TCP_节点集
*连接到0.0.0.0(127.0.0.1)端口50051(#0)
*阿尔卑斯山,提供h2
*ALPN,提供http/1.1
*密码选择:全部:!出口:!出口40:!出口56:!阿努尔:!低:!RC4:@强度
*已成功设置证书验证位置:
*CAfile:/etc/ssl/cert.pem
卡帕斯:没有
*TLSv1.2(输出),TLS握手,客户端问候(1):
*错误:1400410B:SSL例程:CONNECT\u CR\u SRVR\u HELLO:版本号错误
*停止暂停流!
*正在关闭连接0
curl:(35)错误:1400410B:SSL例程:CONNECT\u CR\u SRVR\u HELLO:版本号错误
测试openssl:

openssl s_client https://localhost:50051/testapp/v1/order -connect localhost:50051 
结果:

CONNECTED(00000005)
4488771180:error:140040E5:SSL routines:CONNECT_CR_SRVR_HELLO:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.200.4/l
ibressl-2.6/ssl/ssl_pkt.c:585:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Start Time: 1582109828
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
应用程序代码

package main

import (
    "io"
    "net/http"
    "github.com/gorilla/handlers"
)
func main() {
    http.HandleFunc("/testapp/v1/order", testHandler)
    headersOk := handlers.AllowedHeaders([]string{""})
    http.ListenAndServe(":50051", headersOk)
}
func testHandler(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Heyyy!")
}

有人帮我吗?我被困在这里1-2天,不知道该怎么办?

从评论中的讨论来看,问题似乎与https的握手有关

一个简单的解决方案是使用以下URL查询服务:

curl-H“内容类型:application/json”-X GET”https://localhost:50051/testapp/v1/order'-v-k
使用
-k
,您将忽略
HTTPS
验证


注意:我已将URL从
http
更改为
https

从容器内部,您需要监听所有接口,而不是本地主机或环回接口。网络在docker中使用名称空间,因此您不仅可以获得一个新的私有ip,还可以在容器内部获得一个外部无法访问的单独环回接口。为此,请更改:

http.ListenAndServe("localhost:50051", headersOk)
致:

  • main.go
    上提供的代码不会启动TLS,因此停止使用
    https
    进行卷曲,它将不起作用。 使用
    http
    的curl将起作用

    package main
    
    import (
        "io"
        "net/http"
    
        "github.com/gorilla/handlers"
    )
    
    func main() {
        http.HandleFunc("/testapp/v1/order", testHandler)
        headersOk := handlers.AllowedHeaders([]string{""})
        http.ListenAndServe(":50051", headersOk)
    }
    func testHandler(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Heyyy!")
    }
    
  • 命令
    opensslsu客户端https://localhost:50051/testapp/v1/order -connect localhost:50051
    向您确认您请求的端口上不存在TLS

  • 许多评论确认使用
    https
    是不相关的,同样,TLS在您的代码上没有激活

  • curl-H“内容类型:application/json”-X GET”http://localhost:50051/testapp/v1/order“
    有效。 再次确认未使用TLS

  • 结论:


    当您的代码上没有激活TLS时,不要尝试卷曲
    https
    ,您是否能够卷曲容器内的端点?是的,如果我这样做
    docker exec-it bash
    并执行
    /testapp
    ,然后我点击卷曲,它将给出结果我不明白为什么我无法从系统中卷曲。我只是停留在那里。请使用
    curl-H“Content-type:application/json”-X GET'http://localhost:50051/testapp/v1/order'-v
    并发布输出。查看日志服务器端。可能你点击的是
    http
    而不是
    https
    。谢谢,它现在会显示“我”
    curl:(35)LibreSSL SSL\u connect:SSL\u ERROR\u连接到本地主机的系统调用:50051
    它现在会给我
    curl:(35)LibreSSL SSL\u connect:SSL\u ERROR\u连接到本地主机的系统调用:50051
    您确定使用的是
    https
    站点而不是
    http
    ?在这种情况下,请运行以下命令并发布输出:
    openssl s\u客户端https://localhost:50051/testapp/v1/order-连接
    gnutls clihttps://localhost:50051/testapp/v1/order
    I更新上述openssl s_客户端的输入/输出。请检查是的,我更改了,我将在上面更新,但当我点击curl时,它会给我
    curl:(35)错误:1400410B:SSL例程:CONNECT\u CR\u SRVR\u HELLO:错误的版本号
    @SumitBon这里没有配置SSL,请从您的问题http返回原始curl命令,不是https。我这样做了,但如果我在docker容器中运行curl,我面临的问题是它工作正常,但从系统中它给了我结果
    curl:(7)连接到0.0.0.0端口50051失败:连接被拒绝
    不理解为什么会这样happens@SumitBon原始命令没有卷曲到
    0.0.0.0
    ,这是为了
    localhost
    ,使用原始的curl命令。谢谢,我完全理解了你的观点,但这是我的问题,一切都很好,除非我在容器内运行curl,它工作正常,但从系统中它给了我结果
    curl:(7)连接到0.0.0.0端口50051失败:连接被拒绝
    package main
    
    import (
        "io"
        "net/http"
    
        "github.com/gorilla/handlers"
    )
    
    func main() {
        http.HandleFunc("/testapp/v1/order", testHandler)
        headersOk := handlers.AllowedHeaders([]string{""})
        http.ListenAndServe(":50051", headersOk)
    }
    func testHandler(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Heyyy!")
    }