You can use Istio to enable service mesh features such as traffic management, observability, and security. Istio can be provisioned using Cloud Service Mesh (CSM), the Open Source Software (OSS) istioctl tool, or via other Istio providers. You can then label individual namespaces for sidecar injection and configure an Istio gateway to replace the frontend-external load balancer.
The following CLI tools needs to be installed and in the PATH:
gcloud
kubectl
kustomize
istioctl
(optional)
-
Set-up some default environment variables.
PROJECT_ID="<your-project-id>" REGION="<your-google-cloud-region" CLUSTER_NAME="online-boutique" gcloud config set project $PROJECT_ID
-
Create an Autopilot GKE cluster.
gcloud container clusters create-auto $CLUSTER_NAME \ --location=$REGION
To make the best use of our service mesh, we need to have GKE Workload Identity, and the Kubernetes Gateway API resource definitions enabled. Autopilot takes care of this for us.
-
Change our kubectl context for the newly created cluster.
gcloud container clusters get-credentials $CLUSTER_NAME \ --region $REGION
Cloud Service Mesh (CSM) provides a service mesh experience that includes a fully managed control plane and data plane. The recommended way to install CSM uses fleet management.
-
Enable the Cloud Service Mesh and GKE Enterprise APIs.
gcloud services enable mesh.googleapis.com anthos.googleapis.com
-
Enable service mesh support fleet-wide.
gcloud container fleet mesh enable
-
Register the GKE cluster to the fleet.
gcloud container clusters update $CLUSTER_NAME \ --location $REGION \ --fleet-project $PROJECT_ID
-
Enable automatic management of the service mesh feature in the cluster.
gcloud container fleet mesh update \ --management automatic \ --memberships $CLUSTER_NAME \ --project $PROJECT_ID \ --location $REGION
-
Add the Istio injection labels to the default namespace.
kubectl label namespace default \ istio.io/rev- istio-injection=enabled --overwrite
-
Verify that the service mesh is fully provisioned. It will take several minutes for both the control plane and data plane to be ready.
gcloud container fleet mesh describe
The output should be similar to:
createTime: '2024-09-18T15:52:36.133664725Z' fleetDefaultMemberConfig: mesh: management: MANAGEMENT_AUTOMATIC membershipSpecs: projects/12345/locations/us-central1/memberships/online-boutique: mesh: management: MANAGEMENT_AUTOMATIC origin: type: USER membershipStates: projects/12345/locations/us-central1/memberships/online-boutique: servicemesh: conditions: - code: VPCSC_GA_SUPPORTED details: This control plane supports VPC-SC GA. documentationLink: http://cloud.google.com/service-mesh/docs/managed/vpc-sc severity: INFO controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed' implementation: TRAFFIC_DIRECTOR state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: 'Revision ready for use: asm-managed.' updateTime: '2024-09-18T16:30:37.632583401Z' name: projects/my-project/locations/global/features/servicemesh resourceState: state: ACTIVE spec: {} updateTime: '2024-09-18T16:15:05.957266437Z'
-
(Optional) If you require Certificate Authority Service, you can configure it by following these instructions.
-
Alternatively you can install the open source version of Istio by following the getting started guide.
# Install istio 1.17 or above istioctl install --set profile=minimal -y # Enable sidecar injection for Kubernetes namespace(s) where microservices-demo is deployed kubectl label namespace default istio-injection=enabled # Make sure the istiod injection webhook port 15017 is accessible via GKE master nodes # Otherwise your replicaset-controller may be blocked when trying to create new pods with: # Error creating: Internal error occurred: failed calling # webhook "namespace.sidecar-injector.istio.io" ... context deadline exceeded gcloud compute firewall-rules list --filter="name~gke-[0-9a-z-]*-master" NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED gke-online-boutique-c94d71e8-master gke-vpc INGRESS 1000 tcp:10250,tcp:443 False # Update firewall rule (or create a new one) to allow webhook port 15017 gcloud compute firewall-rules update gke-online-boutique-c94d71e8-master \ --allow tcp:10250,tcp:443,tcp:15017
Once the service mesh and namespace injection are configured, you can then deploy the Istio manifests using Kustomize. You should also include the service-accounts component if you plan on using AuthorizationPolicies.
-
Enable the service-mesh-istio component.
cd kustomize/ kustomize edit add component components/service-mesh-istio
This will update the
kustomize/kustomization.yaml
file which could be similar to:apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - base components: - components/service-mesh-istio
Note:
service-mesh-istio
component includes the same delete patch as thenon-public-frontend
component. Trying to use both those components in your kustomization.yaml file will result in an error. -
Deploy the manifests.
kubectl apply -k
The output should be similar to:
serviceaccount/adservice created serviceaccount/cartservice created serviceaccount/checkoutservice created serviceaccount/currencyservice created serviceaccount/emailservice created serviceaccount/frontend created serviceaccount/loadgenerator created serviceaccount/paymentservice created serviceaccount/productcatalogservice created serviceaccount/recommendationservice created serviceaccount/shippingservice created service/adservice created service/cartservice created service/checkoutservice created service/currencyservice created service/emailservice created service/frontend created service/paymentservice created service/productcatalogservice created service/recommendationservice created service/redis-cart created service/shippingservice created deployment.apps/adservice created deployment.apps/cartservice created deployment.apps/checkoutservice created deployment.apps/currencyservice created deployment.apps/emailservice created deployment.apps/frontend created deployment.apps/loadgenerator created deployment.apps/paymentservice created deployment.apps/productcatalogservice created deployment.apps/recommendationservice created deployment.apps/redis-cart created deployment.apps/shippingservice created gateway.gateway.networking.k8s.io/istio-gateway created httproute.gateway.networking.k8s.io/frontend-route created serviceentry.networking.istio.io/allow-egress-google-metadata created serviceentry.networking.istio.io/allow-egress-googleapis created virtualservice.networking.istio.io/frontend created
-
Check that the pods and the gateway are in a healthy and ready state.
kubectl get pods,gateways,services
The output should be similar to:
NAME READY STATUS RESTARTS AGE pod/adservice-6cbd9794f9-8c4gv 2/2 Running 0 47s pod/cartservice-667bbd5f6-84j8v 2/2 Running 0 47s pod/checkoutservice-547557f445-bw46n 2/2 Running 0 47s pod/currencyservice-6bd8885d9c-2cszv 2/2 Running 0 47s pod/emailservice-64997dcf97-8fpsd 2/2 Running 0 47s pod/frontend-c54778dcf-wbgmr 2/2 Running 0 46s pod/istio-gateway-istio-8577b948c6-cxl8j 1/1 Running 0 45s pod/loadgenerator-ccfd4d598-jh6xj 2/2 Running 0 46s pod/paymentservice-79b77cd7c-6hth7 2/2 Running 0 46s pod/productcatalogservice-5f75795545-nk5wv 2/2 Running 0 46s pod/recommendationservice-56dd4c7df5-gnwwr 2/2 Running 0 46s pod/redis-cart-799c85c644-pxsvt 2/2 Running 0 46s pod/shippingservice-64f8df74f5-7wllf 2/2 Running 0 45s NAME CLASS ADDRESS READY AGE gateway.gateway.networking.k8s.io/istio-gateway istio 35.247.123.146 True 45s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/adservice ClusterIP 10.68.231.142 <none> 9555/TCP 49s service/cartservice ClusterIP 10.68.184.25 <none> 7070/TCP 49s service/checkoutservice ClusterIP 10.68.177.213 <none> 5050/TCP 49s service/currencyservice ClusterIP 10.68.249.87 <none> 7000/TCP 49s service/emailservice ClusterIP 10.68.205.123 <none> 5000/TCP 49s service/frontend ClusterIP 10.68.94.203 <none> 80/TCP 48s service/istio-gateway-istio LoadBalancer 10.68.147.158 35.247.123.146 15021:30376/TCP,80:30332/TCP 45s service/kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 65m service/paymentservice ClusterIP 10.68.114.19 <none> 50051/TCP 48s service/productcatalogservice ClusterIP 10.68.240.153 <none> 3550/TCP 48s service/recommendationservice ClusterIP 10.68.117.97 <none> 8080/TCP 48s service/redis-cart ClusterIP 10.68.189.126 <none> 6379/TCP 48s service/shippingservice ClusterIP 10.68.221.62 <none> 50051/TCP 48s
-
Find the external IP address of your Istio gateway.
INGRESS_HOST="$(kubectl get gateway istio-gateway \ -o jsonpath='{.status.addresses[*].value}')"
-
Navigate to the frontend in a web browser.
http://$INGRESS_HOST