Hi all,
I am currently trying to route traffic from a service running in Kubernetes to an external service represented by Wikipedia. The routing should be made based on some header value of wikipedia-country
and should route to the respective Wikipedia country host. Thereby, the K8s pod should always use wikipedia.org as its domain.
Some routing examples I imagined based on the docs (Istio / Virtual Service):
wikipedia-country: de → routes to de.wikipedia.org
instead of wikipedia.org
wikipedia-country: fr → routes to fr.wikipedia.org
instead of wikipedia.org
I tried to set this up using ServiceEntry and VirtualService as defined below:
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-wikipedia
namespace: service-mesh-demo
spec:
hosts:
- wikipedia.org
- "*.wikipedia.org"
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: TLS
- number: 80
name: http
protocol: HTTP
resolution: NONE
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: wikipedia
namespace: service-mesh-demo
spec:
hosts:
- wikipedia.org
http:
- match:
- headers:
wikipedia-country:
exact: de
route:
- destination:
host: de.wikipedia.org
- match:
- headers:
wikipedia-country:
exact: fr
route:
- destination:
host: fr.wikipedia.org
Unfortunately, the VirtualService does either not work (even if replacing the redirect with fault injection or timeouts) or result in 504 Gateway errors.
It would be awesome in case someone can point me in the right direction or could tell me if I am aiming for something impossible to do.
I also added the very simple express.js server running in OpenShift/ K8s:
Service source code executing the call
'use strict';
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
const express = require('express');
const axios = require('axios');
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
const WIKIPEDIA_HOST = process.env.WIKIPEDIA_HOST ? process.env.WIKIPEDIA_HOST : "https://wikipedia.org";
console.log("WIKIPEDIA_HOST: " + WIKIPEDIA_HOST);
// App
const app = express();
app.get('/wiki/search', (req, res) => {
console.log(`Received request with searchString ${req.query.searchString} for wikipedia-country ${req.headers["wikipedia-country"]}`)
var config = {
method: 'get',
url: WIKIPEDIA_HOST + "/w/api.php?action=query&origin=*&format=json&generator=search&gsrnamespace=0&gsrlimit=5&gsrsearch=" + req.query.searchString,
headers: propagateHeader(req)
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
res.send(response.data);
})
.catch(function (error) {
console.log(error);
});
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
function propagateHeader(req) {
return {
"wikipedia-country": req.headers["wikipedia-country"]
}
}