Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add labels for upstream object #2279

Merged
merged 4 commits into from
Sep 28, 2020

Conversation

imjoey
Copy link
Member

@imjoey imjoey commented Sep 22, 2020

Signed-off-by: imjoey majunjiev@gmail.com

What this PR does / why we need it:

Hi fellows, we could use labels (as it in Kubernetes) to specify attributes that attached an object. This is a kind of extensibility mechanism for developers. Once I had a short discussion with @moonming at apache/apisix-dashboard#431 (comment) , so this PR is going to take upstream as the starting point and add a new labels property, via a rather simple implementation.

Looking forward to the feedback. Thanks.

Pre-submission checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • Have you added corresponding test cases?
  • Have you modified the corresponding document?
  • Is this PR backward compatible?

labels can be used to specify additional attributes.

Signed-off-by: imjoey <majunjiev@gmail.com>
Copy link
Member

@membphis membphis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need a test case, I think it should be invalid.

{
    ... ...
    lables: {
        key: {
             sub_key: ["a", "b", "c"]
        }
    }
}

apisix/schema_def.lua Show resolved Hide resolved
@@ -332,6 +332,10 @@ local upstream_schema = {
description = "enable websocket for request",
type = "boolean"
},
labels = {
description = "key/value pairs to specify attributes",
type = "table"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be object here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to limit the depth to 1

Copy link
Member Author

@imjoey imjoey Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@membphis agreed, nice catch, thanks. I would make changes as the your suggestions and add one more failure test case after I find the lua way. 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@membphis PR is updated and labels are limited to string key/value pairs, so fix the depth problem. 😄

@tokers
Copy link
Contributor

tokers commented Sep 23, 2020

@imjoey One thing confuses me that the labels field is attached on the whole upstream object, It's closer to the labels on Kubernetes Service, not the Pod, and labels on Pod are more pragmatic, so what about attaching labels for each node in this upstream, with this support, we can group the nodes by labels, and in turn implementing some features like blue green release, canary release or other route rules.

@gxthrj
Copy link
Contributor

gxthrj commented Sep 23, 2020

This is a very interesting topic.
I hope to add labels to all objects in apisix, so that some strong bindings through xxx_id can be changed to loose binding relationships through labels. this is very useful and better fit with etcd design.

@imjoey
Copy link
Member Author

imjoey commented Sep 23, 2020

@imjoey One thing confuses me that the labels field is attached on the whole upstream object, It's closer to the labels on Kubernetes Service, not the Pod, and labels on Pod are more pragmatic, so what about attaching labels for each node in this upstream, with this support, we can group the nodes by labels, and in turn implementing some features like blue green release, canary release or other route rules.

Hi @tokers , thanks for your feedback. I guess labels could be very useful for every single object in APISIX. While currently Node is not an independent object so we are not able to mange the labels attached. We may refer to the existing field named metadata in Node for your requirements.

@gxthrj
Copy link
Contributor

gxthrj commented Sep 23, 2020

@imjoey One thing confuses me that the labels field is attached on the whole upstream object, It's closer to the labels on Kubernetes Service, not the Pod, and labels on Pod are more pragmatic, so what about attaching labels for each node in this upstream, with this support, we can group the nodes by labels, and in turn implementing some features like blue green release, canary release or other route rules.

Your idea is great,
But we also need to pay attention to the structure of APISIX,

  1. The nodes under upstream is not an object yet;
  2. Blue-green or canary releases are more tied to business, not suitable for writing in upstream objects, but more suitable for extension in plug-ins, But upstream currently does not provide any plug-in implementation;
    if we add labels in nodes, I think it will be a big change.

@imjoey
Copy link
Member Author

imjoey commented Sep 23, 2020

This is a very interesting topic.
I hope to add labels to all objects in apisix, so that some strong bindings through xxx_id can be changed to loose binding relationships through labels. this is very useful and better fit with etcd design.

@gxthrj yep, glad to hear your thoughts. Yesterday I was about to migrate the functionality of RouteGroup from MySQL to etcd. But it seemed still under discussions in community. So I deliberated on the whole design, I guess labels could make the relationships of objects in APISIX much more loosely coupled, and also make the extensibility more easily.

@nic-chen
Copy link
Member

@imjoey One thing confuses me that the labels field is attached on the whole upstream object, It's closer to the labels on Kubernetes Service, not the Pod, and labels on Pod are more pragmatic, so what about attaching labels for each node in this upstream, with this support, we can group the nodes by labels, and in turn implementing some features like blue green release, canary release or other route rules.

Your idea is great,
But we also need to pay attention to the structure of APISIX,

  1. The nodes under upstream is not an object yet;
  2. Blue-green or canary releases are more tied to business, not suitable for writing in upstream objects, but more suitable for extension in plug-ins, But upstream currently does not provide any plug-in implementation;
    if we add labels in nodes, I think it will be a big change.

I think we don't need to separate nodes from upstream, just redefine the data structure of nodes.
Of course, there is also a lot of work in this way, but it is better to understand.

@imjoey
Copy link
Member Author

imjoey commented Sep 23, 2020

@imjoey One thing confuses me that the labels field is attached on the whole upstream object, It's closer to the labels on Kubernetes Service, not the Pod, and labels on Pod are more pragmatic, so what about attaching labels for each node in this upstream, with this support, we can group the nodes by labels, and in turn implementing some features like blue green release, canary release or other route rules.

Your idea is great,
But we also need to pay attention to the structure of APISIX,

  1. The nodes under upstream is not an object yet;
  2. Blue-green or canary releases are more tied to business, not suitable for writing in upstream objects, but more suitable for extension in plug-ins, But upstream currently does not provide any plug-in implementation;
    if we add labels in nodes, I think it will be a big change.

I think we don't need to separate nodes from upstream, just redefine the data structure of nodes.
Of course, there is also a lot of work in this way, but it is better to understand.

@nic-chen Just FYI, we could make use of the existing metadata field in node, pls refer to https://github.com/apache/apisix/blob/master/apisix/schema_def.lua#L263 for details.

@tokers
Copy link
Contributor

tokers commented Sep 23, 2020

@imjoey One thing confuses me that the labels field is attached on the whole upstream object, It's closer to the labels on Kubernetes Service, not the Pod, and labels on Pod are more pragmatic, so what about attaching labels for each node in this upstream, with this support, we can group the nodes by labels, and in turn implementing some features like blue green release, canary release or other route rules.

Your idea is great,
But we also need to pay attention to the structure of APISIX,

  1. The nodes under upstream is not an object yet;
  2. Blue-green or canary releases are more tied to business, not suitable for writing in upstream objects, but more suitable for extension in plug-ins, But upstream currently does not provide any plug-in implementation;
    if we add labels in nodes, I think it will be a big change.
  1. I think whether the Node is embedded in Upstream or as a separate object doesn't matter, even in XDS protocol, the CDS does not necessarily depend on EDS.

  2. What we can do is not implementing these route rules in upstream logic, instead, a traffic split plugin can be introduced to solve these problems, I will submit an issue this few days, with some details.

@tokers
Copy link
Contributor

tokers commented Sep 24, 2020

@imjoey @gxthrj @nic-chen @membphis @moonming I have submitted an issue about traffic split #2303.

Signed-off-by: imjoey <majunjiev@gmail.com>
@imjoey
Copy link
Member Author

imjoey commented Sep 27, 2020

@membphis @nic-chen @gxthrj PR updated and any feedback would be much appreciated.

@@ -273,6 +273,7 @@ APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上
|checks |可选|配置健康检查的参数,详细可参考[health-check](../health-check.md)|
|retries |可选|使用底层的 Nginx 重试机制将请求传递给下一个上游,默认 APISIX 会启用重试机制,根据配置的后端节点个数设置重试次数,如果此参数显式被设置将会覆盖系统默认设置的重试次数。|
|enable_websocket|可选| 是否启用 `websocket`(布尔值),默认不启用|
|labels |可选| 用于标识属性的键值对。 |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need more doc, we need an example about how to use this field.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@membphis thanks for reviewing. I will add more guidance docs about labels usage and best practice in APISIX after labels are added in all objects.

Copy link
Member

@membphis membphis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor document issues need to be fixed, LGTM

@membphis membphis merged commit ebe4f66 into apache:master Sep 28, 2020
@membphis
Copy link
Member

@imjoey many thx, merged

@moonming moonming added this to the 2.0 milestone Sep 28, 2020
@imjoey imjoey deleted the feat/add_labels_for_upstream branch September 28, 2020 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants