Secure Kubernetes Services with Istio

Autopilot

This tutorial is intended for Kubernetes users and administrators who areinterested in usingIstio service mesh to securelydeploy Kubernetes Services and enable mutual TLS (mTLS) communication.

Istio and Cloud Service Mesh

Istio is not a supported Google product. We recommend running managedCloud Service Mesh instead. For more information, seeProvision Cloud Service Mesh on a GKE Autopilot cluster.

To run Istio on a GKE Autopilotcluster, you must enable theNET_ADMIN andNET_RAWLinux capabilities in your containers. These are privileged linux capabilities.TheNET_ADMIN capability grants broad access to network operations,such as write access to routing tables and firewalls. An attacker couldpotentially use this access to perform privilege escalation attacks in yourcluster. For details, seetheCAP_NET_ADMIN manpage.

Cloud Service Mesh provides the following benefits:

  • You can provision managed Cloud Service Mesh using theFleet API without client-sidetools likeistioctl.
  • Cloud Service Mesh automatically injects sidecar proxies into workloadswithout granting elevated privileges to your containers.
  • You can view rich dashboards for your mesh and services without anyextra configuration and then use these metrics to configure service levelobjectives (SLOs) and alerts to monitor the health of your applications.
  • The managed Cloud Service Mesh control plane is upgraded automatically to ensure that you getthe latest security patches and features.
  • The Cloud Service Mesh managed data plane automatically upgrades the sidecarproxies in your workloads so that you don't need to restart servicesyourself when proxy upgrades and security patches are available.
  • Cloud Service Mesh is a supported product and can be configured usingstandard open source Istio APIs. For more information, seesupported features.

Objectives

This tutorial includes the following steps:

  • Create a GKE Autopilot cluster.
  • Install Istio using theistioctl command line tool.
  • Deploy a sample application to test mutual TLS (mTLS) authentication.
  • Configure Istio to use mTLS authentication for service-to-servicecommunication using aPeerAuthentication custom resource.
  • Verify mTLS authentication using the Kiali dashboard.

Costs

In this document, you use the following billable components of Google Cloud:

To generate a cost estimate based on your projected usage, use thepricing calculator.

New Google Cloud users might be eligible for afree trial.

When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, seeClean up.

Before you begin

Cloud Shell is preinstalled with the software you need for thistutorial, includingkubectl, thegcloud CLI, andTerraform.If you don't use Cloud Shell, you must install the gcloud CLI.

  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. Install the Google Cloud CLI.

    Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.
  3. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  4. Toinitialize the gcloud CLI, run the following command:

    gcloudinit
  5. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
    Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.
    • Create a Google Cloud project:

      gcloud projects createPROJECT_ID

      ReplacePROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set projectPROJECT_ID

      ReplacePROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the GKE API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enable permission.Learn how to grant roles.

    gcloudservicesenablecontainer.googleapis.com
  8. Install the Google Cloud CLI.

    Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.
  9. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  10. Toinitialize the gcloud CLI, run the following command:

    gcloudinit
  11. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
    Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.
    • Create a Google Cloud project:

      gcloud projects createPROJECT_ID

      ReplacePROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set projectPROJECT_ID

      ReplacePROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the GKE API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enable permission.Learn how to grant roles.

    gcloudservicesenablecontainer.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles:roles/container.clusterAdmin

    gcloudprojectsadd-iam-policy-bindingPROJECT_ID--member="user:USER_IDENTIFIER"--role=ROLE

    Replace the following:

    • PROJECT_ID: Your project ID.
    • USER_IDENTIFIER: The identifier for your user account. For example,myemail@example.com.
    • ROLE: The IAM role that you grant to your user account.

Prepare the environment

To set up your environment, follow these steps:

  1. Set environment variables:

    export PROJECT_ID=PROJECT_IDgcloud config set project $PROJECT_IDgcloud config set compute/region us-central1

    ReplacePROJECT_ID with your Google Cloudproject ID.

  2. Clone the GitHub repository:

    gitclonehttps://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
  3. Change to the working directory:

    cdkubernetes-engine-samples/service-mesh/istio-tutorial

Create a GKE cluster

Enable the Linux capabilities that Istio requires:NET_RAW andNET_ADMIN.GKE Autopilot does not allowNET_ADMIN by default, butyou can enableNET_ADMIN using the--workload-policies=allow-net-admincommand in GKE versions 1.27 and later:

gcloudcontainerclusterscreate-autoistio-cluster\--location="us-central1"\--workload-policies="allow-net-admin"

To learn more about GKE Autopilot security, seeBuilt-in security configurations.

Install Istio

You can install Istio on a GKE cluster usingIstioctl.

In this tutorial, you install Istio with the defaultconfiguration profilerecommended for production deployments.

  1. Install Istio:

    • To install the latest version of Istio:

      curl-Lhttps://istio.io/downloadIstio|sh-
    • To install a specific version of Istio:

      exportISTIO_VERSION=VERSION_NUMBERcurl-Lhttps://istio.io/downloadIstio|TARGET_ARCH=$(uname-m)sh-

      ReplaceVERSION_NUMBER with the version of Istio youwant to install. For information about Istio releases, seeRelease announcements.

  2. Add theistioctl command line tool to the PATH:

    cdistio-*exportPATH=$PWD/bin:$PATH
  3. Install Istio on the cluster:

    istioctlinstall--setprofile="default"-y

    This step might take several minutes.

  4. Wait for the Istio Pods to be ready:

    watchkubectlgetpods-nistio-system

    The output is similar to the following:

    NAME                                    READY   STATUS        RESTARTS   AGEistio-ingressgateway-5c47bff876-wjm96   1/1     Running       0          2m54sistiod-5fc7cb65cd-k8cp4                 1/1     Running       0          2m57s

    When the Istio Pods areRunning, return to the command line by pressingCtrl+C.

Deploy the sample application

In this section, you use theBank of Anthos sample application to create a service mesh with mTLS authentication.

  1. Add a namespace label that instructs Istio to enable automaticinjection of Envoy sidecar proxies:

    kubectllabelnamespacedefaultistio-injection=enabled
  2. Deploy the sample application:

    cd..gitclonehttps://github.com/GoogleCloudPlatform/bank-of-anthos.gitkubectlapply-fbank-of-anthos/extras/jwt/jwt-secret.yamlkubectlapply-fbank-of-anthos/kubernetes-manifests/
  3. Wait for the application to be ready:

    watchkubectlgetpods

    The output is similar to the following:

    NAME                                 READY   STATUS    RESTARTS   AGEaccounts-db-0                        2/2     Running   0          2m16sbalancereader-5c695f78f5-x4wlz       2/2     Running   0          3m8scontacts-557fc79c5-5d7fg             2/2     Running   0          3m7sfrontend-7dd589c5d7-b4cgq            2/2     Running   0          3m7sledger-db-0                          2/2     Running   0          3m6sledgerwriter-6497f5cf9b-25c6x        2/2     Running   0          3m5sloadgenerator-57f6896fd6-lx5df       2/2     Running   0          3m5stransactionhistory-6c498965f-tl2sk   2/2     Running   0          3m4suserservice-95f44b65b-mlk2p          2/2     Running   0          3m4s

    When the Pods areRunning, return to the command line by pressingCtrl+C.

  4. Review the following manifest:

    # Copyright 2020 Google LLC## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion:networking.istio.io/v1alpha3kind:Gatewaymetadata:name:frontend-gatewayspec:selector:istio:ingressgateway# use Istio default gateway implementationservers:-port:number:80name:httpprotocol:HTTPhosts:-"*"---apiVersion:networking.istio.io/v1alpha3kind:VirtualServicemetadata:name:frontend-ingressspec:hosts:-"*"gateways:-frontend-gatewayhttp:-route:-destination:host:frontendport:number:80

    This manifest describes IstioGateway and VirtualService resources that expose the application and use Istio as theIngress controller.

  5. Apply the manifest to your cluster:

    kubectlapply-fbank-of-anthos/extras/istio/frontend-ingress.yaml

Configure mTLS

Mutual TLS (mTLS) authentication is enabled by default in Istio. That meansthat Istio monitors server workloads that have been migrated to Istio proxiesand automatically configures client proxies to establish mTLS connections withthese workloads. Istio also configures client proxies not to use mTLS whenconnecting to workloads without sidecar proxies.

Istio can configure mTLS to work in three modes:

  • PERMISSIVE: Workloads accept both mTLS and plain text traffic.
  • STRICT: Workloads only accept mTLS traffic.
  • DISABLE: mTLS is disabled. Use this mode if you want to use your ownsecurity solution.

You can apply mTLS configuration globally, per namespace, or per workload. Inthis tutorial, you apply configuration per namespace using theSTRICT mTLSmode.

  1. Review the following manifest:

    apiVersion:security.istio.io/v1beta1kind:PeerAuthenticationmetadata:name:defaultspec:mtls:mode:STRICT

    This manifest describes a Peer Authentication Istio Custom Resource.

  2. Apply the manifest to your cluster:

    kubectlapply-fpeer-authentication.yaml

For more information about mTLS in Istio, seemutual TLS authentication.

Verify mTLS is enabled

Kiali is a web-based observability dashboard for Istio service mesh that provides agraphical view of your microservices environment, allowing you to monitor andtroubleshoot your applications. You can use Kiali to verify that mTLSauthentication is enabled and functioning correctly in the Istio service mesh.Kiali requires Prometheus as a telemetry data source. This tutorial usesGoogle Cloud Managed Service for Prometheus.

Install a query interface

  1. Create an IAM service account with theroles/monitoring.viewer to allow the query interface to access metrics:

    gcloudiamservice-accountscreatemonitoring\--display-name="Service account for query interface"gcloudprojectsadd-iam-policy-bindingPROJECT_ID\--member"serviceAccount:monitoring@PROJECT_ID.iam.gserviceaccount.com"\--roleroles/monitoring.viewergcloudiamservice-accountsadd-iam-policy-binding\monitoring@PROJECT_ID.iam.gserviceaccount.com\--roleroles/iam.workloadIdentityUser\--member"serviceAccount:PROJECT_ID.svc.id.goog[monitoring/default]"
  2. Create a Kubernetes namespace:

    kubectlcreatenamespacemonitoring
  3. Annotate the default Kubernetes service account in the namespace toconfigureWorkload Identity Federation for GKE:

    kubectlannotateserviceaccount-nmonitoringdefault\iam.gke.io/gcp-service-account=monitoring@PROJECT_ID.iam.gserviceaccount.com--overwrite
  4. Deploy the query interface workload:

    kubectl-nmonitoringapply-fhttps://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.7.1/examples/frontend.yaml
  5. Review the following manifest:

    apiVersion:monitoring.googleapis.com/v1kind:PodMonitoringmetadata:name:istiodnamespace:istio-systemspec:selector:matchLabels:app:istiodendpoints:-port:15014path:/metricstimeout:30sinterval:60s

    This manifest describes aPodMonitoring resource that collects Istio andEnvoy Proxy metrics.

  6. Apply the manifest to your cluster:

    kubectlapply-fpod-monitorings.yaml
  7. Get a link to the sample application:

    INGRESS_HOST=$(kubectl-nistio-systemgetserviceistio-ingressgateway-ojsonpath='{.status.loadBalancer.ingress[0].ip}')echo"http://$INGRESS_HOST"
  8. Open the link to view the sample application. Sign in with the defaultusername and password to generate traffic between the microservices.

Install Kiali

We recommend that you install Kiali using the Kiali Operator.

  1. Install the Kiali Operator:

    helmrepoaddkialihttps://kiali.org/helm-chartshelmrepoupdatehelminstall\--namespacekiali-operator\--create-namespace\kiali-operator\kiali/kiali-operator
  2. Review the following manifest:

    apiVersion:kiali.io/v1alpha1kind:Kialimetadata:name:kialinamespace:istio-systemspec:deployment:namespace:istio-systemauth:strategy:anonymousexternal_services:custom_dashboards:prometheus:url:"http://frontend.monitoring:9090/"auth:type:noneprometheus:url:"http://frontend.monitoring:9090/"auth:type:nonetracing:enabled:falsegrafana:enabled:false

    This manifest describes an Operator custom resource that defines theKiali server.

  3. Apply the manifest to your cluster:

    kubectlapply-fkiali.yaml
  4. Wait for the Kiali server to be ready:

    watchkubectlgetpods-nistio-system

    The output is similar to the following:

    NAME                                    READY   STATUS    RESTARTS   AGEistio-ingressgateway-6845466857-92zp8   1/1     Running   0          9m11sistiod-6b47d84cf-4cqlt                  1/1     Running   0          12m

    When the Pods areRunning, return to the command line by pressingCtrl+C.

  5. Set up port forwarding on the Kiali server Service to access the dashboard:

    kubectl-nistio-systemport-forwardsvc/kiali8080:20001
  6. Open Web Preview. In Kiali, go to theGraph section and select theSecurity option in theDisplay drop-down. This view displays thesecurity state of each node in the graph. Nodes with anmTLS enabledbadge indicate that mTLS is enabled for that service, and nodes without thebadge indicate that mTLS is not enabled.

Clean up

To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.

Delete the project

    Caution: Deleting a project has the following effects:
    • Everything in the project is deleted. If you used an existing project for the tasks in this document, when you delete it, you also delete any other work you've done in the project.
    • Custom project IDs are lost. When you created this project, you might have created a custom project ID that you want to use in the future. To preserve the URLs that use the project ID, such as anappspot.com URL, delete selected resources inside the project instead of deleting the whole project.

    If you plan to explore multiple architectures, tutorials, or quickstarts, reusing projects can help you avoid exceeding project quota limits.

    Delete a Google Cloud project:

    gcloud projects deletePROJECT_ID

Delete the individual resources

If you used an existing project and you don't want to delete it, delete theindividual resources.

  1. Delete Kiali:

    kubectl-nistio-systemdeletekialikialihelmuninstall--namespacekiali-operatorkiali-operator
  2. Delete the monitoring resources:

    kubectl-nmonitoringdelete-fhttps://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.7.1/examples/frontend.yaml
  3. Delete the sample application:

    kubectldelete-fbank-of-anthos/extras/istio/frontend-ingress.yamlkubectldelete-fbank-of-anthos/kubernetes-manifests
  4. Uninstall Istio:

    istioctluninstall--purge-y
  5. Delete the GKE cluster:

    gcloudcontainerclustersdelete--locationus-central1istio-cluster--quiet

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.