oc new-project data-plane --display-name="Data Plane"
-
Deploy frontend and backend app
oc create -f app.yaml -n data-plane watch -d oc get pods -n data-plane
-
Test with cURL
curl $(oc get route frontend -n data-plane -o jsonpath='{.spec.host}')
Output
Frontend version: v1 => [Backend: http://backend:8080, Response: 200, Body: Backend version:v1, Response:200, Host:backend-v1-6b4dd76bbc-bd4jx, Status:200, Message: Hello, Quarkus]
-
Create control plane and join data plane to control plane
- Create namespace for control plane
oc new-project control-plane --display-name="Control Plane"
- Create control plane
oc create -f https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/smcp.yaml -n control-plane
- Wait couple of minutes for creating control plane
watch -d oc get smcp -n control-plane
- Join data-plane namespace into control-plane
oc create -f https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/member-roll.yaml -n control-plane
- Check Service Mesh Member Roll status
oc describe smmr/default -n control-plane
- Create namespace for control plane
-
Inject sidecar to both frontend and backend
oc patch deployment/frontend-v1 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"true"}}}}}' -n data-plane oc patch deployment/backend-v1 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"true"}}}}}' -n data-plane
-
Check that sidecar is injected
oc get pods -n data-plane
-
Check network policy
oc get networkpolicy/istio-expose-route-basic-install -n data-plane -o yaml
-
Network policy istio-expose-route is automatically added to allow traffic of OpenShift's router pod to only pod with label maistra.io/expose-route: "true"
spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: matchLabels: maistra.io/expose-route: "true" policyTypes: - Ingress
-
Patch frontend with label
oc patch deployment/frontend-v1 -p '{"spec":{"template":{"metadata":{"labels":{"maistra.io/expose-route":"true"}}}}}' -n data-plane
-
Test
curl $(oc get route frontend -n data-plane -o jsonpath='{.spec.host}') # Sample output Frontend version: v1 => [Backend: http://backend:8080, Response: 200, Body: Backend version:v1, Response:200, Host:backend-v1-5c45fb5d76-gg8sc, Status:200, Message: Hello, Quarkus]
Remark: You need to replace SUBDOMAIN with your cluster subdomain in every yaml files
- Create gateway in control-plane
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}')
curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/wildcard-gateway.yaml | sed 's/SUBDOMAIN/'$SUBDOMAIN'/' | oc create -n control-plane -f -
- Create route in control-plane
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}')
curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/frontend-route-istio.yaml | sed 's/SUBDOMAIN/'$SUBDOMAIN'/' | oc create -n control-plane -f -
- Crate virtual service in data-plane
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}')
curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/frontend-virtual-service.yaml | sed 's/SUBDOMAIN/'$SUBDOMAIN'/' | oc create -n data-plane -f -
- Test gateway
curl $(oc get route/frontend -n control-plane -o jsonpath='{.spec.host}')
Deploy frontend v2 and configure canary deployment to route only request from Firefox to v2
- Deploy frontend-v2
oc create -f https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/frontend-v2-deployment.yaml -n data-plane
- Create destination rule with subgroup based on version
Create destination rule
subsets: - name: v1 labels: app: frontend version: v1 trafficPolicy: loadBalancer: simple: ROUND_ROBIN - name: v2 labels: app: frontend version: v2 trafficPolicy: loadBalancer: simple: ROUND_ROBIN
oc apply -f https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/frontend-destination-rule.yaml -n data-plane
- Update frontend virtual service with to routing by header
Create virtual service
http: - match: - headers: user-agent: regex: (.*)Firefox(.*) route: - destination: host: frontend port: number: 8080 subset: v2 - route: - destination: host: frontend port: number: 8080 subset: v1
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}') curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/frontend-virtual-service-canary.yaml |sed 's/SUBDOMAIN/'$SUBDOMAIN'/'|oc apply -n data-plane -f -
- Test
- Set User-Agent to Firefox
Output
#Test with header User-Agent contains "Firefox" curl -H "User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Firefox/78.0" $(oc get route frontend -n control-plane -o jsonpath='{.spec.host}')
Frontend version: v2 => [Backend: http://backend:8080, Response: 200, Body: Backend version:v1, Response:200, Host:backend-v1-5c45fb5d76-gg8sc, Status:200, Message: Hello, Quarkus]
- Set User-Agent to Chrome
Output
curl -H "User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71" $(oc get route frontend -n control-plane -o jsonpath='{.spec.host}')
Frontend version: v1 => [Backend: http://backend:8080, Response: 200, Body: Backend version:v1, Response:200, Host:backend-v1-5c45fb5d76-gg8sc, Status:200, Message: Hello, Quarkus]
- Set User-Agent to Firefox
- Create cretificate and secret key using create-certificate.sh
curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/create-certificate.sh | bash /dev/stdin
- Create secrets
oc create secret generic frontend-credential \ --from-file=tls.key=certs/frontend.key \ --from-file=tls.crt=certs/frontend.crt \ -n control-plane
- Update gateway with simple mode TLS
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}') curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/wildcard-gateway-tls.yaml|sed 's/SUBDOMAIN/'$SUBDOMAIN'/' | oc apply -n control-plane -f -
- Update frontend router to passthrough mode
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}') curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/frontend-route-istio-passthrough.yaml |sed 's/SUBDOMAIN/'$SUBDOMAIN'/' | oc apply -n control-plane -f -
- Test
curl -vk https://$(oc get route frontend -n control-plane -o jsonpath='{.spec.host}')
- Example of Service Mesh Control Plane
- Create secret
oc create secret tls istio-ingressgateway-certs \
--cert certs/tls.crt --key certs/tls.key -n control-plane
- Restart ingress gateway
oc patch deployment istio-ingressgateway \
-p '{"spec":{"template":{"metadata":{"annotations":{"kubectl.kubernetes.io/restartedAt": "'`date +%FT%T%z`'"}}}}}' -n control-plane
- Update gateway with simple mode TLS
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}') curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/wildcard-gateway-tls-v1.yaml | sed 's/SUBDOMAIN/'$SUBDOMAIN'/' | oc apply -n control-plane -f -
- Update frontend router to passthrough mode
SUBDOMAIN=$(oc whoami --show-console | awk -F'apps.' '{print $2}') curl -s https://raw.githubusercontent.com/voraviz/openshift-service-mesh-istio-gateway/main/frontend-route-istio-passthrough.yaml | sed 's/SUBDOMAIN/'$SUBDOMAIN'/' | oc apply -n control-plane -f -
- Test
curl -vk https://$(oc get route frontend -n control-plane -o jsonpath='{.spec.host}')
- Verify certificate in ingress gateway pod
oc exec $(oc get pods --no-headers -l istio=ingressgateway | head -n 1 | awk '{print $1}') -- cat /etc/istio/ingressgateway-certs/tls.crt