הגדרת ניראות (observability) של GKE Dataplane V2

בדף הזה מוסבר איך להגדיר אשכולות Google Kubernetes Engine ‏ (GKE) עם יכולות ניטור של GKE Dataplane V2, החל מגרסאות GKE‏ 1.32 ואילך. מידע נוסף על היתרונות והדרישות של יכולת התצפית של GKE Dataplane V2 זמין במאמר מידע על יכולת התצפית של GKE Dataplane V2.

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.

הגדרת מדדים של GKE Dataplane V2

כדי לאסוף מדדים, צריך להגדיר מדדים של GKE Dataplane V2. אפשר להגדיר מדדים של GKE Dataplane V2 כשיוצרים אשכול או מעדכנים אשכול שפועל עם GKE Dataplane V2. אפשר להפעיל או להשבית את המדדים של GKE Dataplane V2 באמצעות ה-CLI של gcloud.

מומלץ להפעיל את המדדים של GKE Dataplane V2 ואת השירות המנוהל של Google Cloud ל-Prometheus באשכול GKE. אחרי שמפעילים את שניהם, המדדים של GKE Dataplane V2 נשלחים לשירות המנוהל של Google Cloud ל-Prometheus.

יצירת אשכול Autopilot עם הפעלת מדדים של GKE Dataplane V2

כשיוצרים אשכולות חדשים של GKE Autopilot,‏ GKE מפעיל את המדדים של GKE Dataplane V2 כברירת מחדל באשכול, בלי שנדרש דגל ספציפי.

כדי להשתמש במדדים של GKE Dataplane V2 באשכול GKE Autopilot עם השירות המנוהל של Google Cloud ל-Prometheus, צריך להגדיר את משאב ClusterPodMonitoring כדי לגרד את המדדים ולשלוח אותם לשירות המנוהל של Google Cloud ל-Prometheus.

  1. יצירת קובץ מניפסט ClusterPodMonitoring:

    # 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: []
    
  2. החלת מניפסט ClusterPodMonitoring:

    kubectl apply -f ClusterPodMonitoring.yaml
    
אחרי שמגדירים את משאב ClusterPodMonitoring, מערכת GKE מחייבת עלות על העברת נתונים על סמך נפח המדדים.

יצירת אשכול Standard עם מדדים של GKE Dataplane V2

כדי להפעיל את המדדים של GKE Dataplane V2, יוצרים אשכול עם הדגל --enable-dataplane-v2-metrics:

gcloud container clusters create CLUSTER_NAME \
    --enable-dataplane-v2 \
    --enable-ip-alias \
    --enable-managed-prometheus \
    --enable-dataplane-v2-metrics

מחליפים את מה שכתוב בשדות הבאים:

  • CLUSTER_NAME: השם של האשכול.

הדגל --enable-managed-prometheus מורה ל-GKE להשתמש במדדים עם השירות המנוהל של Google Cloud ל-Prometheus.

הפעלה של מדדים של GKE Dataplane V2 באשכול קיים

כדי להפעיל מדדים של GKE Dataplane V2 באשכול קיים, מריצים את הפקודה הבאה:

gcloud container clusters update CLUSTER_NAME \
    --enable-dataplane-v2-metrics

מחליפים את CLUSTER_NAME בשם האשכול.

השבתה של מדדים ב-GKE Dataplane V2

כדי להשבית את המדדים של GKE Dataplane V2:

gcloud container clusters update CLUSTER_NAME \
    --disable-dataplane-v2-metrics

מחליפים את CLUSTER_NAME בשם האשכול.

הגדרת כלי ניראות (observability) של GKE Dataplane V2

אתם יכולים להשתמש בנקודת קצה פרטית כדי לגשת לכלי פתרון הבעיות של GKE Dataplane V2 observability. כדי להפעיל כלי ניטור של GKE Dataplane V2, צריך להגדיר אשכול עם GKE Dataplane V2. אפשר להפעיל כלי ניטור של GKE Dataplane V2 באשכול חדש או באשכול קיים.

יצירת אשכול Autopilot עם הפעלת יכולת צפייה

כדי ליצור אשכול GKE Autopilot עם יכולת ניטור של GKE Dataplane V2:

