I'm looking at using canary deployments in Istio but it seems it randomly distributes requests to new and old versions based on a weighting. This implies a user in the business could see one behaviour one minute and different behaviour the next minute & people within teams could experience different behaviour to each other. For this reason it seems if I want consistent behaviour for a user or team I need to build my own roll-out mechanism where I can control who moves on to the new service version.
Am I correct or am I misunderstanding how Istio canary rollout works?
If you do a basic traffic distribution by weight, you are correct.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- helloworld
http:
- route:
- destination:
host: helloworld
subset: v1
weight: 90
- destination:
host: helloworld
subset: v2
weight: 10
Here 10 % of the traffic is routed to v2 randomly. Any request might call a different version.
But you can do more sophisticated routing.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- helloworld
http:
- match:
- headers:
group:
exact: testing
route:
- destination:
host: helloworld
subset: v2
- route:
- destination:
host: helloworld
subset: v1
Now there are two routes:
The users with a header group=testing will be send to v2
All other users will be send to v1
The header in this example could be set in the frontend based on the user, so backend requests for that user will call v2.
Or you could set a cookie for a specific group and route them to a different frontend by using something like:
- match:
- headers:
cookie:
[...]
There are multiple match criteria, including headers, queryParams and authority.
Related
I have two backend services(X backend service and Y backend service) for which I have configured a load balancer and created some routing rules as can be seen in the photo.
My goal:
Access dev.somedomain.io -> redirects to X backend service
Access dev.somedomain.io/shopify -> redirects to Y backend service
Access dev.somedomain.io/api -> redirects to X backend service
Actual result:
When I try to load: dev.somedomain.io everything seems to work fine and I get can see
swagger as in dev.somedomain.io/swagger/index.html.
When I try to load: dev.somedomain.io/api I get a 404 and nothing loads.
When I try to load: dev.somedomain.io/shopify I get a 404 and nothing loads.
From what I can see only the last route seems to get matched (the one with /* as a path).
Not sure what am I missing here.
So it turns out I needed to specify the action and url rewrite for the above routes to work. But since there is no option to specify those from the UI I needed to select the advanced route configuration and need to provide it as YAML as the following:
defaultService: projects/some-project/global/backendServices/x-api-dev-backend-service
name: path-matcher-1
pathRules:
- paths:
- /shopify/*
service: projects/some-project/global/backendServices/y-dev-backend-service
routeAction:
urlRewrite:
pathPrefixRewrite: /
- paths:
- /api/*
service: projects/some-project/global/backendServices/x-dev-backend-service
routeAction:
urlRewrite:
pathPrefixRewrite: /
According to their documentation of TLSRoute it does not include rewrite that you typically do for HTTPRoute`
Is it possible to do the same for HTTPS or TLS ?
http:
- match:
- uri:
prefix: /ratings
rewrite:
uri: /v1/bookRatings
route:
- destination:
host: ratings.prod.svc.cluster.local
When TLS traffic is not terminated, traffic (including the URL parts needed for rewrite) is encrypted and therefore Istio can't read or manipulate it. Therefore, these options are not available.
The below configuration works as expected
- id: test-service
uri: http://localhost:8080/
predicates:
- Path=/ap1/test/**,/api2/test/**,/api3/test/**
I am trying to use the OR condition(as shown below) for the above paths. Is there a way we can achieve it using regex and not code/redirect
- Path=/(api1|api2|api3)/test/**
Found this documentation, https://istio.io/latest/docs/tasks/security/authentication/authn-policy/#end-user-authentication, which discusses how to do JWT token validation at the gateway, and I have a fee questions regaring this:
Is there a way to specify the jwt_uri with like a templated value, where the value gets filled in by the value of a header that you specify or other information in the request? If so can you point me to any examples? The use case here is that we have multiple tenants, and we need to validate the token in a request for a given tenant against the keys for that respective tenant, which is retreived from jwt_uri path that includes tenant (realm) in uri path.
Can we specify a different jwt_uri per path? If so can you point me to any examples?
Are the keys retrieves from the jwt_uri cached? If so how do we control the caching?
Is there a way to specify the jwt_uri with like a templated value, where the value gets filled in by the value of a header that you specify or other information in the request?
I checked in the istio in action book and seems like it's possible. Take a look at below example.
apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
name: "jwt-token-request-authn"
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
jwtRules:
- issuer: "auth#istioinaction.io"
jwks: |
{ "keys": [{"e":"AQAB","kid":"##REDACTED##","kty":"RSA","n":"##REDACTED##"}]}
As I mentioned in comments there is istio documentation about jwt.
Can we specify a different jwt_uri per path? If so can you point me to any examples?
I checked in older documentation and it was possible to do with Policy, I checked here and now it should be possible to achieve with AuthorizationPolicy and RequestPolicy.
Take a look at below documentation links:
https://istio.io/latest/docs/reference/config/security/request_authentication/
https://istio.io/latest/docs/reference/config/security/authorization-policy/
https://istio.io/latest/docs/reference/config/security/conditions/
Are the keys retrieves from the jwt_uri cached? If so how do we control the caching?
Quoted from envoy documentation
cache_duration
(Duration) Duration after which the cached JWKS should be expired. If not specified, default cache duration is 5 minutes.
I'm not sure if it can be set up in istio, there is github issue about that, there is no answer so far.
I'm pretty excited about HTTP Gateways due to the drastically reduced pricing in comparison to REST Gateways, but I'm stuck on creating routes that do not completely blow up my serverless.yml file.
The documentation for HTTP Gateway at Serverless describes this to define routes:
functions:
params:
handler: handler.params
events:
- httpApi:
method: GET
path: /get/for/any/{param}
There is a support for '*', but this causes issues with OPTIONS cause those will overwrite the created CORS policies (so OPTIONS requests would actually get to the application, which does not make any sense, especially if the route is protected via an authorizer).
Also, it's not possible to define multiple methods.
# does not work
method: GET,POST,DELETE
# also not possible
method:
- GET
- POST
- DELETE
The only configuration I found is to define all routes separately:
events:
- httpApi:
path: /someApi/{proxy+}
method: GET
- httpApi:
path: /someApi/{proxy+}
method: POST
- httpApi:
path: /someApi/{proxy+}
method: DELETE
This works fine & the UI is even bundling the routes cause they're on the same prefixed path:
But with this I have to define all HTTP methods for all my main resources separately including the attached authorizer.
Is there some way to combine this?