Can Kubernetes Service control traffic percentage to a given pod? - kubernetes

Is it possible to control the percentage of traffic going to a particular pod with Kubernetes Service, without controlling the number of underlying pod? By default, kube- chooses a backend via a round-robin algorithm.

Yes, possible with the extra configuration of Service mesh.
If you looking forward to do it using the simple service it's hard to do it based on % as the default behavior is round-robin.
For example, if you are using the Istio service mesh
You can route the traffic based on weight
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 50
- destination:
host: reviews
subset: v3
weight: 50
where subset you can consider is more like the label so you are running the deployments with multiple labels and do the routing based on weight using the Istio.
See the example.

Related

How to replicate some traffic on Kubernetes and divert it to the Service for investigation

I'm using istio and I know that I can define weights in Virtual Service and divert traffic to different services.
My question is: how to amplify some of the traffic and direct the amplified traffic to the validation service? This amplified traffic will not go back to the original source but will be closed within the cluster. In other words, it does not bother the user.
I'm not even sure if there is an ecosystem, feature or application that provides this kind of mechanism. I don't even know if there is an ecosystem or application that provides such a mechanism and I don't know what it is called, so I'm having trouble finding it.
Thanks.
OP found a soultion by themselves, in the comments, hence the CW.
In this scenario, the best solution is to use Istio Mirroring - also called shadowing.
When traffic gets mirrored, the requests are sent to the mirrored service with their Host/Authority headers appended with -shadow. For example, cluster-1 becomes cluster-1-shadow.
Also, it is important to note that these requests are mirrored as “fire and forget”, which means that the responses are discarded.
To create mirroring rule, you have to create VirtualService with mirror and mirrorPercentage fields.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
http:
- route:
- destination:
host: httpbin
subset: v1
weight: 100
mirror:
host: httpbin
subset: v2
mirrorPercentage:
value: 100.0
This route rule sends 100% of the traffic to v1. The last stanza specifies that you want to mirror (i.e., also send) 100% of the same traffic to the httpbin:v2 service.
[source]

Why isn't the circuit breaking of ISTIO working?

with istio 1.4.6
I configured Kubernetes using resources such as service, deployment.
I also configured gateway, virtual service, and destination rules to implement circuit breakers.
The composition diagram is as follows. (number of Pod's replica is two. & I operate only one version of app.)
I wrote VirtualServices and DestinationRules to use circuit breakers
VirtualService
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews-virtual-service
spec:
gateways:
- reviews-istio-gateway
hosts:
- reviews
http:
- route:
- destination:
host: reviews-service
port:
number: 80
DestinationRules
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews-destination-rule
spec:
host: reviews
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
outlierDetection:
baseEjectionTime: 1m
consecutiveErrors: 1
interval: 1s
maxEjectionPercent: 100
Here, I expect that if more than one error occurs in reviews-app, all pods will be excluded from the load balancing list for a minute.
Therefore, I expected the circuit breaking to work as below.
However, contrary to expectations, circuit breakers did not work, and error logs were continuously being recorded in reviews-app.
Why isn't the circuit breaker working?
I guess the problem is not about Circuit Breaking, but about the usage of Virtual Services and Destination Rules.
For example, if using a Virtual Service with a Gateway, its host should probably be of public host, like http://amce.io
The host of the Destination Rule should probably be that of the Kubernetes Service.

Istio routing unique URL to specific pod

I am interested in using Istio in a use case where I spin up a pod based on some event (user starting a game for example), and allow that user to connect to the specific pod through a unqiue URL. Then when this game is over, I can spin the pod down.
I am trying to configure Istio in such a way that either the subdomain or URL can indicate a specific pod to send that request.
Maybe some way to dynamically control label matching? Like <pod_label>.api.com routes to pod matching label label_name: <pod_label> without having to update VirtualServices and DestinationRoutes every time a pod is created?
Edit:
A psuedo config would look similar to:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: dynamic-route
spec:
hosts:
- r.prod.svc.cluster.local
http:
- match:
uri:
prefix: "/pod/{pod_name}"
ignoreUriCase: true
route:
- destination:
host: {pod_name}.prod.svc.cluster.local
(not sure if this would belong in the virtual service or the destination route)

How to use variables in Istio VirtualService?

I'm currently working on a case when we need to dynamically create services and provide access to them via URI subpaths of the main gateway.
I'm planning to use virtual services for traffic routing for them. Virtual Service for a particular service should look like:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: subpaths-routes
spec:
hosts:
- mainservice.prod.svc.cluster.local
http:
- name: "subpath-redirection"
match:
- uri:
prefix: "/bservices/svc-2345-6789"
route:
- destination:
host: svc-2345-6789.prod.svc.cluster.local
But there may be a huge number of such services (like thousands). All follow the same pattern of routing.
I would like to know if Istio has a mechanism to specify VirtualService with variables/parameters like the following:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: subpaths-routes
spec:
hosts:
- mainservice.prod.svc.cluster.local
http:
- name: "subpath-redirection"
match:
- uri:
prefix: "/bservices/"{{ variable }}
route:
- destination:
host: {{ variable }}.prod.svc.cluster.local
In Nginx, one can do a similar thing by specifying something like this:
location ~ /service/(?<variable>[0-9a-zA-Z\_\-]+)/ {
proxy_pass http://$variable:8080;
}
Is there a way in Istio to accomplish that?
And if there is not, how would thousands of VSs impact the performance of request processing? Is It expensive to keep them in terms of CPU and RAM being consumed?
Thank you in advance!
How to use variables in Istio VirtualService?
As far as I know there is no such option in istio to specify a variable in prefix and host, if it was only a prefix then you could try with regex instead of prefix.
If you would like to automate it in some way, I mean create a variable and put in in both, prefix and host, then you could try do to it with helm.
There are few examples for virtual service in helm.
https://github.com/streamsets/helm-charts/blob/master/incubating/control-hub/templates/istio-gateway-virtualservice.yaml
https://github.com/salesforce/helm-starter-istio/blob/master/templates/virtualService.yaml
how would thousands of VSs impact the performance of request processing?
There is github issue about that, as #lanceliuu mentioned there
When we create ~1k virtualservices in a single cluster, the ingress gateway is picking up new virtualservice slowly.
So that might be one of the issues with thousands of Virtual Services.
Is It expensive to keep them in terms of CPU and RAM being consumed?
I would say it would require testing. I checked in above github issue and they mentioned that there is no mem/cpu pressure for istio components, but I can't say how expensive is that.
In theory you could create 1 big virtual service instead of thousands, but as mentioned in documentation you should rather Split large virtual services into multiple resources.
Additional resources:
https://engineering.hellofresh.com/everything-we-learned-running-istio-in-production-part-2-ff4c26844bfb
https://istio.io/latest/docs/ops/deployment/performance-and-scalability/
https://perf.dashboard.istio.io/

Service Mesh: Using Istio to route TCP traffic based on Client IP in Virtual Service

Ingress gateway is located behind AWS ELB(classic) using nodeport and I want to route TCP traffic in Virtual Service based on client ip.
Of course Proxy Protocol of ELB is enabled.
When I use HTTP, it works. The configuration is below.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: app-vservice
namespace: test
spec:
hosts:
- "app-service"
http:
- match:
- headers:
x-forwarded-for:
exact: 123.123.123.123
route:
- destination:
host: app-service
subset: v2
- route:
- destination:
host: app-service
subset: v1
But I can't find headers field of TCP route in official documents.
Is it impossible?
Thank you.
According to docs yes there is no field to pass headers in TCPRoute in Istio. Also to answer your question every header manipulation should be done using envoy filters because Istio, built on envoy supports that and also decreases the complexity.
Using envoy and lua filters as stated in Istio docs. It can be achieved. Please follow envoy docs.
Checkout the Istio Discussion for headers in Virtual Service.
For implementation of the same using Lua. And a blog showing an example how to implement filters on envoy.