gcloud container clusters create-auto CLUSTER_NAME \
    --enable-dataplane-v2-flow-observability \
    --location COMPUTE_LOCATION

מחליפים את הערכים הבאים: * CLUSTER_NAME: שם האשכול. ‫* COMPUTE_LOCATION: המיקום של Compute Engine באשכול.

יצירת אשכול רגיל עם הפעלת יכולת התבוננות

כדי ליצור אשכול GKE Standard עם יכולת ניהול של GKE Dataplane V2:

gcloud container clusters create CLUSTER_NAME \
    --enable-dataplane-v2 \
    --enable-ip-alias \
    --enable-dataplane-v2-flow-observability \
    --location COMPUTE_LOCATION

מחליפים את הערכים הבאים: * CLUSTER_NAME: שם האשכול. ‫* COMPUTE_LOCATION: המיקום של Compute Engine באשכול.

הפעלת כלי נראות של GKE Dataplane V2 באשכול קיים

כדי להפעיל את יכולת הצפייה ב-GKE Dataplane V2 באשכול קיים, מריצים את הפקודה הבאה:

gcloud container clusters update CLUSTER_NAME \
    --enable-dataplane-v2-flow-observability \
    --location COMPUTE_LOCATION

מחליפים את מה שכתוב בשדות הבאים:

השבתה של כלי ניראות ב-GKE Dataplane V2

כדי להשבית את כלי הנראות של GKE Dataplane V2 באשכול קיים, מריצים את הפקודה הבאה:

gcloud container clusters update CLUSTER_NAME \
    --disable-dataplane-v2-flow-observability

מחליפים את CLUSTER_NAME בשם האשכול.

איך משתמשים ב-Hubble CLI

אחרי שמפעילים את תכונת יכולת הצפייה ב-GKE Dataplane V2, אפשר להשתמש בכלי Hubble CLI באשכול.

  1. הגדרת כינוי לקובץ הבינארי hubble-cli:

    alias hubble="kubectl exec -it -n gke-managed-dpv2-observability deployment/hubble-relay -c hubble-cli -- hubble"
    
  2. כדי לבדוק את הסטטוס של Hubble, כשמופעלת תכונת היכולת להתבוננות של GKE Dataplane V2, משתמשים ב-Hubble CLI בכל אשכולות Autopilot:

    hubble status
    
  3. כדי לראות את התנועה הנוכחית, משתמשים ב-CLI של Hubble באופן הבא:

    hubble observe
    

איך פורסים את הפצה הבינארית של ממשק המשתמש של Hubble

אחרי שמפעילים את יכולת הצפייה במישור הנתונים של GKE Dataplane V2, אפשר לפרוס את ממשק המשתמש של Hubble בקוד פתוח.

  1. הפעלת יכולת צפייה באשכול GKE:

    1. יוצרים אשכול GKE עם הפעלת יכולות ניהול:

      gcloud container clusters create-auto hubble-rc-auto \
          --location COMPUTE_LOCATION \
          --cluster-version VERSION \
          --enable-dataplane-v2-flow-observability
      

      מחליפים את מה שכתוב בשדות הבאים:

    2. אפשרות אחרת היא להפעיל את יכולת הצפייה בצביר קיים:

      gcloud container clusters update CLUSTER_NAME \
          --location COMPUTE_LOCATION \
          --enable-dataplane-v2-flow-observability
      

      מחליפים את מה שכתוב בשדות הבאים:

  2. מגדירים את kubectl כדי להתחבר לאשכול:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location COMPUTE_LOCATION
    

    החלפה

  3. פורסים את ממשק המשתמש של Hubble:

    # 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: 8081
    
  4. החלת מניפסט hubble-ui-132.yaml:

    kubectl apply -f hubble-ui-132.yaml
    
  5. חשיפת שירות באמצעות העברה ליציאה אחרת:

    kubectl -n gke-managed-dpv2-observability port-forward service/hubble-ui 16100:80 --address='0.0.0.0'
    
  6. ניגשים לממשק המשתמש של Hubble בדפדפן האינטרנט:

    http://localhost:16100/

המאמרים הבאים