Skip to content
New issue

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

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

Already on GitHub? # 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.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants