分享方式:


設定 Azure Kubernetes Service (AKS) 的進階網路可檢視性 - Azure 受控 Prometheus 和 Grafana (預覽)

本文說明如何使用受控 Prometheus 和 Grafana 來設定 Azure Kubernetes Service (AKS) 的進階網路可檢視性,以將已擷取的計量視覺化。

您可以使用進階網路可檢視性來收集 AKS 叢集網路流量的相關資料。 其可啟用集中式平台以供監視應用程式和網路的健康情況。 目前,計量會儲存在 Prometheus 中,並可使用 Grafana 來將計量視覺化。 進階網路可檢視性也提供啟用 Hubble 的能力。 Cilium 和非 Cilium 叢集都支援這些功能。

進階網路可檢視性是進階容器網路服務的其中一項功能。 如需 Azure Kubernetes Service (AKS) 進階容器網路服務的詳細資訊,請參閱什麼是 Azure Kubernetes Service (AKS) 進階容器網路服務?

重要

進階網路可檢視性目前為預覽版。 請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。

必要條件

  • 具有有效訂用帳戶的 Azure 帳戶。 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶
  • 本文步驟所需的 Azure CLI 最低版本為 2.56.0。 執行 az --version 以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure CLI

安裝 aks-preview Azure CLI 延伸模組

使用 az extension addaz extension update 命令來安裝或更新 Azure CLI 預覽延伸模組。

# Install the aks-preview extension
az extension add --name aks-preview

# Update the extension to make sure you have the latest version installed
az extension update --name aks-preview

註冊 AdvancedNetworkingPreview 功能旗標

使用 az feature register 命令註冊 az feature register --namespace "Microsoft.ContainerService" --name "AdvancedNetworkingPreview" 功能旗標。

az feature register --namespace "Microsoft.ContainerService" --name "AdvancedNetworkingPreview"

使用 az feature show 命令來確認註冊成功。 需要幾分鐘的時間才能完成註冊。

az feature show --namespace "Microsoft.ContainerService" --name "AdvancedNetworkingPreview"

在功能顯示 Registered 後,請使用 az provider register 命令重新整理 Microsoft.ContainerService 資源提供者的註冊。

建立資源群組

資源群組是在其中部署與管理 Azure 資源的邏輯容器。 使用 az group create 命令建立資源群組。

# Set environment variables for the resource group name and location. Make sure to replace the placeholders with your own values.
export RESOURCE_GROUP="<resource-group-name>"
export LOCATION="<azure-region>"

# Create a resource group
az group create --name $RESOURCE_GROUP --location $LOCATION

建立具有進階網路可檢視性的 AKS 叢集

使用 az aks create 命令和 --enable-advanced-networking-observability 旗標,以非 Cilium 資料平面建立具有進階網路可檢視性的 AKS 叢集。

# Set an environment variable for the AKS cluster name. Make sure to replace the placeholder with your own value.
export CLUSTER_NAME="<aks-cluster-name>"

# Create an AKS cluster
az aks create \
    --name $CLUSTER_NAME \
    --resource-group $RESOURCE_GROUP \
    --generate-ssh-keys \
    --network-plugin azure \
    --network-plugin-mode overlay \
    --pod-cidr 192.168.0.0/16 \
    --enable-advanced-network-observability

在現有叢集上啟用進階網路可檢視性

使用 az aks update 命令在現有叢集上啟用進階網路可檢視性。

注意

從 Kubernetes 1.29 版開始,使用 Cilium 資料平面的叢集可支援進階網路可檢視性。

az aks update \
    --resource-group $RESOURCE_GROUP \
    --name $CLUSTER_NAME \
    --enable-advanced-network-observability

取得叢集認證

使用 az aks get-credentials 命令來取得叢集認證。

az aks get-credentials --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP

Azure 受控的 Prometheus 和 Grafana

使用下列範例,為您的 AKS 叢集安裝並啟用 Prometheus 和 Grafana。

建立 Azure 監視器資源

#Set an environment variable for the Grafana name. Make sure to replace the placeholder with your own value.
export AZURE_MONITOR_NAME="<azure-monitor-name>"

# Create Azure monitor resource
az resource create \
    --resource-group $RESOURCE_GROUP \
    --namespace microsoft.monitor \
    --resource-type accounts \
    --name $AZURE_MONITOR_NAME \
    --location eastus \
    --properties '{}'

建立 Grafana 實例

使用 az grafana create 建立 Grafana 執行個體。 Grafana 執行個體的名稱必須是唯一的。

# Set an environment variable for the Grafana name. Make sure to replace the placeholder with your own value.
export GRAFANA_NAME="<grafana-name>"

# Create Grafana instance
az grafana create \
    --name $GRAFANA_NAME \
    --resource-group $RESOURCE_GROUP 

將 Grafana 和 Azure 監視器資源識別碼放在變數中

使用 az grafana show 將 Grafana 資源識別碼放在變數中。 使用 az resource show 將 Azure 監視器資源標識碼放在變數中。 以 Grafana 執行個體名稱取代 myGrafana

grafanaId=$(az grafana show \
                --name $GRAFANA_NAME \
                --resource-group $RESOURCE_GROUP \
                --query id \
                --output tsv)
