In this project, let's say I set the value of hosts to hello
:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: hello-k8s
spec:
hosts:
- ???
http:
- name: hello-k8s
match:
- uri:
prefix: /
route:
- destination:
host: hello # <--------------
port:
number: 8080
After deploying the project to my local minikube:
hello.local
?$ curl what.should.be.here:8080
kubectl
and introspection?Update 1:
I changed the host to hello.local
.
Then I verified that istio
is enabled in minikube
:
➜ minikube addons list
|-----------------------------|----------|--------------|
| ADDON NAME | PROFILE | STATUS |
|-----------------------------|----------|--------------|
| ambassador | minikube | disabled |
| csi-hostpath-driver | minikube | disabled |
| dashboard | minikube | disabled |
| default-storageclass | minikube | enabled ✓ |
| efk | minikube | disabled |
| freshpod | minikube | disabled |
| gcp-auth | minikube | disabled |
| gvisor | minikube | disabled |
| helm-tiller | minikube | disabled |
| ingress | minikube | disabled |
| ingress-dns | minikube | disabled |
| istio | minikube | enabled ✓ |
| istio-provisioner | minikube | enabled ✓ |
| kubevirt | minikube | disabled |
| logviewer | minikube | disabled |
| metallb | minikube | disabled |
| metrics-server | minikube | disabled |
| nvidia-driver-installer | minikube | disabled |
| nvidia-gpu-device-plugin | minikube | disabled |
| olm | minikube | disabled |
| pod-security-policy | minikube | disabled |
| registry | minikube | disabled |
| registry-aliases | minikube | disabled |
| registry-creds | minikube | disabled |
| storage-provisioner | minikube | enabled ✓ |
| storage-provisioner-gluster | minikube | disabled |
| volumesnapshots | minikube | disabled |
|-----------------------------|----------|--------------|
I deployed the app and verified everything is working:
➜ kubectl apply -k base/
service/hello-k8s unchanged
deployment.apps/hello-k8s unchanged
virtualservice.networking.istio.io/hello-k8s configured
➜ kubectl get deployments/hello-k8s
NAME READY UP-TO-DATE AVAILABLE AGE
hello-k8s 1/1 1 1 20h
➜ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-k8s-6d9cc7d655-plzs8 1/1 Running 0 20h
➜ kubectl get service/hello-k8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-k8s ClusterIP 10.98.144.226 <none> 8080/TCP 21h
➜ kubectl get virtualservice/hello-k8s
NAME GATEWAYS HOSTS AGE
hello-k8s ["hello.local"] 20h
➜ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istio-ingressgateway-8577c95547-6c9sk 1/1 Running 0 21h
istiod-6ccd677dc7-7cvr2 1/1 Running 0 21h
prometheus-7767dfd55-x2pv6 2/2 Running 0 21h
Not sure why I have to do this, but apparently it should be done:
➜ kubectl label namespace default istio-injection=enabled --overwrite
namespace/default labeled
➜ kubectl get namespace -L istio-injection
NAME STATUS AGE ISTIO-INJECTION
default Active 21h enabled
istio-operator Active 21h
istio-system Active 21h disabled
kube-node-lease Active 21h
kube-public Active 21h
kube-system Active 21h
playground Active 21h
I inspected the ip of minikube
and added an entry to /etc/hosts for hello.local
:
➜ minikube ip
192.168.49.2
➜ tail -n 3 /etc/hosts
# Minikube
192.168.49.2 hello.local
Then I queried the port of istio-ingressgateway
according to this blog post:
➜ kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
30616
Finally I sent a request to hello.local:30616
, but the requests are not arriving at my app:
➜ curl -iv hello.local:30616/hello
* Trying 192.168.49.2:30616...
* TCP_NODELAY set
* Connected to hello.local (192.168.49.2) port 30616 (#0)
> GET /hello HTTP/1.1
> Host: hello.local:30616
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
HTTP/1.1 404 Not Found
< date: Thu, 25 Feb 2021 14:51:18 GMT
date: Thu, 25 Feb 2021 14:51:18 GMT
< server: istio-envoy
server: istio-envoy
< content-length: 0
content-length: 0
<
* Connection #0 to host hello.local left intact
What domain name should I send my requests to? hello.local
?
The answer would be that you can use whatever the domain you want but you will be required to add this domain in /etc/hosts
. Then /etc/hosts
domain will be the ip address of the istio gateway loadbalancer.
Thanks to it you will be able to use that domain instead of the ingress gateway ip
Moving on there are couple of things about hosts/host in Virtual Service to consider:
If you set virtual service hosts
value to just hello
then as per documentation Istio will interpret the short name based on the namespace of the rule, not the service. A rule in the default
namespace with host hello
will be interpreted as hello.default.svc.cluster.local
.
You can also reference services along domains in hosts.
So to avoid potential misconfigurations, it is recommended to always use fully qualified domain names over short names.
Now coming next to destination.host
:
The name of a service from the service registry. Service names are looked up from the platform’s service registry (e.g., Kubernetes services, Consul services, etc.) and from the hosts declared by ServiceEntry. Traffic forwarded to destinations that are not found in either of the two, will be dropped.
Here's also a good exmpale how to configure metallb as loadbalancer and istio in minikube. Having metallb will give your service automatically configure as loadbalancer.
After further checking into your case I figure that problem might be related to your gateway not being used at all:
➜ kubectl get virtualservice/hello-k8s
NAME GATEWAYS HOSTS AGE
hello-k8s ["hello.local"] 20h ## Gateway describes a load balancer operating at the edge of the mesh receiving incoming or outgoing HTTP/TCP connections.
"Gateway describes a load balancer operating at the edge of the mesh receiving incoming or outgoing HTTP/TCP connections. Using Istio Gateway configuration you can bind VirtualService via virtualservice.spec.gateways with specific gateways (allowing external traffic or internal traffic inside istio service mesh) "The reserved word mesh is used to imply all the sidecars in the mesh. When this field is omitted, the default gateway (mesh) will be used" https://istio.io/latest/docs/reference/config/networking/virtual-service/#VirtualService
Make sure you configure Gateway
and VirtualService
:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
spec:
selector:
istio: ingressgateway ### this should be verified with istio ingress gateway pod labels
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*" ### for specific hosts it can be f.e. hello.local
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: hello-k8s
spec:
hosts:
- hello.local
gateways:
- my-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: hello-k8s.default.svc.cluster.local
port:
number: 8080