This blog entry is meant to host random discoveries noted during my work with Istio in general. The notes are expectingly blunt & without contexts (apologies).
Istio Gateway
Once istio is installed, it will expose several ports through NodePort. To see which istio-controller port is mapped to which port on the node(s), use the following command:
kubectl get svc istio-ingressgateway -n istio-system
The mapped PORTS are available in the output, for example:
15021:31445/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15443:31392/TCP
If we request at <nodeIP>:31380
now, the request is refused. It’s because there is no Gateway resource to declare the use of port 80 (which is mapped to 31380 as seen from the example output above)
To start using the mapping, we can deploy the following example Gateway resource:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: foo-gateway
namespace: foo
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
Istio VirtualService
Declaring the use of the mapping is one thing. Declaring the service behind the istio-controller port is another thing. At this point, requests coming to the node’s port get routed to the port 80 within istio realm, but there’s nothing listening there yet. This is where istio VirtualService comes in. We can declare something like this:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: foo-vs
namespace: foo
spec:
gateways:
- foo-gateway
hosts:
- '*'
http:
- match:
- uri:
prefix: /
route:
- destination:
host: foo-app # the actual destination service
port:
number: 80 # the actual destination service's listening port
Now if there’s a real service accessible at foo-app.<ns>.svc.cluster.local
, it’ll serve the request coming into <nodeIP>:31380. Note that the hosts
are declared as wildcard for both the Gateway and VirtualService resources in the examples above. Feel free to experiment & fine-tune them to your likings in your own setups.
k8s Istio Gateway TLS Termination (i.e. tls.mode = SIMPLE)
From the example above, you may notice TLS traffic is also supported. In simple terms: HTTPS requests coming in can be decrypted & terminated at Istio Gateway, then the traffic goes to the VirtualService
behind can just be plain HTTP.
While we can provide direct paths to the cert & key files, if Istio is installed in k8s environment, this may be inconvenient. A more “k8s-native” approach would be k8s Secret, which is supported via the tls.credentialName
setting. Configuring this is a simple 2-step process:
Step 1: from your local (or any workstation), generate the k8s secret from the certificate file & key:
kubectl create -n istio-system secret tls <secret-name> --key=/path/to/key/file --cert=/path/to/cert/file
Step 2: configure Istio Gateway to use the correct tls mode & certificate info:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
# ...
spec:
# ...
servers:
- hosts:
- '*'
port:
name: https
number: 443
protocol: HTTPS
tls:
credentialName: <secret-name>
mode: SIMPLE
NB: this is not the only possible setup, but it’s a typical example of how we can configure Istio for this purpose.
TBC