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

时间:2020-02-19 08:18:44

标签: 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 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 build -t testapp  -f Dockerfile .

那是完美的作品

运行Docker文件

docker run -d -p 50051:50051 testapp

那也可以正常工作

我正在检查运行中的容器

docker ps

这会给我

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                      NAMES
57cd3c01bcda        testapp           "./testapp"       2 seconds ago       Up 2 seconds        0.0.0.0:50051->50051/tcp   gracious_bhaskara

当我检查网络时,请检查

docker network inspect bridge

这会给我

[
    {
        "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 "Content-type:application/json" -X GET 'https://localhost:50051/testapp/v1/order'
or
curl -H "Content-type:application/json" -X GET 'https://172.17.0.2:50051/testapp/v1/order'

它给了我

Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 0.0.0.0...
* TCP_NODELAY set
* Connected to 0.0.0.0 (127.0.0.1) port 50051 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* stopped the pause stream!
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number

测试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天不知道该怎么办?

3 个答案:

答案 0 :(得分:0)

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

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

curl -H "Content-type:application/json" -X GET 'https://localhost:50051/testapp/v1/order' -v -k

使用-k,您将忽略HTTPS验证。

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

答案 1 :(得分:0)

从容器内部,您需要侦听所有接口,而不是localhost或回送接口。网络在docker中具有命名空间,因此您不仅会获得一个新的私有IP,而且还会在容器内部获得一个单独的回送接口,该接口无法从外部访问。为此,请更改:

  SELECT
  k.customer_id,
  k.customer_name,
  l.label_name
  FROM
  label_table   l
  right JOIN client k ON k.value_of_client != l.value_of_client
where l.label_id=(case when k.value_of_client>(select value_of_client from label_table where label_id=1)
                   and  k.delayed=(select delayed from label_table where label_id=1)
                   and k.no_months >(select no_months from label_table where label_id=1)
                   and k.no_of_services>=(select no_of_services from label_table where label_id=1)
                   and k.no_of_mobile_sims>=(select no_of_mobile_sims from label_table where label_id=1)
                   then 1

                   when k.value_of_client > (select value_of_client from label_table where label_id=2) 
                   and  k.delayed<(select delayed from label_table where label_id=2)
                   and k.no_months >=(select no_months from label_table where label_id=2)
                   and k.no_of_services>=(select no_of_services from label_table where label_id=2)
                   and k.no_of_mobile_sims>(select no_of_mobile_sims from label_table where label_id=2)
                   then 2

                   when k.value_of_client>(select value_of_client from label_table where label_id=3)
                   and  k.delayed<(select delayed from label_table where label_id=3)
                   and  k.no_months >(select no_months from label_table where label_id=3)
                   and  k.no_of_services>(select no_of_services from label_table where label_id=3)
                   and  k.no_of_mobile_sims>(select no_of_mobile_sims from label_table where label_id=3)
                   then 3
                   else 4
                   end)
ORDER BY 1;

收件人:

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

答案 2 :(得分:0)

  1. main.go上提供的代码无法启动TLS,因此请停止使用https进行卷曲,它将无法正常工作。 用http卷曲会起作用

    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!")
    }
    
  2. 命令openssl s_client https://localhost:50051/testapp/v1/order -connect localhost:50051向您确认您请求的端口上没有TLS

  3. 很多注释确认使用https不相关,再次在您的代码上未激活TLS

  4. curl -H "Content-type:application/json" -X GET 'http://localhost:50051/testapp/v1/order'有效。 再次确认不使用TLS

结论:

在代码上未激活TLS时,请勿尝试卷曲https