douzhantao2857
2016-07-28 04:18
浏览 71

Golang微服务无法使用Docker for Mac进行通信

I am trying to get two containers that are each running a different golang service. Both services were built with the net/http package. I have an API frontend as one and an Authentication service backend.

Here is my compose file:

version: "2"
services:
  staticfiles:
    build: ./files
    volumes:
      - /public
      - /views
  api:
    build: ./api
    environment:
      - PORT=8080
      - BASE_URL=https://example.org
      - AUTH_HOST=auth
      - AUTH_PORT=8080
      - VIEW_DIR=/views
      - PUBLIC_DIR=/public
    ports:
      - "80:8080"
    volumes_from:
      - staticfiles:ro
    links:
      - auth
    depends_on:
      - staticfiles
  db:
    build: ./postgres
    environment:
      - POSTGRES_USER=inheritor
      - POSTGRES_DB=inheritor
  auth:
    build: ./auth
    expose:
      - "8080"
    environment:
      - PORT=8080
      - DB_USER=inheritor
      - DB_NAME=inheritor
      - DB_HOST=db
      - DB_Port=5432
    links:
      - db

I know the links are working because from the api container I can ping auth and curl -X Post http://auth:8080/validate but within golang I get a dial address tcp i/o timeout. Here is the golang code.

var (
    authString = "http://" + env.AuthHost + ":" + env.AuthPort
)

//ValidateToken validates a token using the session in DB
func ValidateToken(req *model.ValidateRequest) (*model.JWTClaims, error) {
    client := new(http.Client)
    api := authString + "/validate"
    cont, err := model.Jsonify(req)
    if err != nil {
        return nil, exception.NewInternalError("Could not turn the request into a json object.")
    }

    request, err := http.NewRequest("POST", api, bytes.NewBuffer(cont))
    if err != nil {
        return nil, exception.NewInternalError("Could not create request: " + err.Error())
    }
    request.Header.Set("Content-type", "application/json")
    response, err := client.Do(request)
    if err != nil {
        return nil, exception.NewInternalError("Could not make the request: " + err.Error())
    }
    defer response.Body.Close()

    res := new(model.AuthResponse)
    res.Claims = new(model.JWTClaims)
    decoder := json.NewDecoder(response.Body)
    err = decoder.Decode(&res)
    spew.Dump(response.Body)
    if err != nil {
        return nil, exception.NewInternalError("Could not parse response back from auth service. " + err.Error())
    }

    if response.StatusCode != http.StatusOK {
        return nil, exception.NewInvalidJWTError(res.Error)
    }

    return res.Claims, nil
}

The client.Do(request) is what is throwing the Dial error. Now my auth service is not even being touched because I have a logger that prints to screen every request that is coming in.

  • env.AuthHost is mapped to the AUTH_HOST environment variable.
  • env.AuthPort is mapped to the Auth_PORT environment variable.

Much help is appreciated.

If it helps I am running MacOSX.

Client:
 Version:      1.12.0-rc4
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   e4a0dbc
 Built:        Wed Jul 13 03:28:51 2016
 OS/Arch:      darwin/amd64
 Experimental: true

Server:
 Version:      1.12.0-rc4
 API version:  1.24
 Go version:   go1.6.2
 Git commit:   e4a0dbc
 Built:        Wed Jul 13 03:28:51 2016
 OS/Arch:      linux/amd64
 Experimental: true

Both golangs Dockerfile looks like this:

FROM golang:1.6
RUN mkdir -p /go/src/github.com/dixonwille/Inheritor/api
WORKDIR /go/src/github.com/dixonwille/Inheritor/api

COPY . /go/src/github.com/dixonwille/Inheritor/api

RUN go build -v -o Inheritor cmd/Inheritor/main.go

USER nobody
ENTRYPOINT ["./Inheritor"]

EDIT:

So I ran net.LookupHost(env.AuthHost) within golang and it is returning a different IP address then ping, curl, and even docker inspect. Is this a golang thing then?

EDIT:

Sorry for all the edits kind of trying to debug as the day goes.

If I remove the port portion of the authString, the request goes through but get an error when parsing response. The response is a 301 redirect by NGINX which I think is strange because that is not even in my stack. The location header for the redirect is localhost, which I think is strange as well.

I have tried exposing a port on the host machine and accessing it with that port with no better luck (same hostname).

EDIT:

So it is a Mac only thing I assume. I cloned down the repo and ran on Windows 10 and I was able to connect to my auth service. Would this be Docker for Mac error? I am probably going to report it to them, but I would not consider this closed since it still is an issue for Mac users.

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • duang5049 2016-07-29 14:44
    已采纳

    So Docker for Mac just came out with a new beta version today. This seemed to have fixed my issue with connecting. Now I did make changes to source code when I found out it worked on my Windows pc.

    Here is the version of Docker for fix:

    Client:
     Version:      1.12.0
     API version:  1.24
     Go version:   go1.6.3
     Git commit:   8eab29e
     Built:        Thu Jul 28 21:04:48 2016
     OS/Arch:      darwin/amd64
     Experimental: true
    
    Server:
     Version:      1.12.0
     API version:  1.24
     Go version:   go1.6.3
     Git commit:   8eab29e
     Built:        Thu Jul 28 21:04:48 2016
     OS/Arch:      linux/amd64
     Experimental: true
    

    And here is the compose file:

    version: "2"
    services:
      staticfiles:
        build: ./files
        volumes:
          - /public
          - /views
          - /migrations
      databasefiles:
        build: ./databasefiles
        volumes:
          - /var/lib/postgresql/data
      db:
        build: ./postgres
        depends_on:
          - databasefiles
        volumes_from:
          - databasefiles
        environment:
          - POSTGRES_USER=inheritor
          - POSTGRES_DB=inheritor
      auth:
        build: ./auth
        expose:
          - "8080"
        depends_on:
          - staticfiles
        volumes_from:
          - staticfiles:ro
        environment:
          - PORT=8080
          - DB_USER=inheritor
          - DB_NAME=inheritor
          - DB_HOST=db
          - DB_PORT=5432
          - MIGRATION_DIR=/migrations
        links:
          - db
      api:
        build: ./api
        environment:
          - PORT=8080
          - BASE_URL=https://example.org
          - AUTH_HOST=auth
          - AUTH_PORT=8080
          - VIEW_DIR=/views
          - PUBLIC_DIR=/public
        ports:
          - "80:8080"
        volumes_from:
          - staticfiles:ro
        links:
          - auth
        depends_on:
          - staticfiles
    

    I did move services around but I do not see anything different that would change the communication between containers. This is just here incase others have same problem.

    已采纳该答案
    打赏 评论

相关推荐 更多相似问题