douhei8633 2018-05-04 12:54
浏览 190
已采纳

如何知道负载均衡在Docker Swarm中是否有效?

I created a service called accountservice and replicated it 3 times after. In my service I get IP address of the producing service instance and populate it in JSON response. The question is everytime I run curl $manager-ip:6767/accounts/10000 the returned IP is the same as before (I tried 100 times)

manager-ip environment variable:

set -x manager-ip (docker-machine ip swarm-manager-1)

Here's my Dockerfile:

FROM iron/base

EXPOSE 6767
ADD accountservice-linux-amd64 /
ADD healthchecker-linux-amd64 /
HEALTHCHECK --interval=3s --timeout=3s CMD ["./healthchecker-linux-amd64", "-port=6767"] || exit 1

ENTRYPOINT ["./accountservice-linux-amd64"]

And here's my automation script to build and run service:

#!/usr/bin/env fish

set -x GOOS linux
set -x CGO_ENABLED 0
set -x GOBIN ""

eval (docker-machine env swarm-manager-1)

go get
go build -o accountservice-linux-amd64 .

pushd ./healthchecker
go get
go build -o ../healthchecker-linux-amd64 .
popd

docker build -t azbshiri/accountservice .
docker service rm accountservice
docker service create \
  --name accountservice \
  --network my_network \
  --replicas=1 \
  -p 6767:6767 \
  -p 6767:6767/udp \
  azbshiri/accountservice

And here's the function I call to get the IP:

package common

import "net"

func GetIP() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        return "error"
    }

    for _, addr := range addrs {
        ipnet, ok := addr.(*net.IPNet)
        if ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                return ipnet.IP.String()
            }
        }
    }

    panic("Unable to determine local IP address (non loopback). Exiting.")
}

And I scale the service using the command below:

docker service scale accountservice=3
  • 写回答

1条回答 默认 最新

  • dse3168 2018-05-04 23:35
    关注

    A few things:

    • Your results are normal. By default, a Swarm service has a VIP (virtual IP) in front of the service tasks to act as a load balancer. Trying to reach that service from inside the virtual network will only show that IP.
    • If you want to use a round-robin approach and skip the VIP, you could create a service with --endpoint-mode=dnsrr that would then return a different service task for each DNS request (but your client might be caching DNS names, causing that to show the same IP, which is why VIP is usually better).
    • If you wanted to get a list of IP's for task replicas, do a dig tasks.<servicename> inside the service's network.
    • If you wanted to test something easy, have your service create a random string, or use hostname on startup and return that so you can tell the different replicas when accessing. A easy example is to run one service using image elasticsearch:2 which will return JSON on port 9200 with a different random name per container.
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 python代码,帮调试
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条