CURL не работает в Docker образе [невозможно получить доступ к хосту в Docker образе] - PullRequest
0 голосов
/ 19 февраля 2020

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 голосов
/ 19 февраля 2020

Внутри контейнера вам нужно прослушивать все интерфейсы, а не localhost или loopback-интерфейс. Сеть имеет пространство имен в docker, поэтому вы получаете не только новый частный IP-адрес, но и отдельный интерфейс обратной связи внутри контейнера, который не может быть доступен извне. Для этого измените:

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

На:

http.ListenAndServe(":50051", headersOk)
0 голосов
/ 19 февраля 2020
  1. Код, указанный на main.go, не запускает TLS, поэтому прекратите сворачивать с https, он не будет работать. будет работать curl с 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 не используется

Вывод:

Не пытайтесь свернуть https, когда TLS не активирован в вашем коде

0 голосов
/ 19 февраля 2020

Из обсуждения в комментарии проблема, похоже, связана с рукопожатием https.

Простое решение - запросить службу по следующему URL-адресу:

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

Используя -k, вы будете игнорировать проверку HTTPS.

ПРИМЕЧАНИЕ : я изменил URL с http на https.

...