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

The upstrem configuration rewrite and upstrem_host in the traffic-split plug-in did not take effect correctly #3851

Closed
aiyiyi121 opened this issue Mar 17, 2021 · 10 comments · Fixed by #3870

Comments

@aiyiyi121
Copy link

aiyiyi121 commented Mar 17, 2021

Issue description

目的:想要根据分流规则,比如-H "user-name:test",改变Host让流量跑到k8s集群中不同的ingress。

实现方法:使用nginx做为ingress controller,流量根据规则转向同一个k8s里的不同ingress。apisix的route中,nodes里面填的是同一个k8s集群ingress controller的地址,根据规则把upstream_host改为ingress服务的host。详细配置见下面

遇到问题:traffic-split里面的upstream通过upstream_host字段不能正确改变Host值,访问时报错404,不把upstream配在traffic-split里时没问题

Environment

  • apisix version (cmd: apisix version): 2.4
  • OS (cmd: uname -a): Ubuntu 16.04.2 LTS
  • OpenResty / Nginx version (cmd: nginx -V or openresty -V): openresty/1.19.3.1
  • etcd version, if have (cmd: run curl http://127.0.0.1:9090/v1/server_info to get the info from server-info API): 3.4.13
  • apisix-dashboard version, if have: 2.4

路由配置

curl http://127.0.0.1:9080/apisix/admin/routes/10 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/route10",
    "plugins": {
        "traffic-split": {
            "rules": [
                {
                    "match": [
                        {
                            "vars": [
                                ["http_username", "==", "test"]
                            ]
                        }
                    ],
                    "weighted_upstreams": [
                        {
                            "upstream": {
                                    "type": "roundrobin",
                                    "pass_host": "rewrite",
                                    "upstream_host": "echo-headers.pro.test-k8s.qslocal.com",
                                    "nodes": {
                                        "10.255.1.107:80":1,
                                        "10.255.1.108:80":1
                                    }
                            }
                        }
                    ]
                }
            ]
        }
    },
    "upstream": {
            "type": "roundrobin",
            "pass_host": "rewrite",
            "upstream_host": "echo-headers.pro.test-k8s.qslocal.com",
            "nodes": {
                "10.255.1.107:80":1,
                "10.255.1.108:80":1
            }
    }
}'

What's the actual result? (including assertion message & call stack if applicable)

traffic-split插件中upstream_host改变没生效,流量到不了相应host的ingress,报错404

@Firstsawyou
Copy link
Contributor

The current plugin only supports the pass_host operation when the upstream node is a domain name. If the upstream node is IP, the pass_host operation is not performed. Please refer here: https://github.com/apache/apisix/blob/master/apisix/plugins/traffic-split.lua#L151-L152

Example:

curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/route01",
    "plugins": {
        "traffic-split": {
            "rules": [
                {
                    "match": [
                        {
                            "vars": [
                                ["http_username", "==", "test"]
                            ]
                        }
                    ],
                    "weighted_upstreams": [
                        {
                            "upstream": {
                                    "type": "roundrobin",
                                    "pass_host": "rewrite",
                                    "upstream_host": "echo-headers.pro.test-k8s.qslocal.com",
                                    "nodes": {
                                        "localhost:1990":1                                        
                                    }
                            }
                        }
                    ]
                }
            ]
        }
    },
    "upstream": {
            "type": "roundrobin",            
            "nodes": {
                "127.0.0.1:1980":1               
            }
    }
}'
 curl http://127.0.0.1:9080/route01  -H 'username:test'
