Create a GKE cluster with Cloud Service Mesh and the gcloud CLI
In this tutorial, you provision managed Cloud Service Mesh using the Google Kubernetes Engine (GKE) Fleet API on a new GKE public cluster. This tutorial walks you through:
- Configuring your Google Cloud project.
- Creating a GKE cluster with the minimum number of vCPUs required by Cloud Service Mesh.
- Registering the GKE cluster to your project's Fleet.
- Provisioning managed Cloud Service Mesh on the cluster using the Fleet API.
- Deploying an ingress gateway to expose the application.
- Deploying a sample application so that you can view telemetry data on the Cloud Service Mesh dashboards in the Google Cloud console.
- Exposing and accessing the sample application.
Fleet API
This guide assumes you are familiar with
Fleets, which are
logical groupings of GKE clusters and other resources that can be
managed together. A Fleet is a GKE concept — not a Kubernetes
concept. Registering a cluster to a Fleet allows you to provision managed
Cloud Service Mesh on that cluster using the
gcloud container fleet mesh update
command.
The use of Fleets is enabled by the Fleet API (gkehub.googleapis.com
) which
you enable when you begin this tutorial.
Costs
In this document, you use the following billable components of Google Cloud:
To generate a cost estimate based on your projected usage,
use the pricing calculator.
When you finish this quickstart, you can avoid continued billing by deleting the cluster. For more information, see Clean up.
Before you begin
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE, Fleet (GKE Hub), and Cloud Service Mesh APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE, Fleet (GKE Hub), and Cloud Service Mesh APIs.
- Make a note of your project ID.
Install required tools
You can run the tool on Cloud Shell or on your local machine. Cloud Shell pre-installs all the required tools.
Cloud Shell
Cloud Shell provisions a g1-small Compute Engine virtual machine (VM) running a Debian-based Linux operating system. The advantages to using Cloud Shell are:
Cloud Shell includes
gcloud
,kubectl
,git
, and the other command-line tools that you need.Your Cloud Shell $HOME directory has 5GB persistent storage space.
You have your choice of text editors:
Code editor, which you access by clicking edit at the top of the Cloud Shell window.
Emacs, Vim, or Nano, which you access from the command line in Cloud Shell.
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Local computer
Make sure you have the following tools installed:
Authenticate with the Google Cloud CLI:
gcloud auth login --project PROJECT_ID
Update the components:
gcloud components update
Create a GKE cluster
Run the following command to create the cluster with the minimum number of vCPUs required by Cloud Service Mesh. In the command, replace the placeholders with the following information:
- CLUSTER_NAME: the name of your cluster. The name can
contain only lowercase alphanumerics and
-
, must start with a letter and end with an alphanumeric, and must be no longer than 40 characters. - PROJECT_ID: the project ID that the cluster will be created in.
- CLUSTER_LOCATION: the
zone for the cluster, such as
us-central1-a
.
gcloud container clusters create CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION \ --machine-type=e2-standard-4 \ --num-nodes=2 \ --workload-pool=PROJECT_ID.svc.id.goog
It takes several minutes to create the cluster. While the cluster is being created, the
gcloud
command displays the following:Creating cluster CLUSTER_NAME in CLUSTER_LOCATION...working...
Expected output on successful creation is similar to the following:
Creating cluster CLUSTER_NAME in CLUSTER_LOCATION...done. Created [https://container.googleapis.com/v1/projects/PROJECT_ID/zones/CLUSTER_LOCATION/clusters/CLUSTER_NAME]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/CLUSTER_LOCATION/CLUSTER_NAME?project=PROJECT_ID kubeconfig entry generated for CLUSTER_NAME. NAME: CLUSTER_NAME LOCATION: CLUSTER_LOCATION MASTER_VERSION: 1.20.10-gke.1600 MASTER_IP: 198.51.100.1 MACHINE_TYPE: e2-standard-4 NODE_VERSION: 1.20.10-gke.1600 NUM_NODES: 2 STATUS: RUNNING
- CLUSTER_NAME: the name of your cluster. The name can
contain only lowercase alphanumerics and
Get authentication credentials to interact with the cluster.
gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
Expected output:
Fetching cluster endpoint and auth data. kubeconfig entry generated for CLUSTER_NAME.
Set the current context for
kubectl
to the cluster.kubectl config set-context CLUSTER_NAME
Expected output:
Context "CLUSTER_NAME" created.
Provision Cloud Service Mesh
If you haven't closed this page since you created the cluster, the placeholders
have the values that you entered for the gcloud container clusters create
command.
Enable Cloud Service Mesh on your project's Fleet.
gcloud container fleet mesh enable --project PROJECT_ID
The output is similar to:
Waiting for Feature Service Mesh to be created...done.
Register the cluster to the project's Fleet:
gcloud container fleet memberships register CLUSTER_NAME-membership \ --gke-cluster=CLUSTER_LOCATION/CLUSTER_NAME \ --enable-workload-identity \ --project PROJECT_ID
The output is similar to:
Waiting for membership to be created...done. Finished registering to the Fleet.
Provision managed Cloud Service Mesh on the cluster using the Fleet API:
gcloud container fleet mesh update \ --management automatic \ --memberships CLUSTER_NAME-membership \ --project PROJECT_ID
The output is similar to:
Waiting for Feature Service Mesh to be updated...done.
Verify that managed Cloud Service Mesh has been enabled for the cluster and is ready to be used:
gcloud container fleet mesh describe --project PROJECT_ID
It can take about 10 minutes for Cloud Service Mesh to provision and be ready to use on the cluster. If you see
controlPlaneManagement.state: DISABLED
orcontrolPlaneManagement.state: PROVISIONING
, you will need to re-run the previous command every few minutes until you seecontrolPlaneManagement.state: ACTIVE
.The output is similar to:
createTime: '2022-07-06T01:05:39.110120474Z' membershipSpecs: projects/123456789123/locations/global/memberships/your-cluster-membership: mesh: management: MANAGEMENT_AUTOMATIC membershipStates: projects/123456789123/locations/global/memberships/your-cluster-membership: servicemesh: controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed' state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: 'Revision(s) ready for use: asm-managed.' updateTime: '2022-07-06T01:19:24.243993678Z' name: projects/your-project-id/locations/global/features/servicemesh resourceState: state: ACTIVE spec: {} state: state: {} updateTime: '2022-07-06T01:19:27.475885687Z'
Download the sample code
Clone the git repository that contains the example code used in this tutorial:
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-packages.git
The next sections of this tutorial use a DIR_PATH variable.
Set this variable to the path of the anthos-service-mesh-packages
repository
that you cloned (for example, ./anthos-service-mesh-packages
).
Deploy an ingress gateway
Cloud Service Mesh gives you the option to deploy and manage gateways as part of your service mesh. A gateway describes a load balancer operating at the edge of the mesh receiving incoming or outgoing HTTP/TCP connections. Gateways are Envoy proxies that provide you with fine-grained control over traffic entering and leaving the mesh.
Create a namespace for the ingress gateway if you don't already have one. Gateways are user workloads, and as a best practice, they shouldn't be deployed in the control plane namespace. Replace
GATEWAY_NAMESPACE
with the name of your namespace.kubectl create namespace GATEWAY_NAMESPACE
Expected output:
namespace/GATEWAY_NAMESPACE created
Enable auto-injection on the gateway. The steps required depend on whether you want to use default injection labels (for example,
istio-injection=enabled
) or the revision label on the gateway namespace. The default revision tag and revision label are used by the sidecar injector webhook to associate injected proxies with a particular control plane revision.Default injection labels
Apply the default injection labels to the namespace.
kubectl label namespace GATEWAY_NAMESPACE istio-injection=enabled istio.io/rev-
Revision label
Use the following command to locate the revision label on
istiod
:kubectl get deploy -n istio-system -l app=istiod -o \ "jsonpath={.items[*].metadata.labels['istio\.io/rev']}{'\n'}"
The command outputs the revision label that corresponds to the Cloud Service Mesh version, for example:
asm-1187-26
Apply the revision label to the namespace. In the following command,
REVISION
is the value of theistiod
revision label that you noted in the previous step.kubectl label namespace GATEWAY_NAMESPACE \ istio.io/rev=REVISION --overwrite
Expected output:
namespace/GATEWAY_NAMESPACE labeled
You can ignore the message
"istio.io/rev" not found
in the output. That means that the namespace didn't previously have theistio.io/rev
label, which you should expect in new installations of Cloud Service Mesh or new deployments. Because auto-injection fails if a namespace has both theistio.io/rev
and theistio-injection
label, allkubectl label
commands in the Cloud Service Mesh documentation explicitly specify both labels.If the gateway namespace is not labelled, the
istio-ingressgateway
pods will fail with anImagePullBackOff
error when the gateway attempts to pull and theauto
image. This image should be replaced by the webhook.Download the example ingress gateway .yaml configuration file from the
anthos-service-mesh-packages
repository.Apply the example ingress gateway .yaml configuration as is, or modify as needed.
kubectl apply -n GATEWAY_NAMESPACE \ -f CONFIG_PATH/istio-ingressgateway
Expected output:
deployment.apps/istio-ingressgateway created poddisruptionbudget.policy/istio-ingressgateway created horizontalpodautoscaler.autoscaling/istio-ingressgateway created role.rbac.authorization.k8s.io/istio-ingressgateway created rolebinding.rbac.authorization.k8s.io/istio-ingressgateway created service/istio-ingressgateway created serviceaccount/istio-ingressgateway created
Learn more about best practices for gateways.
Deploy the Online Boutique sample
The Online Boutique sample application in the
anthos-service-mesh-packages
repo is modified from the original set of manifests in the
microservices-demo
repo. Following best practices, each service is deployed in a separate namespace
with a unique service account.
Create the namespaces for the application:
kubectl apply -f \ DIR_PATH/samples/online-boutique/kubernetes-manifests/namespaces
Expected output:
namespace/ad created namespace/cart created namespace/checkout created namespace/currency created namespace/email created namespace/frontend created namespace/loadgenerator created namespace/payment created namespace/product-catalog created namespace/recommendation created namespace/shipping created
Enable automatic sidecar injection (auto-injection). The command required depends on whether you want to use default injection labels (for example,
istio-injection=enabled
) or the same revision label that you used to annotate the ingress gateway namespaceDefault injection labels
Apply the default injection labels to the namespace. In the following command, GATEWAY_NAMESPACE is the same value that you used to annotate the ingress gateway namespace.
for ns in ad cart checkout currency email frontend loadgenerator payment product-catalog recommendation shipping; do kubectl label namespace $ns istio-injection=enabled istio.io/rev- done;
Expected output:
namespace/ad labeled namespace/cart labeled namespace/checkout labeled namespace/currency labeled namespace/email labeled namespace/frontend labeled namespace/loadgenerator labeled namespace/payment labeled namespace/product-catalog labeled namespace/recommendation labeled namespace/shipping labeled
Revision label
Apply the revision label to the application namespaces. In the following command, REVISION is the same value that you used to annotate the ingress gateway namespace.
for ns in ad cart checkout currency email frontend loadgenerator payment product-catalog recommendation shipping; do kubectl label namespace $ns istio.io/rev=REVISION --overwrite done;
Expected output:
namespace/ad labeled namespace/cart labeled namespace/checkout labeled namespace/currency labeled namespace/email labeled namespace/frontend labeled namespace/loadgenerator labeled namespace/payment labeled namespace/product-catalog labeled namespace/recommendation labeled namespace/shipping labeled
Deploy the sample application to the cluster.
Create the service accounts and deployments:
kubectl apply -f \ DIR_PATH/samples/online-boutique/kubernetes-manifests/deployments
Expected output:
serviceaccount/ad created deployment.apps/adservice created serviceaccount/cart created deployment.apps/cartservice created serviceaccount/checkout created deployment.apps/checkoutservice created serviceaccount/currency created deployment.apps/currencyservice created serviceaccount/email created deployment.apps/emailservice created serviceaccount/frontend created deployment.apps/frontend created serviceaccount/loadgenerator created deployment.apps/loadgenerator created serviceaccount/payment created deployment.apps/paymentservice created serviceaccount/product-catalog created deployment.apps/productcatalogservice created serviceaccount/recommendation created deployment.apps/recommendationservice created serviceaccount/shipping created deployment.apps/shippingservice created
Create the services:
kubectl apply -f \ DIR_PATH/samples/online-boutique/kubernetes-manifests/services
Expected output:
service/adservice created service/cartservice created service/checkoutservice created service/currencyservice created service/emailservice created service/frontend created service/frontend-external created service/paymentservice created service/productcatalogservice created service/recommendationservice created service/shippingservice created
Create the service entries:
kubectl apply -f \ DIR_PATH/samples/online-boutique/istio-manifests/allow-egress-googleapis.yaml
Expected output:
serviceentry.networking.istio.io/allow-egress-googleapis created serviceentry.networking.istio.io/allow-egress-google-metadata created
Exposing and accessing the application
There are multiple ways to expose the application. In this guide, we will use the ingress gateway we deployed above to do that. For other ways to expose the Online Boutique application refer to exposing and accessing the application section in the Deploying the Online Boutique sample application guide.
Deploy a
Gateway
andVirtualService
for the frontend servicekubectl apply -f \ DIR_PATH/samples/online-boutique/istio-manifests/frontend-gateway.yaml
Expected output:
gateway.networking.istio.io/frontend-gateway created virtualservice.networking.istio.io/frontend-ingress created
Get the external IP address of the ingress gateway, replace the placeholders with the following information:
- GATEWAY_SERVICE_NAME: the name of ingress gateway
service. If you deployed the sample gateway without modification that would
be
istio-ingressgateway
. - GATEWAY_NAMESPACE: the namespace in which you deployed the ingress gateway:
kubectl get service GATEWAY_SERVICE_NAME \ -n GATEWAY_NAMESPACE
The output is similar to:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.19.247.233 35.239.7.64 80:31380/TCP,443:31390/TCP,31400:31400/TCP 27m
In this example, the IP address of the ingress gateway is
35.239.7.64
.- GATEWAY_SERVICE_NAME: the name of ingress gateway
service. If you deployed the sample gateway without modification that would
be
Visit the application on your browser to confirm installation:
http://EXTERNAL_IP/
View the Service Mesh dashboards
After you have workloads deployed on your cluster with the sidecar proxies injected, you can explore the Cloud Service Mesh pages in the Google Cloud console to see all of the observability features that Cloud Service Mesh offers. Note that it takes about one or two minutes for telemetry data to be displayed in the Google Cloud console after you deploy workloads.
Access to Cloud Service Mesh in the Google Cloud console is controlled by Identity and Access Management (IAM). To access the Cloud Service Mesh pages, a Project Owner must grant users the Project Editor or Viewer role, or the more restrictive roles described in Controlling access to Cloud Service Mesh in the Google Cloud console.
In the Google Cloud console, go to Cloud Service Mesh.
Select the Google Cloud project from the drop-down list on the menu bar.
If you have more than one service mesh, select the mesh from the Service Mesh drop-down list.
To learn more, see Exploring Cloud Service Mesh in the Google Cloud console.
Clean up
Before cleaning up, if you are interested in learning more about mutual TLS, see Cloud Service Mesh by example: mTLS.
If you want to keep your cluster and remove the Online Boutique sample:
Delete the application namespaces:
kubectl delete -f DIR_PATH/samples/online-boutique/kubernetes-manifests/namespaces
Expected output:
namespace "ad" deleted namespace "cart" deleted namespace "checkout" deleted namespace "currency" deleted namespace "email" deleted namespace "frontend" deleted namespace "loadgenerator" deleted namespace "payment" deleted namespace "product-catalog" deleted namespace "recommendation" deleted namespace "shipping" deleted
Delete the service entries:
kubectl delete -f DIR_PATH/samples/online-boutique/istio-manifests/allow-egress-googleapis.yaml
Expected output:
serviceentry.networking.istio.io "allow-egress-googleapis" deleted serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
If you want to prevent additional charges, delete the cluster:
Run the following command:
gcloud container clusters delete CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
At the Do you want to continue (Y/n)? prompt, enter y.
After a few minutes, you see the following output:
Deleting cluster CLUSTER_NAME...done. Deleted [https://container.googleapis.com/v1/projects/PROJECT_ID/zones/CLUSTER_LOCATION/clusters/CLUSTER_NAME].
What's next
- To find out more about Managed Cloud Service Mesh, see Provisioning managed Cloud Service Mesh
- For a quick introduction to the gcloud CLI used in this tutorial, see
gcloud
commands - To find out how to explore Cloud Service Mesh in the Google Cloud console, see Exploring Cloud Service Mesh in the Google Cloud console
- To explore Cloud Service Mesh optional features, such as Cloud Trace, distroless proxy images, and end user authentication, see Enable optional features on managed Cloud Service Mesh
- To learn more about Security in Cloud Service Mesh, see Cloud Service Mesh Security Overview and Cloud Service Mesh Security Best Practices
- To find out more about Telemetry in Cloud Service Mesh, see Observability Overview