I deployed Istion on my local Kubernetes cluster running in my Mac. I created this VirtualService, DestinationRule and Gateway.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: code-gateway
namespace: code
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "gateway.code"
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: codemaster
namespace: code
spec:
hosts:
- master.code
- codemaster
gateways:
- codemaster-gateway
- code-gateway
http:
- route:
- destination:
host: codemaster
subset: v1
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: codemaster-gateway
namespace: code
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "master.code"
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: codemaster
namespace: code
spec:
host: codemaster
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- apiVersion: "v1"
kind: "Service"
metadata:
labels:
app: "codemaster"
group: "code"
name: "codemaster"
namespace: "code"
spec:
ports:
- name: http-web
port: 80
targetPort: 80
selector:
app: "codemaster"
group: "code"
type: "ClusterIP"
- apiVersion: "apps/v1"
kind: "Deployment"
metadata:
labels:
app: "codemaster"
group: "code"
env: "production"
name: "codemaster"
namespace: "code"
spec:
replicas: 2
selector:
matchLabels:
app: "codemaster"
group: "code"
template:
metadata:
labels:
app: "codemaster"
version: "v1"
group: "code"
env: "production"
spec:
containers:
- env:
- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: "metadata.namespace"
- name: "SPRING_DATASOURCE_URL"
value: "jdbc:postgresql://host.docker.internal:5432/code_master"
- name: "SPRING_DATASOURCE_USERNAME"
value: "postgres"
- name: "SPRING_DATASOURCE_PASSWORD"
value: "postgres"
image: "kzone/code/codemaster:1.0.0"
imagePullPolicy: "IfNotPresent"
name: "codemaster"
ports:
- containerPort: 80
name: "http"
protocol: "TCP"
apiVersion: "v1"
kind: "List"
items:
- apiVersion: "apps/v1"
kind: "Deployment"
metadata:
labels:
app: "codemaster"
group: "code"
env: "canary"
name: "codemaster-canary"
namespace: "code"
spec:
replicas: 1
selector:
matchLabels:
app: "codemaster"
group: "code"
template:
metadata:
labels:
app: "codemaster"
version: "v2"
group: "code"
env: "canary"
spec:
containers:
- env:
- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: "metadata.namespace"
- name: "SPRING_DATASOURCE_URL"
value: "jdbc:postgresql://host.docker.internal:5432/code_master"
- name: "SPRING_DATASOURCE_USERNAME"
value: "postgres"
- name: "SPRING_DATASOURCE_PASSWORD"
value: "postgres"
image: "kzone/code/codemaster:1.0.1"
imagePullPolicy: "IfNotPresent"
name: "codemaster"
ports:
- containerPort: 80
name: "http"
protocol: "TCP"
These are the services running in code namespace,
codemaster ClusterIP 10.103.151.80 <none> 80/TCP 18h
gateway ClusterIP 10.104.154.57 <none> 80/TCP 18h
I deployed 2 spring-boot microservices in ton k8s. One is a spring-boot gateway. These are the pods running in code namespace,
codemaster-6cb7b8ddf5-mlpzn 2/2 Running 0 7h3m
codemaster-6cb7b8ddf5-sgzt8 2/2 Running 0 7h3m
codemaster-canary-756697d9c8-22qb2 2/2 Running 0 7h3m
gateway-5b5c8697f4-jpb4q 2/2 Running 0 7h3m
When I send a request to http://master.code/version(the gateway created for codemaster service) it always goes to the correct subset. But when I send a request via spring-boot gateway (http://gateway.code/codemaster/version) request doesn't go to subset v1 only, requests go in round-robin to all the 3 pods. This is what I see in Kiali,
I want to apply traffic shifting between the gateway and other services.
Istio relies on the Host header of a request to apply the traffic rules. Since you are using spring boot gateway to make the request ribbon hits the pod IP directly instead of hitting the service. So to avoid it provide static server list to the
route /version as http://master.code.cluster.local
in your spring boot gateway config -> to avoid ribbon dynamic endpoint discovery. This should fix the problem.
After doing some search I found that there is no CNI in Docker for Mac k8s. Because of that traffic shifting doesn't not work on Docker for Mac K8s