azuremonitorId=$(az resource show \
                    --resource-group $RESOURCE_GROUP \
                    --name $AZURE_MONITOR_NAME \
                    --resource-type "Microsoft.Monitor/accounts" \
                    --query id \
                    --output tsv)

使用 az aks update 將 Azure 監視器和 Grafana 資源連結至您的 AKS 叢集。

az aks update \
    --name $CLUSTER_NAME \
    --resource-group $RESOURCE_GROUP \
    --enable-azure-monitor-metrics \
    --azure-monitor-workspace-resource-id $azuremonitorId \
    --grafana-resource-id $grafanaId

使用 Grafana 的視覺效果

注意

由於大規模叢集會有高計量基數,系統預設不會擷取 hubble_flows_processed_total 計量。 因此,「Pod 流向」儀表板會有遺漏資料的面板。 若要改變此情況,您可以修改 ama 計量設定,以在計量保留清單中納入 hubble_flows_processed_total。 若要了解如何執行此操作,請參閱最低擷取文件

  1. 使用 kubectl get pods 命令確定 Azure 監視器 Pod 正在執行。

    kubectl get pods -o wide -n kube-system | grep ama-
    

    您的輸出看起來應類似下列的範例輸出:

    ama-metrics-5bc6c6d948-zkgc9          2/2     Running   0 (21h ago)   26h
    ama-metrics-ksm-556d86b5dc-2ndkv      1/1     Running   0 (26h ago)   26h
    ama-metrics-node-lbwcj                2/2     Running   0 (21h ago)   26h
    ama-metrics-node-rzkzn                2/2     Running   0 (21h ago)   26h
    ama-metrics-win-node-gqnkw            2/2     Running   0 (26h ago)   26h
    ama-metrics-win-node-tkrm8            2/2     Running   0 (26h ago)   26h
    
  2. 我們已建立範例儀表板。 您可以在 [儀表板] > [Azure 受控 Prometheus] 資料夾下找到這些儀表板。 其名稱類似 "Kubernetes / Networking / <name>"。 儀表板套件中包含:

    • 叢集:顯示叢集的節點層級計量。
    • DNS (叢集):顯示叢集或所選節點上的 DNS 計量。
    • DNS (工作負載):顯示指定工作負載的 DNS 計量 (例如 DaemonSet 或部署的 Pod,像是 CoreDNS)。
    • 置放 (工作負載):顯示指定工作負載為目的地/來源的置放 (例如部署或 DaemonSet 的 Pod)。
    • Pod 流向 (命名空間):顯示流入/流出指定命名空間的 L4/L7 封包 (即命名空間中的 Pod)。
    • Pod 流向 (工作負載):顯示流入/流出指定工作負載的 L4/L7 封包 (例如部署或 DaemonSet 的 Pod)。

注意

  • Cilium 資料平面目前不支援 DNS 計量/儀表板。

安裝 Hubble CLI

安裝 Hubble CLI,以使用下列命令存取其收集的資料:

# Set environment variables
export HUBBLE_VERSION=v0.11.0
export HUBBLE_ARCH=amd64

#Install Hubble CLI
if [ "$(uname -m)" = "aarch64" ]; then HUBBLE_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}
sha256sum --check hubble-linux-${HUBBLE_ARCH}.tar.gz.sha256sum
sudo tar xzvfC hubble-linux-${HUBBLE_ARCH}.tar.gz /usr/local/bin
rm hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}

將 Hubble 流向視覺化

  1. 使用 kubectl get pods 命令確定 Hubble Pod 正在執行。

    kubectl get pods -o wide -n kube-system -l k8s-app=hubble-relay
    

    您的輸出看起來應類似下列的範例輸出:

    hubble-relay-7ddd887cdb-h6khj     1/1  Running     0       23h 
    
  2. 使用 kubectl port-forward 命令來以連接埠轉送 Hubble 轉送。

    kubectl port-forward -n kube-system svc/hubble-relay --address 127.0.0.1 4245:443
    
  3. 相互 TLS (mTLS) 可確保 Hubble 轉送伺服器的安全性。 若要讓 Hubble 用戶端擷取流向,您需要取得適當的憑證,並使用這些憑證設定用戶端。 使用下列命令套用憑證:

    #!/usr/bin/env bash
    
    set -euo pipefail
    set -x
    
    # Directory where certificates will be stored
    CERT_DIR="$(pwd)/.certs"
    mkdir -p "$CERT_DIR"
    
    declare -A CERT_FILES=(
      ["tls.crt"]="tls-client-cert-file"
      ["tls.key"]="tls-client-key-file"
      ["ca.crt"]="tls-ca-cert-files"
    )
    
    for FILE in "${!CERT_FILES[@]}"; do
      KEY="${CERT_FILES[$FILE]}"
      JSONPATH="{.data['${FILE//./\\.}']}"
    
      # Retrieve the secret and decode it
      kubectl get secret hubble-relay-client-certs -n kube-system \
        -o jsonpath="${JSONPATH}" | \
        base64 -d > "$CERT_DIR/$FILE"
    
      # Set the appropriate hubble CLI config
      hubble config set "$KEY" "$CERT_DIR/$FILE"
    done
    
    hubble config set tls true
    hubble config set tls-server-name instance.hubble-relay.cilium.io
    
  4. 使用下列 kubectl get secrets 命令確認已產生秘密:

    kubectl get secrets -n kube-system | grep hubble-
    

    您的輸出看起來應類似下列的範例輸出:

    kube-system     hubble-relay-client-certs     kubernetes.io/tls     3     9d
    
    kube-system     hubble-relay-server-certs     kubernetes.io/tls     3     9d
    
    kube-system     hubble-server-certs           kubernetes.io/tls     3     9d    
    
  5. 使用 hubble relay service 命令確定 Hubble 轉送 Pod 正在執行。

    hubble relay service 
    

