This example shows a meshed app with a single frontend and a pair of backends (blue and green). A VirtualService is created to split the frontend->backend traffic 50/50 between blue and green.
Create cluster.
kind create cluster --name servicemesh --image kindest/node:v1.26.3
Install istioctl
, run a precheck, install, then check status.
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 sh -
sudo mv istio-*/bin/istioctl /usr/local/bin
istioctl x precheck
istioctl install --set profile=default -y
istioctl proxy-status
Install apps into meshed namespace.
kubectl create namespace demos
kubectl label namespace/demos istio-injection=enabled
cat <<EOF | kubectl -n demos apply -f -
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
labels:
app: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: alpine
image: alpine
ports:
- containerPort: 80
command: ["/bin/sh"]
args: ["-c", "apk update && apk add curl && sleep infinity"]
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
type: ClusterIP
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-blue
labels:
app: backend-blue
spec:
replicas: 1
selector:
matchLabels:
app: backend-blue
template:
metadata:
labels:
app: backend-blue
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'v1' > /usr/share/nginx/html/index.html"]
---
apiVersion: v1
kind: Service
metadata:
name: backend-blue
spec:
type: ClusterIP
selector:
app: backend-blue
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-green
labels:
app: backend-green
spec:
replicas: 1
selector:
matchLabels:
app: backend-green
template:
metadata:
labels:
app: backend-green
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'v2' > /usr/share/nginx/html/index.html"]
---
apiVersion: v1
kind: Service
metadata:
name: backend-green
spec:
type: ClusterIP
selector:
app: backend-green
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
spec:
hosts:
- backend
http:
- route:
- destination:
host: backend-blue
weight: 50
- destination:
host: backend-green
weight: 50
---
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: ClusterIP
# NOTE no selector - the associated VirtualService fulfills this role dynamically
ports:
- name: http
port: 80
targetPort: 80
EOF
Exec onto frontend and curl backend repeatedly
kubectl -n demos exec -it deployments/frontend -- \
/bin/sh -c "while true; do curl backend.demos.svc.cluster.local; sleep 1; done"
Show the certificate chain for a pod.
istioctl proxy-config secret $(kubectl -n demos get pods -l app=backend-blue -o jsonpath='{.items[0].metadata.name}').demos
TODO maybe show Prometheus, Grafana, Kiali, Jaeger, etc.