tokers commented on issue #441:
URL: 
https://github.com/apache/apisix-ingress-controller/issues/441#issuecomment-846400865


   > ### Issue description
   > Currently, when we specify a Kubernetes service in `ApisixRoute` as the 
backend, we push all endpoints/pod to the target upstream in APISIX.
   > 
   > Sometimes a Kubernetes Service will contain multiple versions, for 
instance, some endpoints are `v1` while others are `v2`. Users might need to do 
some traffic management among these different releases. But this is not 
feasible in apisix-ingress-controller.
   > 
   > So a subset can be introduced when we select a Kubernetes Service as the 
backend, just like what istio 
[provides](https://istio.io/latest/docs/reference/config/networking/destination-rule/),
 for instance:
   > 
   > ```yaml
   > apiVersion: apisix.apache.org/v2alpha1
   > kind: ApisixRoute
   > metadata:
   >   name: foo-route
   > spec:
   >   http:
   >   - name: foo-canary-route
   >      priority: 1
   >      match:
   >        paths: ["/*"]
   >        hosts: ["foo.org"]
   >        exprs:
   >        - subject:
   >             scope: Cookie
   >             name: sessionid
   >          op: Equal
   >          value: "33333"
   >      backend:
   >        serviceName: foo
   >        servicePort: 80
   >        subset:
   >          name: v2-subset
   >          labels:
   >            version: v2
   >            app: foo
   >   - name: foo-stable-route
   >      priority: 0
   >      match:
   >        paths: ["/*"]
   >        hosts: ["foo.org"]
   >      backend:
   >        serviceName: foo
   >        servicePort: 80
   >        subset:
   >          name: v1-subset
   >          labels:
   >            version: v1
   >            app: foo
   > ```
   > 
   > In the above example, requests which `sesssionid` in cookie is `33333` 
will hit the first route then forward to the subset of foo service where pods 
version is `v2`. For requests which don't meet the route conditions, will hit 
the second route then forward to the subset of foo service where pods version 
is `v1`.
   
   After deep consideration, I found it's not a good idea to define subset in 
ApisixRoute directly, the following problem has to be addressed in such a case:
   
   * How to name the Apisix Upstream?
   
   We cannot just use service namespace + service name + service port to name 
an upstream, as there might exist multiple subsets for the service, we may need 
to use subset name as the extra component to compose the upstream name. If so, 
we'll meet another problem, how to find this upstream when endpoints for this 
service change? we know nothing in the endpoints controller loop. It will be 
tough to traverse all ApisixRoute objects or mapping the reference relationship 
between ApisixRoute and Service.
   
   The definition and reference of the subset should be separated. A good way 
is define subset to ApisixUpstream and use it in ApisixRoute (just by its name).
   
   ```yaml
   apiVersion: apisix.apache.org/v1
   kind: ApisixUpstream
   metadata:
     name: foo-service
   spec:
     subsets:
     - name: group-v1
        labels:
          version: v1
          app: foo
          env: prod
     - name: group-v2
        labels:
           version: v2
           app: foo
           env: prod
   ---
   apiVersion: apisix.apache.org/v2alpha1
   kind: ApisixRoute
   metadata:
     name: foo-route
   spec:
     http:
     - name: route1
        match:
          paths: ["/*"]
        backends:
        - serviceName: foo-service
          servicePort: 9080
          subset: v1
        - serviceName: foo-service
          servicePort: 9080
          subset: v2
   ```
   
   By this design, we name an upstream with the subset component (if any), and 
when endpoints change, subset array still can be found since the name of 
ApisixUpstream is named to the Service, i.e. the endpoint.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to