request_uri: /route01
x-real-ip: ::1
x-forwarded-for: ::1
x-forwarded-proto: http
x-forwarded-host: localhost
x-forwarded-port: 9080
host: echo-headers.pro.test-k8s.qslocal.com
accept: */*
username: test
user-agent: curl/7.29.0

It seems that the plugin needs to support the situation where the upstream node is IP.

@tokers
Copy link
Contributor

tokers commented Mar 18, 2021

The current plugin only supports the pass_host operation when the upstream node is a domain name. If the upstream node is IP, the pass_host operation is not performed. Please refer here: https://github.com/apache/apisix/blob/master/apisix/plugins/traffic-split.lua#L151-L152

Example:

curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/route01",
    "plugins": {
        "traffic-split": {
            "rules": [
                {
                    "match": [
                        {
                            "vars": [
                                ["http_username", "==", "test"]
                            ]
                        }
                    ],
                    "weighted_upstreams": [
                        {
                            "upstream": {
                                    "type": "roundrobin",
                                    "pass_host": "rewrite",
                                    "upstream_host": "echo-headers.pro.test-k8s.qslocal.com",
                                    "nodes": {
                                        "localhost:1990":1                                        
                                    }
                            }
                        }
                    ]
                }
            ]
        }
    },
    "upstream": {
            "type": "roundrobin",            
            "nodes": {
                "127.0.0.1:1980":1               
            }
    }
}'
 curl http://127.0.0.1:9080/route01  -H 'username:test'
request_uri: /route01
x-real-ip: ::1
x-forwarded-for: ::1
x-forwarded-proto: http
x-forwarded-host: localhost
x-forwarded-port: 9080
host: echo-headers.pro.test-k8s.qslocal.com
accept: */*
username: test
user-agent: curl/7.29.0

It seems that the plugin needs to support the situation where the upstream node is IP.

So what should @aiyiyi121 do so he/she can resolve this problem?

@Chinaxiang
Copy link

Why only supports a single upstream of the domain name? IP should be universal. Have any other problems?

@aiyiyi121
Copy link
Author

The current plugin only supports the pass_host operation when the upstream node is a domain name. If the upstream node is IP, the pass_host operation is not performed. Please refer here: https://github.com/apache/apisix/blob/master/apisix/plugins/traffic-split.lua#L151-L152
Example:

curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/route01",
    "plugins": {
        "traffic-split": {
            "rules": [
                {
                    "match": [
                        {
                            "vars": [
                                ["http_username", "==", "test"]
                            ]
                        }
                    ],
                    "weighted_upstreams": [
                        {
                            "upstream": {
                                    "type": "roundrobin",
                                    "pass_host": "rewrite",
                                    "upstream_host": "echo-headers.pro.test-k8s.qslocal.com",
                                    "nodes": {
                                        "localhost:1990":1                                        
                                    }
                            }
                        }
                    ]
                }
            ]
        }
    },
    "upstream": {
            "type": "roundrobin",            
            "nodes": {
                "127.0.0.1:1980":1               
            }
    }
}'
 curl http://127.0.0.1:9080/route01  -H 'username:test'
request_uri: /route01
x-real-ip: ::1
x-forwarded-for: ::1
x-forwarded-proto: http
x-forwarded-host: localhost
x-forwarded-port: 9080
host: echo-headers.pro.test-k8s.qslocal.com
accept: */*
username: test
user-agent: curl/7.29.0

It seems that the plugin needs to support the situation where the upstream node is IP.

So what should @aiyiyi121 do so he/she can resolve this problem?

I solve this problem by referencing upstream_id in the traffic-split plug-in, because I have no other way.

@Firstsawyou
Copy link
Contributor

So what should @aiyiyi121 do so he/she can resolve this problem?

We can use the upstream_id of the traffic-split plugin to refer to the upstream to solve the problem.

@Firstsawyou
Copy link
Contributor

Why only supports a single upstream of the domain name? IP should be universal. Have any other problems?

We should also support the ip situation. PR is welcome.

@moonming
Copy link
Member

@aiyiyi121
Please use English in the public channel, thx

@moonming moonming changed the title bug: traffic-split插件里的upstrem配置rewrite和upstrem_host,没有正确生效 The upstrem configuration rewrite and upstrem_host in the traffic-split plug-in did not take effect correctly Mar 19, 2021
@aiyiyi121
Copy link
Author

@aiyiyi121
Please use English in the public channel, thx

OK,thx. I think this issue can be closed.

@Chinaxiang

This comment has been minimized.

@juzhiyuan
Copy link
Member

We Apache community build software shared by the global world, and welcome anyone to use and give feedback.

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 a pull request may close this issue.

6 participants