当前位置: 代码网 > 服务器>服务器>云虚拟主机 > docker部署golang http服务时端口无法访问的问题解决

docker部署golang http服务时端口无法访问的问题解决

2024年05月22日 云虚拟主机 我要评论
需要使用docker将golang的httpserver容器化。在这个过程中遇到了一个低级问题,golang http服务时端口无法访问,特此记录解决这个问题的过程。1.背景1.1 问题描述问题描述:

需要使用docker将golang的httpserver容器化。在这个过程中遇到了一个低级问题,golang http服务时端口无法访问,特此记录解决这个问题的过程。

1.背景

1.1 问题描述

问题描述: docker镜像启动成果之后,通过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.问题分析

发现curl无法访问docker容器中的服务,telnet结果如下:

[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.

于是,打算采用命令进入docker容器内部查看:

[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。进入容器:

[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 #

可以看到,在容器内部实际上8360端口已经被监听。容器访问应该不存在问题。 容器内部支持wget:

/web-server # wget -q -o -  http://127.0.0.1:8360/hello
hello http server
/web-server # 

可以看到在docker服务内部运行是正常的。

查看其网络端口衍射:

[root@hecs-205828 ~]# docker port  dfb2b46abd34 
8360/tcp -> 0.0.0.0:8360
8360/tcp -> :::8360

端口衍射也不存在问题。那么问题究竟出在什么地方呢? 忽然想到,容器内部的nestat监听端口是127.0.0.1,于是瞬间明白了。 在容器内部的监听端口为127.0.0.1的话,那么只能接受容器内部来自127.0.0.1的本地回环访问。来自容器外外部的访问请求将被拒绝。 因此,这个问题的修复原因实际上很简单,只需要将main.go的中监听ip改为0.0.0.0即可。

3.解决方案

果断将监听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

然后启动本地镜像:

 sudo docker run -d -p 8260:8230 httpserver:0.0.2

启动之后:

[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 ~]# 

之后再访问新增的容器,结果正常:

[root@hecs-205828 ~]# curl -xget http://127.0.0.1:8260/hello
hello http server
[root@hecs-205828 ~]# 

问题解决。

到此这篇关于docker部署golang http服务时端口无法访问的问题解决的文章就介绍到这了,更多相关docker部署golang http内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com