docker部署golang http服務(wù)時(shí)端口無法訪問的問題解決
需要使用docker將golang的httpserver容器化。在這個(gè)過程中遇到了一個(gè)低級(jí)問題,golang http服務(wù)時(shí)端口無法訪問,特此記錄解決這個(gè)問題的過程。
1.背景
1.1 問題描述
問題描述: docker鏡像啟動(dòng)成果之后,通過curl不能訪問:
[root@hecs-205828 ~]# curl -XGET http://127.0.0.1:8360/hello curl: (56) Recv failure: Connection reset by peer
1.2 webserver代碼
go文件:main.go
package main
import (
"fmt"
"net/http"
"os"
"strings"
)
func main() {
http.HandleFunc("/hello", handler_hello)
http.HandleFunc("/healthz", handler_healthz)
http.ListenAndServe("127.0.0.1:8360", nil)
}
func handler_healthz(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}
func handler_hello(w http.ResponseWriter, r *http.Request) {
fmt.Println("method = ", r.Method)
fmt.Println("URL = ", r.URL)
fmt.Println("RemoteAddr = ", r.RemoteAddr)
fmt.Println("IP = ", strings.Split(r.RemoteAddr, ":")[0])
fmt.Println("header = ", r.Header)
fmt.Println("body = ", r.Body)
fmt.Println(r.RemoteAddr, "連接成功")
for name, values := range r.Header {
for _, value := range values {
fmt.Println(name, value)
_, exits := w.Header()[name]
if exits {
w.Header().Add(name, value)
} else {
w.Header().Set(name, value)
}
}
}
VERSION := os.Getenv("VERSION")
fmt.Println("VERSION is :", VERSION)
w.Header().Set("VERSION", VERSION)
w.WriteHeader(http.StatusOK)
w.Write([]byte("hello http server"))
}
3.Dockerfile文件
Dockerfile文件:
FROM golang:1.17 AS build WORKDIR /web-server/ COPY . . ENV CGO_ENABLED=0 ENV GO111MODULE=on ENV GOPROXY=https://goproxy.cn,direct RUN GOOS=linux go build -installsuffix cgo -o web-server main.go FROM busybox COPY --from=build /web-server/web-server /web-server/web-server EXPOSE 8360 ENV ENV local WORKDIR /web-server/ ENTRYPOINT ["/web-server/web-server"]
2.問題分析
發(fā)現(xiàn)curl無法訪問docker容器中的服務(wù),telnet結(jié)果如下:
[root@hecs-205828 ~]# telnet 127.0.0.1 8360 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. Connection closed by foreign host.
于是,打算采用命令進(jìn)入docker容器內(nèi)部查看:
[root@hecs-205828 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dfb2b46abd34 httpserver:0.0.1 "/web-server/web-ser…" 27 hours ago Up 2 hours 0.0.0.0:8360->8360/tcp, :::8360->8360/tcp relaxed_mccarthy
通過docer ps -a 得到容器id為dfb2b46abd34。進(jìn)入容器:
[root@hecs-205828 ~]# docker exec -it dfb2b46abd34 sh
/web-server # ps
PID USER TIME COMMAND
1 root 0:00 /web-server/web-server
38 root 0:00 sh
94 root 0:00 sh
101 root 0:00 ps
/web-server # netstat -an |grep 8360
tcp 0 0 127.0.0.1:8360 0.0.0.0:* LISTEN
/web-server #
可以看到,在容器內(nèi)部實(shí)際上8360端口已經(jīng)被監(jiān)聽。容器訪問應(yīng)該不存在問題。 容器內(nèi)部支持wget:
/web-server # wget -q -O - http://127.0.0.1:8360/hello hello http server /web-server #
可以看到在docker服務(wù)內(nèi)部運(yùn)行是正常的。
查看其網(wǎng)絡(luò)端口衍射:
[root@hecs-205828 ~]# docker port dfb2b46abd34 8360/tcp -> 0.0.0.0:8360 8360/tcp -> :::8360
端口衍射也不存在問題。那么問題究竟出在什么地方呢? 忽然想到,容器內(nèi)部的nestat監(jiān)聽端口是127.0.0.1,于是瞬間明白了。 在容器內(nèi)部的監(jiān)聽端口為127.0.0.1的話,那么只能接受容器內(nèi)部來自127.0.0.1的本地回環(huán)訪問。來自容器外外部的訪問請(qǐng)求將被拒絕。 因此,這個(gè)問題的修復(fù)原因?qū)嶋H上很簡(jiǎn)單,只需要將main.go的中監(jiān)聽ip改為0.0.0.0即可。
3.解決方案
果斷將監(jiān)聽ip改為0.0.0.0:
func main() {
http.HandleFunc("/hello", handler_hello)
http.HandleFunc("/healthz", handler_healthz)
http.ListenAndServe("0.0.0.0:8360", nil)
}
之后重新制作鏡像:
sudo docker build . -t httpserver:0.0.2
然后啟動(dòng)本地鏡像:
sudo docker run -d -p 8260:8230 httpserver:0.0.2
啟動(dòng)之后:
[root@hecs-205828 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ae5e2bf431c7 httpserver:0.0.2 "/web-server/web-ser…" 50 minutes ago Up 50 minutes 0.0.0.0:8260->8360/tcp, :::8260->8360/tcp affectionate_nash dfb2b46abd34 httpserver:0.0.1 "/web-server/web-ser…" 27 hours ago Up 2 hours 0.0.0.0:8360->8360/tcp, :::8360->8360/tcp relaxed_mccarthy [root@hecs-205828 ~]#
之后再訪問新增的容器,結(jié)果正常:
[root@hecs-205828 ~]# curl -XGET http://127.0.0.1:8260/hello hello http server [root@hecs-205828 ~]#
問題解決。
到此這篇關(guān)于docker部署golang http服務(wù)時(shí)端口無法訪問的問題解決的文章就介紹到這了,更多相關(guān)docker部署golang http內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
docker?掛載MySQL實(shí)現(xiàn)數(shù)據(jù)持久化的實(shí)現(xiàn)
本文主要介紹了docker?掛載MySQL實(shí)現(xiàn)數(shù)據(jù)持久化的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Docker沒有啟動(dòng)環(huán)境變量的問題解決
在使用Docker容器時(shí),有時(shí)候我們會(huì)遇到一個(gè)問題,就是在容器中沒有啟動(dòng)環(huán)境變量,本文主要介紹了Docker沒有啟動(dòng)環(huán)境變量的問題解決,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
Docker安裝Jenkins的實(shí)現(xiàn)步驟
版本與jdk版本以及各類插件有對(duì)應(yīng)關(guān)系,所以普通安裝較為麻煩,本文主要介紹了Docker安裝Jenkins的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
Docker 命令自動(dòng)補(bǔ)全的實(shí)現(xiàn)
這篇文章主要介紹了Docker 命令自動(dòng)補(bǔ)全的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Docker報(bào)錯(cuò)Operation?not?permitted問題的解決方法
剛開始接觸Docker的朋友經(jīng)常會(huì)遇到問題,下面這篇文章主要給大家介紹了關(guān)于Docker報(bào)錯(cuò)Operation?not?permitted問題的解決方法,需要的朋友可以參考下2023-02-02
Docker 教程之?dāng)?shù)據(jù)管理詳細(xì)介紹
這篇文章主要介紹了Docker 教程之?dāng)?shù)據(jù)管理詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-01-01

