kong-Loadbalancing

2,179 阅读4分钟

简介

kong提供了多种负载均衡到upstream service的方式:最直观的DNS方式;或者是动态的ring-balance方式。

基于DNS的负载均衡

当使用基于DNS的负载均衡时,upstream service的注册是由DNS服务器完成的,是在kong之外的,kong会接收DNS服务器的更新信息。(这种方式我们当前项目不使用)

基于Ring-balancer的负载均衡

这种方式upstream service的增删都由kong控制,不需要DNS更新。这种方式的配置方法如下:

  • target: IP+Port,每个target还有一个权重,支持Ipv4和Ipv6
  • upstream:一个虚拟的hostname,可以用于Route的host字段。例如一个upstream名为:weather.v2.service,可以接受全部host=weather.v2.service的服务的请求。

Upstream

每个upstream有自己的ring-balance。每个upstream可以有很多的target实体与其关联,代理到virtual hostname的请求都会被负载到每个target上。一个ring-balancer有一系列预置数量的槽,根据target的权重分配给每个target。

可以通过向Admin API发送请求来增加或删target。这个操作相对廉价的,修改upstream消耗就比较大,因为它会导致balancer重建。只有当target history清空时balancer才会自动重建,除此之外它只有在改变的时候重建。

balancer中的槽位(1到slots)随机的分布在环上,一个简单的round-robin模式就可以让槽位很好的分布,并且提供廉价增加\删除target的能力。

每个target的槽位数大概在100左右,这样能保证分布的均匀。权衡点在于:槽位越多,分布越随机,但是增/减target的代价越大。

upstream也可以包含健康检查的配置,一个upstream结构的例子如下:

{
    "id": "58c8ccbb-eafb-4566-991f-2ed4f678fa70",
    "created_at": 1422386534,
    "name": "my-upstream",
    "algorithm": "round-robin",
    "hash_on": "none",
    "hash_fallback": "none",
    "hash_on_cookie_path": "/",
    "slots": 10000,
    "healthchecks": {
        "active": {
            "https_verify_certificate": true,
            "unhealthy": {
                "http_statuses": [429, 404, 500, 501, 502, 503, 504, 505],
                "tcp_failures": 0,
                "timeouts": 0,
                "http_failures": 0,
                "interval": 0
            },
            "http_path": "/",
            "timeout": 1,
            "healthy": {
                "http_statuses": [200, 302],
                "interval": 0,
                "successes": 0
            },
            "https_sni": "example.com",
            "concurrency": 10,
            "type": "http"
        },
        "passive": {
            "unhealthy": {
                "http_failures": 0,
                "http_statuses": [429, 500, 503],
                "tcp_failures": 0,
                "timeouts": 0
            },
            "type": "http",
            "healthy": {
                "successes": 0,
                "http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308]
            }
        },
        "threshold": 0
    },
    "tags": ["user-level", "low-priority"],
    "host_header": "example.com"
}

Target

因为upstream维护target的历史,所以不能修改或删除target,只能增加target的事例或修改权重,当把权重设为0的时候,这个target就自动disable了。一个target不但可以是ip地址,也可以是一个hostname,当它为hostname时,该hostname对应的实例会单独的加入到ring balancer中去。例如:添加一个target:api.host.com:123,权重为100。api.host.com可以被解析成2个ip地址,name此时这两个ip地址都会被作为target添加进来,并且每个的权重都是100、端口都是123。注意:权重适用于单独的实体的,而不是曾个hostname。balancer会根据DNS的ttl设置去查询更新记录。

target例子如下:

{
    "id": "a3395f66-2af6-4c79-bea2-1b6933764f80",
    "created_at": 1422386534,
    "upstream": {"id":"885a0392-ef1b-4de3-aacf-af3f1697ce2c"},
    "target": "example.com:8000",
    "weight": 100,
    "tags": ["user-level", "low-priority"]
}

Balancing algorithms

默认的ring-balancer会使用权重round-robin算法。除此之外,kong还提供基于hash的算法。hash的输入可以是,none, consumer, ip, header, 或 cookie. 当设置成none时,round-robin生效。

蓝绿部署

下面例子介绍了如何使用上述内容实现蓝绿部署:

1. 首先部署”blue“环境,运行v1版本服务

# create an upstream
$ curl -X POST http://kong:8001/upstreams \
    --data "name=address.v1.service"

# add two targets to the upstream
$ curl -X POST http://kong:8001/upstreams/address.v1.service/targets \
    --data "target=192.168.34.15:80"
    --data "weight=100"
$ curl -X POST http://kong:8001/upstreams/address.v1.service/targets \
    --data "target=192.168.34.16:80"
    --data "weight=50"

# create a Service targeting the Blue upstream
$ curl -X POST http://kong:8001/services/ \
    --data "name=address-service" \
    --data "host=address.v1.service" \
    --data "path=/address"

# finally, add a Route as an entry-point into the Service
$ curl -X POST http://kong:8001/services/address-service/routes/ \
    --data "hosts[]=address.mydomain.com"

此时包含host头为address.mydomian.com的请求2/3 会被代理到http://192.168.34.15:80/address (weight=100), 1/3会被代理到 http://192.168.34.16:80/address (weight=50).

2. 现在我们部署”Green“

# create a new Green upstream for address service v2
$ curl -X POST http://kong:8001/upstreams \
    --data "name=address.v2.service"

# add targets to the upstream
$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \
    --data "target=192.168.34.17:80"
    --data "weight=100"
$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \
    --data "target=192.168.34.18:80"
    --data "weight=100"

3. 这是我们希望进行blue/green切换,仅仅需要更新一下Service即可。

# Switch the Service from Blue to Green upstream, v1 -> v2
$ curl -X PATCH http://kong:8001/services/address-service \
    --data "host=address.v2.service"

这是再请求,Green的部署将会生效。这种通过Admin API的改变是动态的,并且是立即生效的。