diff --git a/apisix/schema_def.lua b/apisix/schema_def.lua index 706062414685..bc0776544836 100644 --- a/apisix/schema_def.lua +++ b/apisix/schema_def.lua @@ -321,25 +321,6 @@ local upstream_schema = { }, required = {"connect", "send", "read"}, }, - k8s_deployment_info = { - type = "object", - properties = { - namespace = {type = "string", description = "k8s namespace"}, - deploy_name = {type = "string", description = "k8s deployment name"}, - service_name = {type = "string", description = "k8s service name"}, - port = {type = "number", minimum = 0}, - backend_type = { - type = "string", - default = "pod", - description = "k8s service name", - enum = {"svc", "pod"} - }, - }, - anyOf = { - {required = {"namespace", "deploy_name", "port"}}, - {required = {"namespace", "service_name", "port"}}, - }, - }, type = { description = "algorithms of load balancing", type = "string", @@ -391,7 +372,6 @@ local upstream_schema = { }, anyOf = { {required = {"type", "nodes"}}, - {required = {"type", "k8s_deployment_info"}}, {required = {"type", "service_name"}}, }, additionalProperties = false, diff --git a/doc/admin-api.md b/doc/admin-api.md index 367a0f375a94..0726e85e3b8a 100644 --- a/doc/admin-api.md +++ b/doc/admin-api.md @@ -507,8 +507,7 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst |Name |Optional|Description| |------- |-----|------| |type |required|`roundrobin` supports the weight of the load, `chash` consistency hash,`ewma` minimum latency ,pick one of them.see https://en.wikipedia.org/wiki/EWMA_chart for details| -|nodes |required if `k8s_deployment_info` not configured|Hash table, the key of the internal element is the upstream machine address list, the format is `Address + Port`, where the address part can be IP or domain name, such as `192.168.1.100:80`, `foo.com:80`, etc. Value is the weight of the node. In particular, when the weight value is `0`, it has a special meaning, which usually means that the upstream node is invalid and never wants to be selected. The `nodes` can be empty, which means it is a placeholder and will be filled later. Clients use such an upstream will get 502 response. | -|k8s_deployment_info|required if `nodes` not configured|fields: `namespace`、`deploy_name`、`service_name`、`port`、`backend_type`, `port` is number, `backend_type` is `pod` or `service`, others is string. | +|nodes |required|Hash table, the key of the internal element is the upstream machine address list, the format is `Address + Port`, where the address part can be IP or domain name, such as `192.168.1.100:80`, `foo.com:80`, etc. Value is the weight of the node. In particular, when the weight value is `0`, it has a special meaning, which usually means that the upstream node is invalid and never wants to be selected. The `nodes` can be empty, which means it is a placeholder and will be filled later. Clients use such an upstream will get 502 response. | |hash_on |optional|This option is only valid if the `type` is `chash`. Supported types `vars`(Nginx variables), `header`(custom header), `cookie`, `consumer`, the default value is `vars`.| |key |optional|This option is only valid if the `type` is `chash`. Find the corresponding node `id` according to `hash_on` and `key`. When `hash_on` is set as `vars`, `key` is the required parameter, for now, it support nginx built-in variables like `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`, `arg_***` is arguments in the request line, [Nginx variables list](http://nginx.org/en/docs/varindex.html). When `hash_on` is set as `header`, `key` is the required parameter, and `header name` is customized. When `hash_on` is set to `cookie`, `key` is the required parameter, and `cookie name` is customized. When `hash_on` is set to `consumer`, `key` does not need to be set. In this case, the `key` adopted by the hash algorithm is the `consumer_name` authenticated. If the specified `hash_on` and `key` can not fetch values, it will be fetch `remote_addr` by default.| |checks |optional|Configure the parameters of the health check. For details, refer to [health-check](health-check.md).| @@ -522,6 +521,14 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst |create_time|optional| epoch timestamp in second, like `1602883670`, will be created automatically if missing| |update_time|optional| epoch timestamp in second, like `1602883670`, will be created automatically if missing| +`hash_on` can be set to different types: + +1. when it is `vars`, the `key` is required. The `key` can be any [Nginx builtin variables](http://nginx.org/en/docs/varindex.html), without the prefix '$'. +1. when it is `header`, the `key` is required. It is equal to "http_`key`". +1. when it is `cookie`, the `key` is required. It is equal to "cookie_`key`". +1. when it is `consumer`, the `key` is optional. The key is the `consumer_name` set by authentication plugin. +1. If there is no value for either `hash_on` or `key`, `remote_addr` will be used as key. + Config Example: ```shell @@ -534,13 +541,6 @@ Config Example: "read":15, }, "nodes": {"host:80": 100}, # Upstream machine address list, the format is `Address + Port` - "k8s_deployment_info": { # kubernetes deployment info - "namespace": "test-namespace", - "deploy_name": "test-deploy-name", - "service_name": "test-service-name", - "backend_type": "pod", # pod or service - "port": 8080 - }, "type":"roundrobin", # chash or roundrobin "checks": {}, # Health check parameters "hash_on": "", diff --git a/doc/architecture-design.md b/doc/architecture-design.md index bd49f11f4d5e..2166845f40d3 100644 --- a/doc/architecture-design.md +++ b/doc/architecture-design.md @@ -260,40 +260,14 @@ Upstream configuration can be directly bound to the specified `Route` or it can ### Configuration -In addition to the basic complex equalization algorithm selection, APISIX's Upstream also supports logic for upstream passive health check and retry, see the table below. - -|Name |Optional|Description| -|------- |-----|------| -|type |required|`roundrobin` supports the weight of the load, `chash` consistency hash, pick one of them.| -|nodes |required if `service_name` and `k8s_deployment_info` not configured|Hash table, the key of the internal element is the upstream machine address list, the format is `Address + Port`, where the address part can be IP or domain name, such as `192.168.1.100:80`, `foo.com:80`, etc. Value is the weight of the node. In particular, when the weight value is `0`, it has a special meaning, which usually means that the upstream node is invalid and never wants to be selected.| -|service_name |required if `nodes` and `k8s_deployment_info` not configured |The name of the upstream service and used with the registry, refer to [Integration service discovery registry](discovery.md).| -|k8s_deployment_info |required if `nodes` and `service_name` not configured|fields: `namespace`、`deploy_name`、`service_name`、`port`、`backend_type`, `port` is number, `backend_type` is `pod` or `service`, others is string. | -|hash_on |optional|This option is only valid if the `type` is `chash`. Supported types `vars`(Nginx variables), `header`(custom header), `cookie`, `consumer`, the default value is `vars`.| -|key |required|This option is only valid if the `type` is `chash`. Find the corresponding node `id` according to `hash_on` and `key`. When `hash_on` is set as `vars`, `key` is the required parameter, for now, it support nginx built-in variables like `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`, `arg_***` is arguments in the request line, [Nginx variables list](http://nginx.org/en/docs/varindex.html). When `hash_on` is set as `header`, `key` is the required parameter, and `header name` is customized. When `hash_on` is set to `cookie`, `key` is the required parameter, and `cookie name` is customized. When `hash_on` is set to `consumer`, `key` does not need to be set. In this case, the `key` adopted by the hash algorithm is the `consumer_name` authenticated. If the specified `hash_on` and `key` can not fetch values, it will be fetch `remote_addr` by default.| -|checks |optional|Configure the parameters of the health check. For details, refer to [health-check](health-check.md).| -|retries |optional|Pass the request to the next upstream using the underlying Nginx retry mechanism, the retry mechanism is enabled by default and set the number of retries according to the number of backend nodes. If `retries` option is explicitly set, it will override the default value.| -|timeout|optional| Set the timeout for connection, sending and receiving messages. | -|desc |optional|Identifies route names, usage scenarios, and more.| -|labels |optional|The key/value pairs to specify attributes. | -|pass_host |optional|`pass` pass the client request host, `node` not pass the client request host, using the upstream node host, `rewrite` rewrite host by the configured `upstream_host`.| -|upstream_host |optional|This option is only valid if the `pass_host` is `rewrite`.| +In addition to the basic complex equalization algorithm selection, APISIX's Upstream also supports logic for upstream passive health check and retry, see the link below. + +https://github.com/apache/apisix/blob/master/doc/admin-api.md#upstream Create an upstream object use case: ```json curl http://127.0.0.1:9080/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' -{ - "type": "roundrobin", - "k8s_deployment_info": { - "namespace": "test-namespace", - "deploy_name": "test-deploy-name", - "service_name": "test-service-name", - "backend_type": "pod", - "port": 8080 - } -}' - -curl http://127.0.0.1:9080/apisix/admin/upstreams/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "type": "chash", "key": "remote_addr", @@ -310,7 +284,7 @@ After the upstream object is created, it can be referenced by specific `Route` o curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri": "/index.html", - "upstream_id": 2 + "upstream_id": 1 }' ``` diff --git a/doc/zh-cn/admin-api.md b/doc/zh-cn/admin-api.md index b30dee4f506f..18397a51cd56 100644 --- a/doc/zh-cn/admin-api.md +++ b/doc/zh-cn/admin-api.md @@ -515,14 +515,13 @@ APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上 |名字 |可选项 |类型 |说明 |示例| |---------|---------|----|-----------|----| -|nodes |与 `k8s_deployment_info` 二选一|Node|哈希表,内部元素的 key 是上游机器地址列表,格式为`地址 + Port`,其中地址部分可以是 IP 也可以是域名,比如 `192.168.1.100:80`、`foo.com:80`等。value 则是节点的权重,特别的,当权重值为 `0` 有特殊含义,通常代表该上游节点失效,永远不希望被选中。`nodes` 可以为空,这通常用作占位符。客户端命中这样的上游会返回 502。|`192.168.1.100:80`| -|k8s_deployment_info|与 `nodes` 二选一|哈希表|字段包括 `namespace`、`deploy_name`、`service_name`、`port`、`backend_type`,其中 `port` 字段为数值,`backend_type` 为 `pod` 或 `service`,其他为字符串 | `{"namespace": "test-namespace", "deploy_name": "test-deploy-name", "service_name": "test-service-name", "backend_type": "pod", "port": 8080}` | +|nodes |必需|Node|哈希表,内部元素的 key 是上游机器地址列表,格式为`地址 + Port`,其中地址部分可以是 IP 也可以是域名,比如 `192.168.1.100:80`、`foo.com:80`等。value 则是节点的权重,特别的,当权重值为 `0` 有特殊含义,通常代表该上游节点失效,永远不希望被选中。`nodes` 可以为空,这通常用作占位符。客户端命中这样的上游会返回 502。|`192.168.1.100:80`| |type |必需|枚举|`roundrobin` 支持权重的负载,`chash` 一致性哈希,两者是二选一的|`roundrobin`|| |key |条件必需|匹配类型|该选项只有类型是 `chash` 才有效。根据 `key` 来查找对应的 node `id`,相同的 `key` 在同一个对象中,永远返回相同 id,目前支持的 Nginx 内置变量有 `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`,其中 `arg_***` 是来自URL的请求参数,[Nginx 变量列表](http://nginx.org/en/docs/varindex.html)|| |checks |可选|health_checker|配置健康检查的参数,详细可参考[health-check](../health-check.md)|| |retries |可选|整型|使用底层的 Nginx 重试机制将请求传递给下一个上游,默认启用重试且次数为后端 node 数量。如果指定了具体重试次数,它将覆盖默认值。`0` 代表不启用重试机制|| |timeout |可选|超时时间对象|设置连接、发送消息、接收消息的超时时间|| -|hash_on |可选 |辅助|该参数作为一致性 hash 的入参|| +|hash_on |可选|辅助|`hash_on` 支持的类型有 `vars`(Nginx内置变量),`header`(自定义header),`cookie`,`consumer`,默认值为 `vars`| |name |可选 |辅助|标识上游服务名称、使用场景等。|| |desc |可选 |辅助|上游服务描述、使用场景等。|| |pass_host |可选|枚举|`pass` 透传客户端请求的 host, `node` 不透传客户端请求的 host, 使用 upstream node 配置的 host, `rewrite` 使用 `upstream_host` 配置的值重写 host 。|| @@ -531,6 +530,14 @@ APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上 |create_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670| |update_time|可选|辅助|单位为秒的 epoch 时间戳,如果不指定则自动创建|1602883670| +`hash_on` 比较复杂,这里专门说明下: + +1. 设为 `vars` 时,`key` 为必传参数,目前支持的 Nginx 内置变量有 `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`,其中 `arg_***` 是来自URL的请求参数,[Nginx 变量列表](http://nginx.org/en/docs/varindex.html) +1. 设为 `header` 时, `key` 为必传参数,其值为自定义的 header name, 即 "http_`key`" +1. 设为 `cookie` 时, `key` 为必传参数,其值为自定义的 cookie name,即 "cookie_`key`" +1. 设为 `consumer` 时,`key` 不需要设置。此时哈希算法采用的 `key` 为认证通过的 `consumer_name`。 +1. 如果指定的 `hash_on` 和 `key` 获取不到值时,就是用默认值:`remote_addr`。 + upstream 对象 json 配置内容: ```shell @@ -543,13 +550,6 @@ upstream 对象 json 配置内容: "read":15, }, "nodes": {"host:80": 100}, # 上游机器地址列表,格式为`地址 + Port` - "k8s_deployment_info": { # k8s deployment 信息 - "namespace": "test-namespace", - "deploy_name": "test-deploy-name", - "service_name": "test-service-name", - "backend_type": "pod", # pod or service - "port": 8080 - }, "type":"roundrobin", # chash or roundrobin "checks": {}, # 配置健康检查的参数 "hash_on": "", diff --git a/doc/zh-cn/architecture-design.md b/doc/zh-cn/architecture-design.md index e98720b9e376..d867e9bb2abb 100644 --- a/doc/zh-cn/architecture-design.md +++ b/doc/zh-cn/architecture-design.md @@ -271,46 +271,14 @@ Upstream 的配置可以被直接绑定在指定 `Route` 中,也可以被绑 ### 配置参数 -APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上游做主被动健康检查、重试等逻辑,具体看下面表格。 - -|名字 |可选|说明| -|------- |-----|------| -|type |必填|`roundrobin` 支持权重的负载,`chash` 一致性哈希,两者是二选一的| -|nodes |与 `k8s_deployment_info`、 `service_name` 三选一|哈希表,内部元素的 key 是上游机器地址列表,格式为`地址 + Port`,其中地址部分可以是 IP 也可以是域名,比如 `192.168.1.100:80`、`foo.com:80` 等。value 则是节点的权重。当权重值为 `0` 代表该上游节点失效,不会被选中,可以用于暂时摘除节点的情况。| -|service_name |与 `nodes`、 `k8s_deployment_info` 三选一 |用于设置上游服务名,并配合注册中心使用,详细可参考[集成服务发现注册中心](discovery.md) | -|k8s_deployment_info|与 `nodes`、 `service_name` 三选一|哈希表|字段包括 `namespace`、`deploy_name`、`service_name`、`port`、`backend_type`,其中 `port` 字段为数值,`backend_type` 为 `pod` 或 `service`,其他为字符串 | -|key |可选|在 `type` 等于 `chash` 是必选项。 `key` 需要配合 `hash_on` 来使用,通过 `hash_on` 和 `key` 来查找对应的 node `id`| -|hash_on |可选|`hash_on` 支持的类型有 `vars`(Nginx内置变量),`header`(自定义header),`cookie`,`consumer`,默认值为 `vars`| -|checks |可选|配置健康检查的参数,详细可参考[health-check](../health-check.md)| -|retries |可选|使用底层的 Nginx 重试机制将请求传递给下一个上游,默认 APISIX 会启用重试机制,根据配置的后端节点个数设置重试次数,如果此参数显式被设置将会覆盖系统默认设置的重试次数。| -|labels |可选| 用于标识属性的键值对。 | -|pass_host |可选|`pass` 透传客户端请求的 host, `node` 不透传客户端请求的 host, 使用 upstream node 配置的 host, `rewrite` 使用 `upstream_host` 配置的值重写 host 。| -|upstream_host |可选|只在 `pass_host` 配置为 `rewrite` 时有效。| - -`hash_on` 比较复杂,这里专门说明下: - -1. 设为 `vars` 时,`key` 为必传参数,目前支持的 Nginx 内置变量有 `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`,其中 `arg_***` 是来自URL的请求参数,[Nginx 变量列表](http://nginx.org/en/docs/varindex.html) -1. 设为 `header` 时, `key` 为必传参数,其值为自定义的 header name, 即 "http_`key`" -1. 设为 `cookie` 时, `key` 为必传参数,其值为自定义的 cookie name,即 "cookie_`key`" -1. 设为 `consumer` 时,`key` 不需要设置。此时哈希算法采用的 `key` 为认证通过的 `consumer_name`。 -1. 如果指定的 `hash_on` 和 `key` 获取不到值时,就是用默认值:`remote_addr`。 +APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上游做主被动健康检查、重试等逻辑,具体看下面的链接。 + +https://github.com/apache/apisix/blob/master/doc/admin-api.md#upstream 创建上游对象用例: ```json curl http://127.0.0.1:9080/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' -{ - "type": "roundrobin", - "k8s_deployment_info": { - "namespace": "test-namespace", - "deploy_name": "test-deploy-name", - "service_name": "test-service-name", - "backend_type": "pod", - "port": 8080 - } -}' - -curl http://127.0.0.1:9080/apisix/admin/upstreams/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "type": "chash", "key": "remote_addr", diff --git a/t/node/upstream.t b/t/node/upstream.t index 326cc121f75c..9acbb28e7376 100644 --- a/t/node/upstream.t +++ b/t/node/upstream.t @@ -53,42 +53,7 @@ GET /t -=== TEST 2: set upstream(id: 1) k8s deployment info ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/upstreams/1', - ngx.HTTP_PUT, - [[{ - "k8s_deployment_info": { - "namespace": "test-namespace", - "deploy_name": "test-deploy-name", - "service_name": "test-service-name", - "backend_type": "pod", - "port": 8080 - }, - "type": "roundrobin", - "desc": "new upstream" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed ---- no_error_log -[error] - - - -=== TEST 3: set upstream(id: 1) nodes +=== TEST 2: set upstream(id: 1) nodes --- config location /t { content_by_lua_block { @@ -119,7 +84,7 @@ passed -=== TEST 4: set route(id: 1) +=== TEST 3: set route(id: 1) --- config location /t { content_by_lua_block { @@ -147,7 +112,7 @@ passed -=== TEST 5: /not_found +=== TEST 4: /not_found --- request GET /not_found --- error_code: 404 @@ -158,7 +123,7 @@ GET /not_found -=== TEST 6: hit routes +=== TEST 5: hit routes --- request GET /hello --- response_body @@ -168,7 +133,7 @@ hello world -=== TEST 7: delete upstream(id: 1) +=== TEST 6: delete upstream(id: 1) --- config location /t { content_by_lua_block { @@ -193,7 +158,7 @@ GET /t -=== TEST 8: delete route(id: 1) +=== TEST 7: delete route(id: 1) --- config location /t { content_by_lua_block { @@ -217,7 +182,7 @@ GET /t -=== TEST 9: delete upstream(id: 1) +=== TEST 8: delete upstream(id: 1) --- config location /t { content_by_lua_block { @@ -241,7 +206,7 @@ GET /t -=== TEST 10: delete upstream again(id: 1) +=== TEST 9: delete upstream again(id: 1) --- config location /t { content_by_lua_block { @@ -265,7 +230,7 @@ GET /t -=== TEST 11: set upstream(id: 1, using `node` mode to pass upstream host) +=== TEST 10: set upstream(id: 1, using `node` mode to pass upstream host) --- config location /t { content_by_lua_block { @@ -297,7 +262,7 @@ passed -=== TEST 12: set route(id: 1, using `node` mode to pass upstream host) +=== TEST 11: set route(id: 1, using `node` mode to pass upstream host) --- config location /t { content_by_lua_block { @@ -325,7 +290,7 @@ passed -=== TEST 13: hit route +=== TEST 12: hit route --- request GET /get --- response_body eval @@ -335,7 +300,7 @@ qr/"Host": "httpbin.org"/ -=== TEST 14: set upstream(id: 1, using `rewrite` mode to pass upstream host) +=== TEST 13: set upstream(id: 1, using `rewrite` mode to pass upstream host) --- config location /t { content_by_lua_block { @@ -368,7 +333,7 @@ passed -=== TEST 15: set route(id: 1, using `rewrite` mode to pass upstream host) +=== TEST 14: set route(id: 1, using `rewrite` mode to pass upstream host) --- config location /t { content_by_lua_block { @@ -396,7 +361,7 @@ passed -=== TEST 16: hit route +=== TEST 15: hit route --- request GET /uri --- response_body eval @@ -406,7 +371,7 @@ qr/host: httpbin.org/ -=== TEST 17: set route(upstream deleted) +=== TEST 16: set route(upstream deleted) --- config location /t { content_by_lua_block { @@ -434,7 +399,7 @@ passed -=== TEST 18: delete upstream +=== TEST 17: delete upstream --- config location /t { content_by_lua_block { @@ -458,7 +423,7 @@ passed -=== TEST 19: hit route +=== TEST 18: hit route --- request GET /uri --- error_code: 502