使用 Hubble UI 進行視覺化

  1. 若要使用 Hubble UI,請將下列內容儲存至 hubble-ui.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: hubble-ui
      namespace: kube-system
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: hubble-ui
      labels:
        app.kubernetes.io/part-of: retina
    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
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: hubble-ui
      labels:
        app.kubernetes.io/part-of: retina
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: hubble-ui
    subjects:
      - kind: ServiceAccount
        name: hubble-ui
        namespace: kube-system
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: hubble-ui-nginx
      namespace: kube-system
    data:
      nginx.conf: |
        server {
            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 / {
                    try_files $uri $uri/ /index.html /index.html;
                }
                # Liveness probe
                location /healthz {
                    access_log off;
                    add_header Content-Type text/plain;
                    return 200 'ok';
                }
            }
        }
    ---
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: hubble-ui
      namespace: kube-system
      labels:
        k8s-app: hubble-ui
        app.kubernetes.io/name: hubble-ui
        app.kubernetes.io/part-of: retina
    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: retina
        spec:
          serviceAccount: hibble-ui
          serviceAccountName: hubble-ui
          automountServiceAccountToken: true
          containers:
          - name: frontend
            image: mcr.microsoft.com/oss/cilium/hubble-ui:v0.12.2   
            imagePullPolicy: Always
            ports:
            - name: http
              containerPort: 8081
            livenessProbe:
              httpGet:
                path: /healthz
                port: 8081
            readinessProbe:
              httpGet:
                path: /
                port: 8081
            resources: {}
            volumeMounts:
            - name: hubble-ui-nginx-conf
              mountPath: /etc/nginx/conf.d/default.conf
              subPath: nginx.conf
            - name: tmp-dir
              mountPath: /tmp
            terminationMessagePolicy: FallbackToLogsOnError
            securityContext: {}
          - name: backend
            image: mcr.microsoft.com/oss/cilium/hubble-ui-backend:v0.12.2
            imagePullPolicy: Always
            env:
            - name: EVENTS_SERVER_PORT
              value: "8090"
            - name: FLOWS_API_ADDR
              value: "hubble-relay:443"
            - name: TLS_TO_RELAY_ENABLED
              value: "true"
            - name: TLS_RELAY_SERVER_NAME
              value: ui.hubble-relay.cilium.io
            - 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
            livenessProbe:
              httpGet:
                path: /healthz
                port: 8090
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8090
            ports:
            - name: grpc
              containerPort: 8090
            resources: {}
            volumeMounts:
            - name: hubble-ui-client-certs
              mountPath: /var/lib/hubble-ui/certs
              readOnly: true
            terminationMessagePolicy: FallbackToLogsOnError
            securityContext: {}
          nodeSelector:
            kubernetes.io/os: linux 
          volumes:
          - configMap:
              defaultMode: 420
              name: hubble-ui-nginx
            name: hubble-ui-nginx-conf
          - emptyDir: {}
            name: tmp-dir
          - name: hubble-ui-client-certs
            projected:
              defaultMode: 0400
              sources:
              - secret:
                  name: hubble-relay-client-certs
                  items:
                    - key: tls.crt
                      path: client.crt
                    - key: tls.key
                      path: client.key
                    - key: ca.crt
                      path: hubble-relay-ca.crt
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: hubble-ui
      namespace: kube-system
      labels:
        k8s-app: hubble-ui
        app.kubernetes.io/name: hubble-ui
        app.kubernetes.io/part-of: retina
    spec:
      type: ClusterIP
      selector:
        k8s-app: hubble-ui
      ports:
        - name: http
          port: 80
          targetPort: 8081
    
  2. 使用下列命令將 hubble-ui.yaml 資訊清單套用至您的叢集

    kubectl apply -f hubble-ui.yaml
    
  3. 使用 kubectl port-forward 命令設定 Hubble UI 的連接埠轉送。

    kubectl -n kube-system port-forward svc/hubble-ui 12000:80
    
  4. 在網頁瀏覽器中輸入 http://localhost:12000/ 以存取 Hubble UI。


清除資源

如果您不打算使用此應用程式,請使用 az group delete 命令刪除您在本文所建立的其他資源。

  az group delete --name $RESOURCE_GROUP

下一步

在本操作說明文章中,您已了解如何安裝和啟用 AKS 叢集的進階網路可檢視性。