Exposing TCP and UDP based services in Istio - The Easy Way
Istio is pretty cool guys. It's manageable and super easy to use. One thing I come across to find out about Istio when considering exposing TCP and UDP services is that it opens ports 80 (HTTP), 443(HTTPS), and 15021 (health check) for the ingress gateway as default ones. Apart from that, it should be on us to configure when exposing other TCP or UDP ports when it's necessary. That being said, it's pretty similar when configuring to expose those new ports with an NGINX Ingress Controller (Check this blog).
When we install or run the Istio service mesh in Kubernetes, we have objects created by default. In our case, we want to focus on this Service Object named istio-ingressgateway.
Let us see what shall we find when sending a get API query for the svc in our namespace called istio-system.
kubectl get svc -n istio-system # This will give us list of service objects in our istio-system namespace NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-egressgateway ClusterIP 10.0.254.114 <none> 80/TCP,443/TCP 1d istio-ingressgateway LoadBalancer 10.0.58.73 x.x.x.x 15021:30890/TCP,80:30850/TCP,443:30560/TCP 1d istiod ClusterIP 10.0.129.213 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 1d
You can see that our istio-ingressgateway has ports 80, 443 & 15021 opened. Let us modify that svc and manage to add other TCP or UDP-based ports. As for this example, I'll go ahead and add port 6379 for the default Redis port.
KUBE_EDITOR="nano" kubectl edit svc -n istio-system istio-ingressgateway
# Add this for within the ports section of the svc. ... - name: redis port: 6379 protocol: TCP #can be also UDP for udp service targetPort: 6379 ...
Once saved we can go ahead and see if it has mapped a port to it, like so:
$ kubectl get svc -n istio-system istio-ingressgateway # Will give us NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.0.58.73 x.x.x.x 15021:30890/TCP,80:30850/TCP,443:30560/TCP,6379:30446/TCP 1d
You can see that it has opened port 6379(TCP) and started to listen.
After we configured our ingress svc object for our Istio, we should modify our gateway(load balancer) object to also handle incoming traffic for our protocol (TCP/UDP):
KUBE_EDITOR="nano" kubectl edit gateway -n istio-system myGateway # add this config to the section of 'servers' in the yaml. .... - hosts: - redis.yourdomain.com port: name: redis-port number: 6379 protocol: TCP ....
Finally, we shall configure our virtualservice object of Istio.
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: redis namespace: istio-system spec: gateways: - myGateway hosts: - redis.yourdomain.com tcp: - match: - port: 6379 route: - destination: host: your-service-object-in-the-cluster port: number: 6379