Create a GKE cluster with Anthos Service Mesh and the gcloud CLI

In this tutorial, you install Anthos Service Mesh using a Google-provided tool, asmcli, on a new Google Kubernetes Engine (GKE) public cluster. This tutorial walks you through:

  1. Configuring your Google Cloud project.
  2. Creating a GKE cluster with the minimum number of vCPUs required by Anthos Service Mesh.
  3. Installing Anthos Service Mesh with an in-cluster control plane.
  4. Deploying a sample application so that you can view telemetry data on the Anthos Service Mesh dashboards in the Google Cloud console.
  5. Exposing and accessing the sample application.

To simplify the quickstart and not have multiple different paths the following choices were made:

  • Enabling Anthos Service Mesh certificate authority (Mesh CA).
  • Deploying an ingress gateway to expose the application.

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. New Google Cloud users might be eligible for a free trial.

When you finish this quickstart, you can avoid continued billing by deleting the cluster. For more information, see Clean up.

Before you begin

  1. 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.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Kubernetes Engine API.

    Enable the API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Kubernetes Engine API.

    Enable the API

  8. Make a note of your project ID.

Although Anthos Service Mesh requires other APIs, asmcli enables them for you. To keep billing costs down, the asmcli script doesn't enable the GKE Enterprise API. There are some minor differences in the Google Cloud console when the GKE Enterprise API is enabled. To learn more about these differences, see GKE Enterprise and Anthos Service Mesh UI differences.

Install required tools

You can run the tool on Cloud Shell or on your local machine running Linux. Cloud Shell pre-installs all the required tools. Note that macOS isn't supported because it comes with an old version of bash.

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, kpt, 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 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.

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 Linux computer

  1. Make sure you have the following tools installed:

  2. Authenticate with the Google Cloud CLI:

    gcloud auth login --project PROJECT_ID
    
  3. Update the components:

    gcloud components update
    
  4. Make sure that git is in your path so that kpt can find it.

Create a GKE cluster

  1. Run the following command to create the cluster with the minimum number of vCPUs required by Anthos 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
    
  2. 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.
    
  3. Set the current context for kubectl to the cluster.

    kubectl config set-context CLUSTER_NAME
    

    Expected output:

    Context "CLUSTER_NAME" created.
    

Apply the mesh_id label

Apply the mesh_id label for your GKE cluster:

  gcloud container clusters update CLUSTER_NAME --zone CLUSTER_LOCATION\
      --update-labels mesh_id=proj-FLEET_PROJECT_NUMBER

where:

  • CLUSTER_NAME is the name of your cluster.
  • CLUSTER_LOCATION is the Compute zone for your cluster.
  • FLEET_PROJECT_NUMBER is the unique identifier for your fleet project.

Download asmcli

This section describes how to download the asmcli.

  1. Download the version that installs Anthos Service Mesh to the current working directory:

    curl https://storage.googleapis.com/csm-artifacts/asm/ > asmcli
    

    Expected output:

    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
    100  167k  100  167k    0     0   701k      0 --:--:-- --:--:-- --:--:--  701k
    
  2. Make the script executable:

    chmod +x asmcli
    

Install Anthos Service Mesh

Run the asmcli tool with the following options to install Anthos Service Mesh on the cluster that you created previously. 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.

./asmcli install \
  --project_id PROJECT_ID \
  --cluster_name CLUSTER_NAME \
  --cluster_location CLUSTER_LOCATION \
  --fleet_id FLEET_PROJECT_ID \
  --output_dir DIR_PATH \
  --enable_all \
  --ca mesh_ca
  • --project_id, --cluster_name, and --cluster_location Specify the project ID that the cluster is in, the cluster name, and either the cluster zone or region.
  • --fleet_id The project ID of the fleet host project. If you don't include this option, asmcli uses the project that the cluster was created in when registering the cluster.
  • --output_dir Include this option to specify a directory where asmcli downloads the anthos-service-mesh package and extracts the installation file, which contains istioctl, samples, and manifests. Otherwise asmcli downloads the files to a tmp directory. You can specify either a relative path or a full path. The environment variable $PWD doesn't work here.
  • --enable_all Allows the script to:
    • Grant required IAM permissions.
    • Enable the required Google APIs.
    • Set a label on the cluster that identifies the mesh.
    • Register the cluster to the fleet if it isn't already registered.

    It can take several minutes for the asmcli tool to finish. The tool outputs informational messages so you can follow its progress.

    Expected output on successful installation:

    asmcli: Successfully installed ASM.
    

    Deploy an ingress gateway

    Anthos 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.

    1. 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
      
    2. 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

      1. 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 Anthos Service Mesh version, for example:

      2. Apply the revision label to the namespace. In the following command, REVISION is the value of the istiod 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 the istio.io/rev label, which you should expect in new installations of Anthos Service Mesh or new deployments. Because auto-injection fails if a namespace has both the istio.io/rev and the istio-injection label, all kubectl label commands in the Anthos Service Mesh documentation explicitly specify both labels.

    3. Download the example ingress gateway .yaml configuration file from the anthos-service-mesh-packages repository.

    4. 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.

    1. 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
      
    2. 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 namespace

      Default 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
      
    3. Deploy the sample application to the cluster.

      1. 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
        
      2. 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
        
      3. 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.

    1. Deploy a Gateway and VirtualService for the frontend service

      kubectl 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
      
    2. 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.

    3. 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 Anthos Service Mesh pages in the Google Cloud console to see all of the observability features that Anthos 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 Anthos Service Mesh in the Google Cloud console is controlled by Identity and Access Management (IAM). To access the Anthos 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 Anthos Service Mesh in the Google Cloud console.

    1. In the Google Cloud console, go to Anthos Service Mesh.

      Go to Anthos Service Mesh

    2. Select the Google Cloud project from the drop-down list on the menu bar.

    3. If you have more than one service mesh, select the mesh from the Service Mesh drop-down list.

    To learn more, see Exploring Anthos Service Mesh in the Google Cloud console.

    Clean up

    Before cleaning up, if you are interested in learning more about mutual TLS, see Anthos Service Mesh by example: mTLS.

    • If you want to keep your cluster and remove the Online Boutique sample:

      1. 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
        
      2. 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:

      1. Run the following command:

        gcloud container clusters delete  CLUSTER_NAME \
            --project=PROJECT_ID \
            --zone=CLUSTER_LOCATION
        
      2. 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