Kubernetes Ingress and Istio Gateway Resource
By default, any service running inside the service mesh is not automatically exposed outside of the cluster which means that we can't get to it from the public Internet. Similarly, services within the mesh don't have access to anything running outside of the cluster either.
istio-ingressgateway
Kubernetes Service that is of type LoadBalancer and, with the corresponding Istio Gateway resource, can be used to allow traffic to the cluster.kubectl get svc istio-ingressgateway -n istio-system
, you will get an output similar to this one:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) ....
istio-ingressgateway LoadBalancer 10.107.249.46 <pending> ...
LoadBalancer
. If you're using a Minikube cluster you will notice how the external IP column shows text <pending>
— that is because we don't actually have a real external load balancer as everything runs locally. With a cluster running in the cloud from any cloud provider, we would see a real IP address there — that IP address is where the incoming traffic enters the cluster.If using Minikube
GATEWAY
environment variable we will be using to access the services.export INGRESS_HOST=$(minikube ip)
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==”http2")].nodePort}')
export GATEWAY=$INGRESS_HOST:$INGRESS_PORT
echo $GATEWAY
you should get an IP address with a port, such as: 192.168.99.100:31380
.If using Minikube (v0.32.0 or higher)
v0.32.0
and higher, has a command called minikube tunnel
. This command creates networking routes from your machine into the Kubernetes cluster as well as allocates IPs to services marked with LoadBalancer
. What this means is that you can access your exposed service using an external IP address, just like you would when you're running Kubernetes in the cloud.minikube tunnel
and you should see an output similar to this one:$ minikube tunnel
Status:
machine: minikube
pid: 43606
route: 10.96.0.0/12 -> 192.168.99.104
minikube: Running
services: [istio-ingressgateway]
errors:
minikube: no errors
router: no errors
loadbalancer emulator: no errors
kubectl get svc istio-ingressgateway -n istio-system
command to get the ingress gateway service, you will notice an actual IP address in the EXTERNAL-IP
column. It should look something like this:$ kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
istio-ingressgateway LoadBalancer 10.107.235.182 10.107.235.182 ...
10.107.235.182
above) as the public entry point to your cluster. Run the command below to set the external IP value to the GATEWAY
variable:export GATEWAY=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
If using Docker for Mac/Windows
localhost:80
:export GATEWAY=localhost
If using hosted Kubernetes
kubectl get svc istio-ingressgateway -n istio-system
command and use the external IP value.GATEWAY
environment variable in all examples when accessing the services.Gateways
GATEWAY
we could try and access it. Unfortunately, we get back something like this:$ curl $GATEWAY
curl: (7) Failed to connect to 192.168.99.100 port 31380: Connection refused
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- '*'
kubectl get pod — selector="istio=ingressgateway" — all-namespaces
to get all the pods with that label. The command will return you the Istio ingress gateway pod that's running in the istio-system namespace. This ingress gateway pod will then, in turn, proxy traffic further to different Kubernetes services.servers
we define which hosts will this gateway proxy — we are using *
which means we want to proxy all requests, regardless of the host name.Note
In the real world, the host would be set to the actual domain name (e.g. www.example.com) where cluster services will be accessible from. The*
should be only used for testing and in local scenarios and not in production.
cat <<EOF | kubectl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- '*'
EOF
$ curl -v $GATEWAY
* Rebuilt URL to: 192.168.99.100:31380/
* Trying 192.168.99.100…
* TCP_NODELAY set
* Connected to 192.168.99.100 (192.168.99.100) port 31380 (#0)
> GET / HTTP/1.1
> Host: 192.168.99.100:31380
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< location: http://192.168.99.100:31380/
< date: Tue, 18 Dec 2018 00:05:17 GMT
< server: envoy
< content-length: 0
<
* Connection #0 to host 192.168.99.100 left intact
VirtualService
— comes into play.