簡體   English   中英

無法連接到 Docker 容器中的 Go 服務器

[英]Can't connect to Go Server in Docker container

我正在嘗試在 docker 容器內運行一個用 Golang 編寫的 HTTP 服務器,但我一直拒絕連接。 一切都在我的 Windows 10 機器上運行的 Ubuntu 20.04 服務器虛擬機中運行。

Go 服務器代碼:

package main

import "github.com/lkelly93/scheduler/internal/server"

func main() {
    server := server.NewHTTPServer()
    server.Start(3000)
}
package server

import (
    "context"
    "fmt"
    "net/http"
)

type HTTPServer interface {
    Start(port int) error

    Stop() error
}

func NewHTTPServer() HTTPServer {
    return &httpServer{}
}

type httpServer struct {
    server *http.Server
}

func (server *httpServer) Start(port int) error {
    serveMux := newServeMux()
    server.server = &http.Server {
        Addr: fmt.Sprintf(":%d", port),
        Handler: serveMux,
    }
    return server.server.ListenAndServe()
}

func (server *httpServer) Stop() error {
    return server.server.Shutdown(context.Background())
}

我的 Dockerfile:

FROM ubuntu:20.04

RUN apt-get update -y

#Install needed packages
RUN apt-get install software-properties-common -y
RUN apt-get install python3 -y
RUN apt-get update -y 
RUN apt-get install python3-pip -y
RUN apt-get install default-jre -y

#Install language dependacies
    #Python
    RUN pip3 install numpy

#Reduce VM size
# RUN rm -rf /var/lib/apt/lists/*

#Setup working DIRs
RUN mkdir secure
RUN mkdir secure/runner_files

COPY scheduler /secure
WORKDIR /secure

EXPOSE 3000

CMD ["./scheduler"] <-- The go server is compiled into a binary called scheduler

我構建給定的 Dockerfile 然后運行:

docker run -d --name scheduler -p 3000:3000 scheduler:latest

然后我通過以下方式獲取容器的地址:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' scheduler
->172.17.0.2

最后我使用 cURL 發送一個 http 請求:

curl http://172.17.0.2:3000/execute/python --data '{"Code":"print(\"Hello\")"}'

我正進入(狀態

curl: (7) Failed to connect to 172.17.0.2 port 3000: Connection refused

但應該得到

{"Stdout":"Hello\n"}%

如果我在 Ubuntu VM 上運行 Go 服務器,我從我的 Win10 機器上調用它沒有問題,但當它存在於 Ubuntu 機器的 docker 容器內時,我似乎無法調用 Go 服務器。

Go 的代碼比那個更復雜,但是在這里發布所有內容太多了,請隨時在https://github.com/lkelly93/scheduler查看整個 repo。

最終它將成為我想要運行代碼的網站的后端。 像 LeetCode 或 Repl.it 這樣的東西。

謝謝!

編輯:

docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
2a56a973040f        scheduler:latest    "./scheduler"       37 seconds ago      Up 36 seconds       0.0.0.0:3000->3000/tcp   scheduler

docker 容器日志 2a56a973040f 沒有給出 output。

編輯 2:

docker run -it --net container:2a56a973040f nicolaka/netshoot ss -lnt
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      4096               *:3000            *:*

編輯 3:

閱讀手冊頁后,我發現如果我有標簽 -.network=host 到我的圖像然后運行。

curl http://localhost:3000/execute/python --data '{"Code":"print(\"Hello\")"}'

我得到正確的 output。雖然這有效,但我希望並排運行多個 docker 圖像。 所以我更願意使用 IP 地址來解決所有這些問題。 所以我不認為這是一個永久性的解決方案。

為了在我的服務器上解決這個問題,我將 IP 地址設置為 0.0.0.0:4000。 我正在使用杜松子酒所以這個例子看起來像:

r := gin.Default()
r.run("0.0.0.0:4000")

在此之后,我終於可以通過瀏覽器訪問它了。

您已經發布了端口,它將端口從 docker 主機轉發到容器。 因此,您要連接到 http://localhost:3000。 連接到容器 IP 可能會因桌面安裝而失敗,因為 docker 在 VM 內部運行,而這些私有 IP 僅在 VM 中可見。

如果您碰巧正在運行docker-machine (較舊的 docker 工具箱安裝就是這種情況),那么您需要獲取 VM 的 IP。 運行echo $DOCKER_HOST以查看 IP 地址並將端口調整為端口 3000。

在做了更多的谷歌搜索之后,我按照指南創建了我自己的“用戶定義的橋接網絡”。

如果我啟動我的容器並將其附加到這個網絡,那么它就可以工作了! 如果有人能解釋原因,我會很高興的!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM