Set up GKE Dataplane V2 observability
Stay organized with collections
Save and categorize content based on your preferences.
This page shows how to configure Google Kubernetes Engine (GKE) clusters with GKE Dataplane V2 observability, starting in GKE versions 1.32 or later. For more information on the benefits and requirements of GKE Dataplane V2 observability, see About GKE Dataplane V2 observability.
Before you begin
Before you start, make sure that you have performed the following tasks:
- Enable the Google Kubernetes Engine API. Enable Google Kubernetes Engine API
- If you want to use the Google Cloud CLI for this task,
install and then
initialize the
gcloud CLI. If you previously installed the gcloud CLI, get the latest
version by running the
gcloud components updatecommand. Earlier gcloud CLI versions might not support running the commands in this document.
Configure GKE Dataplane V2 metrics
To collect metrics, you must configure GKE Dataplane V2 metrics. You can configure GKE Dataplane V2 metrics when you create a cluster or update a cluster running with GKE Dataplane V2. You can enable or disable GKE Dataplane V2 metrics using the gcloud CLI.
We recommend enabling GKE Dataplane V2 metrics and Google Cloud Managed Service for Prometheus on your GKE cluster. Once both are enabled, GKE Dataplane V2 metrics are sent to Google Cloud Managed Service for Prometheus.
Create an Autopilot cluster with GKE Dataplane V2 metrics enabled
When you create new GKE Autopilot clusters, GKE enables GKE Dataplane V2 metrics by default on the cluster without requiring a specific flag.
To use the GKE Autopilot cluster GKE Dataplane V2 metrics
with Google Cloud Managed Service for Prometheus, configure the ClusterPodMonitoring
resource to scrape the metrics and send them to Google Cloud Managed Service for Prometheus.
Create a
ClusterPodMonitoringmanifest:# Copyright 2023 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 # # https://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:monitoring.googleapis.com/v1 kind:ClusterPodMonitoring metadata: name:advanced-datapath-observability-metrics spec: selector: matchLabels: k8s-app:cilium endpoints: -port:flowmetrics interval:60s metricRelabeling: # only keep denormalized pod flow metrics -sourceLabels:[__name__] regex:'pod_flow_(ingress|egress)_flows_count' action:keep # extract pod name -sourceLabels:[__name__,destination] regex:'pod_flow_ingress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${2}' targetLabel:pod_name action:replace -sourceLabels:[__name__,source] regex:'pod_flow_egress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${2}' targetLabel:pod_name action:replace # extract workload name by removing 2 last "-XXX" parts -sourceLabels:[pod_name] regex:'([a-zA-Z0-9-\.]+)((-[a-zA-Z0-9\.]+){2})' replacement:'${1}' targetLabel:workload_name action:replace # extract workload name by removing one "-XXX" part when pod name has only 2 parts (eg. daemonset) -sourceLabels:[pod_name] regex:'([a-zA-Z0-9\.]+)((-[a-zA-Z0-9\.]+){1})' replacement:'${1}' targetLabel:workload_name action:replace # extract pod namespace -sourceLabels:[__name__,destination] regex:'pod_flow_ingress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${1}' targetLabel:namespace_name action:replace -sourceLabels:[__name__,source] regex:'pod_flow_egress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${1}' targetLabel:namespace_name action:replace # extract remote workload name -sourceLabels:[__name__,source] regex:'pod_flow_ingress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${2}' targetLabel:remote_workload action:replace -sourceLabels:[__name__,destination] regex:'pod_flow_egress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${2}' targetLabel:remote_workload action:replace # extract remote workload namespace -sourceLabels:[__name__,source] regex:'pod_flow_ingress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${1}' targetLabel:remote_namespace action:replace -sourceLabels:[__name__,destination] regex:'pod_flow_egress_flows_count;([a-zA-Z0-9-\.]+)/([a-zA-Z0-9-\.]+)' replacement:'${1}' targetLabel:remote_namespace action:replace # default remote workload class to "pod" -replacement:'pod' targetLabel:remote_class action:replace # extract remote workload class from reserved identity -sourceLabels:[__name__,source] regex:'pod_flow_ingress_flows_count;reserved:([^/]*)' replacement:'${1}' targetLabel:remote_class action:replace -sourceLabels:[__name__,destination] regex:'pod_flow_egress_flows_count;reserved:([^/]*)' replacement:'${1}' targetLabel:remote_class action:replace targetLabels: metadata:[]Apply the
ClusterPodMonitoringmanifest:kubectlapply-fClusterPodMonitoring.yaml
Create a Standard cluster with GKE Dataplane V2 metrics enabled
To enable GKE Dataplane V2 metrics, create a cluster with the
--enable-dataplane-v2-metrics flag:
gcloudcontainerclusterscreateCLUSTER_NAME\
--enable-dataplane-v2\
--enable-ip-alias\
--enable-managed-prometheus\
--enable-dataplane-v2-metrics
Replace the following:
CLUSTER_NAME: the name of your cluster.
The --enable-managed-prometheus flag instructs GKE to use the
metrics with Google Cloud Managed Service for Prometheus.
Enable GKE Dataplane V2 metrics on an existing cluster
To enable GKE Dataplane V2 metrics on an existing cluster, run the following command:
gcloudcontainerclustersupdateCLUSTER_NAME\
--enable-dataplane-v2-metrics
Replace CLUSTER_NAME with the name of your cluster.
Disable GKE Dataplane V2 metrics
To disable GKE Dataplane V2 metrics:
gcloudcontainerclustersupdateCLUSTER_NAME\
--disable-dataplane-v2-metrics
Replace CLUSTER_NAME with the name of your cluster.
Configure GKE Dataplane V2 observability tools
You can use a private endpoint to access the GKE Dataplane V2 observability troubleshooting tools. To enable GKE Dataplane V2 observability tools, you must have a cluster configured with GKE Dataplane V2. You can enable GKE Dataplane V2 observability tools on a new cluster or an existing cluster.
Create an Autopilot cluster with observability enabled
To create a GKE Autopilot cluster with GKE Dataplane V2 observability enabled:
gcloudcontainerclusterscreate-autoCLUSTER_NAME\
--enable-dataplane-v2-flow-observability\
--locationCOMPUTE_LOCATION
Replace the following:
* CLUSTER_NAME: the name of your cluster.
* COMPUTE_LOCATION: the
Compute Engine location
for the cluster.
Create a Standard cluster with observability enabled
To create a GKE Standard cluster with GKE Dataplane V2 observability enabled:
gcloudcontainerclusterscreateCLUSTER_NAME\
--enable-dataplane-v2\
--enable-ip-alias\
--enable-dataplane-v2-flow-observability\
--locationCOMPUTE_LOCATION
Replace the following:
* CLUSTER_NAME: the name of your cluster.
* COMPUTE_LOCATION: the
Compute Engine location
for the cluster.
Enable GKE Dataplane V2 observability tools on an existing cluster
To enable GKE Dataplane V2 observability on an existing cluster, run the following command:
gcloudcontainerclustersupdateCLUSTER_NAME\
--enable-dataplane-v2-flow-observability\
--locationCOMPUTE_LOCATION
Replace the following:
CLUSTER_NAME: the name of your cluster.COMPUTE_LOCATION: the Compute Engine location for the cluster.
Disable GKE Dataplane V2 observability tools
To disable GKE Dataplane V2 observability tools on an existing cluster, run the following command:
gcloudcontainerclustersupdateCLUSTER_NAME\
--disable-dataplane-v2-flow-observability
Replace CLUSTER_NAME with the name of your cluster.
How to use Hubble CLI
Use the Hubble CLI tool on the cluster after you enable the GKE Dataplane V2 observability feature.
Define alias for
hubble-clibinary:aliashubble="kubectl exec -it -n gke-managed-dpv2-observability deployment/hubble-relay -c hubble-cli -- hubble"To check the Hubble status, with the GKE Dataplane V2 observability feature enabled, use the Hubble CLI in all Autopilot clusters:
hubblestatusTo view current traffic, use the Hubble CLI as follows:
hubbleobserve
How to deploy the Hubble UI binary distribution
After GKE Dataplane V2 observability is enabled, you can deploy the open source Hubble UI.
Enable observability in your GKE cluster:
Create a GKE cluster with observability enabled:
gcloudcontainerclusterscreate-autohubble-rc-auto\ --locationCOMPUTE_LOCATION\ --cluster-versionVERSION\ --enable-dataplane-v2-flow-observabilityReplace the following:
VERSION: the version of your cluster.COMPUTE_LOCATION: the Compute Engine location for the cluster.
Alternatively, enable observability in an existing cluster:
gcloudcontainerclustersupdateCLUSTER_NAME\ --locationCOMPUTE_LOCATION\ --enable-dataplane-v2-flow-observabilityReplace the following:
CLUSTER_NAME: the name of your cluster.COMPUTE_LOCATION: the Compute Engine location for the cluster.
Configure
kubectlto connect to the cluster:gcloudcontainerclustersget-credentialsCLUSTER_NAME\ --locationCOMPUTE_LOCATIONReplace
CLUSTER_NAME: the name of your cluster.COMPUTE_LOCATION: the Compute Engine location for the cluster.
Deploy Hubble UI:
# Copyright 2025 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 # # https://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:v1 kind:ServiceAccount metadata: name:hubble-ui namespace:gke-managed-dpv2-observability --- kind:ClusterRole apiVersion:rbac.authorization.k8s.io/v1 metadata: name:hubble-ui labels: app.kubernetes.io/part-of:cilium rules: -apiGroups: -networking.k8s.io resources: -networkpolicies verbs: -get -list -watch -apiGroups: -"" resources: -componentstatuses -endpoints -namespaces -nodes -pods -services verbs: -get -list -watch -apiGroups: -apiextensions.k8s.io resources: -customresourcedefinitions verbs: -get -list -watch -apiGroups: -cilium.io resources: -"*" verbs: -get -list -watch --- kind:ClusterRoleBinding apiVersion:rbac.authorization.k8s.io/v1 metadata: name:hubble-ui labels: app.kubernetes.io/part-of:cilium roleRef: apiGroup:rbac.authorization.k8s.io kind:ClusterRole name:hubble-ui subjects: -kind:ServiceAccount name:hubble-ui namespace:gke-managed-dpv2-observability --- apiVersion:v1 kind:ConfigMap metadata: name:hubble-ui-nginx namespace:gke-managed-dpv2-observability data: nginx.conf:| server { listen 8081; # uncomment for IPv6 # listen [::]:8081; server_name localhost; root /app; index index.html; client_max_body_size 1G; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # CORS add_header Access-Control-Allow-Methods "GET, POST, PUT, HEAD, DELETE, OPTIONS"; add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 1728000; add_header Access-Control-Expose-Headers content-length,grpc-status,grpc-message; add_header Access-Control-Allow-Headers range,keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout; if ($request_method = OPTIONS) { return 204; } # /CORS location /api { proxy_http_version 1.1; proxy_pass_request_headers on; proxy_hide_header Access-Control-Allow-Origin; proxy_pass http://127.0.0.1:8090; } location / { # double `/index.html` is required here try_files $uri $uri/ /index.html /index.html; } } } --- kind:Deployment apiVersion:apps/v1 metadata: name:hubble-ui namespace:gke-managed-dpv2-observability labels: k8s-app:hubble-ui app.kubernetes.io/name:hubble-ui app.kubernetes.io/part-of:cilium spec: replicas:1 selector: matchLabels: k8s-app:hubble-ui template: metadata: labels: k8s-app:hubble-ui app.kubernetes.io/name:hubble-ui app.kubernetes.io/part-of:cilium spec: securityContext: fsGroup:1000 seccompProfile: type:RuntimeDefault serviceAccount:hubble-ui serviceAccountName:hubble-ui containers: -name:frontend image:quay.io/cilium/hubble-ui:v0.13.2 ports: -name:http containerPort:8081 volumeMounts: -name:hubble-ui-nginx-conf mountPath:/etc/nginx/conf.d/default.conf subPath:nginx.conf -name:tmp-dir mountPath:/tmp terminationMessagePolicy:FallbackToLogsOnError securityContext: allowPrivilegeEscalation:false readOnlyRootFilesystem:true runAsUser:1000 runAsGroup:1000 capabilities: drop: -all -name:backend image:quay.io/cilium/hubble-ui-backend:v0.13.2 env: -name:EVENTS_SERVER_PORT value:"8090" -name:FLOWS_API_ADDR value:"hubble-relay.gke-managed-dpv2-observability.svc:443" -name:TLS_TO_RELAY_ENABLED value:"true" -name:TLS_RELAY_SERVER_NAME value:relay.gke-managed-dpv2-observability.svc.cluster.local -name:TLS_RELAY_CA_CERT_FILES value:/var/lib/hubble-ui/certs/hubble-relay-ca.crt -name:TLS_RELAY_CLIENT_CERT_FILE value:/var/lib/hubble-ui/certs/client.crt -name:TLS_RELAY_CLIENT_KEY_FILE value:/var/lib/hubble-ui/certs/client.key ports: -name:grpc containerPort:8090 volumeMounts: -name:hubble-ui-client-certs mountPath:/var/lib/hubble-ui/certs readOnly:true terminationMessagePolicy:FallbackToLogsOnError securityContext: allowPrivilegeEscalation:false readOnlyRootFilesystem:true runAsUser:1000 runAsGroup:1000 capabilities: drop: -all volumes: -configMap: defaultMode:420 name:hubble-ui-nginx name:hubble-ui-nginx-conf -emptyDir:{} name:tmp-dir -name:hubble-ui-client-certs projected: # note: the leading zero means this number is in octal representation: do not remove it defaultMode:0400 sources: -secret: name:hubble-relay-client-certs items: -key:ca.crt path:hubble-relay-ca.crt -key:tls.crt path:client.crt -key:tls.key path:client.key --- kind:Service apiVersion:v1 metadata: name:hubble-ui namespace:gke-managed-dpv2-observability labels: k8s-app:hubble-ui app.kubernetes.io/name:hubble-ui app.kubernetes.io/part-of:cilium spec: type:ClusterIP selector: k8s-app:hubble-ui ports: -name:http port:80 targetPort:8081Apply the
hubble-ui-132.yamlmanifest:kubectl apply -f hubble-ui-132.yamlExpose Service with port forwarding:
kubectl-ngke-managed-dpv2-observabilityport-forwardservice/hubble-ui16100:80--address='0.0.0.0'Access the Hubble UI in your web browser: