Configurare Container Network Observability for servizio Azure Kubernetes (AKS) - Azure managed Prometheus e Grafana

Questo articolo illustra come configurare Container Network Observability for servizio Azure Kubernetes (AKS) usando Managed Prometheus e Grafana e BYO Prometheus e Grafana e per visualizzare le metriche raschiate

È possibile usare Container Network Observability per raccogliere dati sul traffico di rete dei cluster del servizio Azure Kubernetes. Questa funzionalità offre una piattaforma centralizzata per il monitoraggio dell'integrità delle applicazioni e della rete. Attualmente, le metriche vengono archiviate in Prometheus e Grafana può essere usato per visualizzarle. Container Network Observability offre anche la possibilità di abilitare Hubble. Queste funzionalità sono supportate sia per i cluster Cilium che per quelli non Cilium.

Container Network Observability è una delle funzionalità di Advanced Container Networking Services. Per altre informazioni sui servizi avanzati di rete per contenitori per il servizio Azure Kubernetes, vedere Che cosa sono i servizi avanzati di rete per contenitori per il servizio Azure Kubernetes?.

Prerequisiti

  • La versione minima dell'interfaccia della riga di comando di Azure necessaria per i passaggi descritti in questo articolo è 2.56.0. Eseguire az --version per trovare la versione. Se è necessario eseguire l'installazione o l'aggiornamento, vedere Installare l'interfaccia della riga di comando di Azure.

Installare l'estensione dell'interfaccia della riga di comando di Azure aks-preview

Installare o aggiornare l'estensione di anteprima dell'interfaccia della riga di comando di Azure usando i comandi az extension add o az extension update.

# 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

Abilitare Advanced Container Networking Services

Per continuare, è necessario disporre di un cluster del servizio Azure Kubernetes con Servizi di rete dei contenitori avanzati abilitati.

Il az aks create comando con il flag Advanced Container Networking Services, --enable-acns, crea un nuovo cluster del servizio Azure Kubernetes con tutte le funzionalità di Advanced Container Networking Services. Queste funzionalità includono:

Nota

I cluster con il piano dati Cilium supportano la sicurezza container Network Observability and Container Network a partire da Kubernetes versione 1.29.

# 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 \
    --location eastus \
    --max-pods 250 \
    --network-plugin azure \
    --network-plugin-mode overlay \
    --network-dataplane cilium \
    --node-count 2 \
    --pod-cidr 192.168.0.0/16 \
    --kubernetes-version 1.29 \
    --enable-acns

Abilitare Advanced Container Networking Services in un cluster esistente

Il az aks update comando con il flag Advanced Container Networking Services, --enable-acns, aggiorna un cluster del servizio Azure Kubernetes esistente con tutte le funzionalità di Advanced Container Networking Services che includono l'osservabilità della rete dei contenitori e la funzionalità Sicurezza di rete dei contenitori.

Nota

Solo i cluster con il piano dati Cilium supportano le funzionalità di sicurezza di rete dei contenitori di Advanced Container Networking Services.

az aks update \
    --resource-group $RESOURCE_GROUP \
    --name $CLUSTER_NAME \
    --enable-acns

Ottenere le credenziali del cluster

Dopo aver ottenuto le credenziali del cluster usando il az aks get-credentials comando .

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

Prometheus gestito di Azure e Grafana

Ignorare questa sezione se si usa BYO Prometheus e Grafana

Usare l'esempio seguente per installare e abilitare Prometheus e Grafana per il cluster del servizio Azure Kubernetes.

Creare una risorsa di Monitoraggio di 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 '{}'

Creare un'istanza di Grafana gestita di Azure

Usare az grafana create per creare un'istanza di Grafana. Il nome dell'istanza di Grafana deve essere univoco.

# 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 

Inserire gli ID risorsa Grafana e Monitoraggio di Azure nelle variabili

Usare az grafana show per inserire l'ID risorsa Grafana in una variabile. Usare az resource show per inserire l'ID risorsa di Monitoraggio di Azure in una variabile. Sostituire myGrafana con il nome dell'istanza di Grafana.

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)

Usare az aks update per collegare le risorse di Monitoraggio di Azure e Grafana al cluster del servizio Azure Kubernetes.

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

Visualizzazione

Visualizzazione con Grafana gestita di Azure

Ignorare questo passaggio se si usa BYO Grafana

Nota

La metrica hubble_flows_processed_total non viene raschiata per impostazione predefinita a causa dell'elevata cardinalità delle metriche nei cluster su larga scala. Per questo motivo, i dashboard dei flussi di pod dispongono di pannelli con dati mancanti. Per cambiare questo parametro, è possibile modificare le impostazioni delle metriche ama in modo da includerle hubble_flows_processed_total nell'elenco di mantenimento delle metriche. Per informazioni su come eseguire questa operazione, vedere la Documentazione sull’inserimento minimo.

  1. Assicurarsi che i pod di Monitoraggio di Azure siano in esecuzione usando il comando kubectl get pods.

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

    L'output dovrebbe essere simile all'esempio di output seguente:

    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. Sono stati creati dashboard di esempio, che sono disponibili nella cartella Dashboard> di Prometheus gestito da Azure. I nomi di tali dashboard sono, ad esempio "Kubernetes/Networking/ <name>". La suite di dashboard include:

    • Cluster: mostra le metriche a livello di nodo per i cluster.
    • DNS (cluster): mostra le metriche DNS in un cluster o in una selezione di nodi.
    • DNS (carico di lavoro): mostra le metriche DNS per il carico di lavoro specificato (ad esempio, i pod di un DaemonSet o una distribuzione, ad esempio CoreDNS).
    • Drop (carico di lavoro): mostra i drop da/verso il carico di lavoro specificato, ad esempio i pod di un oggetto Deployment o DaemonSet.
    • Flussi pod (spazio dei nomi): mostra i flussi di pacchetti L4/L7 da/verso lo spazio dei nomi specificato, ad esempio i pod nello spazio dei nomi.
    • Flussi pod (carico di lavoro): mostra i flussi di pacchetti L4/L7 da/verso il carico di lavoro specificato, ad esempio i pod di un oggetto Deployment o DaemonSet.

Visualizzazione con BYO Grafana

Ignorare questo passaggio se si usa Grafana gestito di Azure

  1. Aggiungere il processo di scrape (scorporamento) seguente alla configurazione prometheus esistente e riavviare il server Prometheus:

    - job_name: networkobservability-hubble
      kubernetes_sd_configs:
        - role: pod
      relabel_configs:
        - target_label: cluster
          replacement: myAKSCluster
          action: replace
        - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_pod_label_k8s_app]
          regex: kube-system;(retina|cilium)
          action: keep
        - source_labels: [__address__]
          action: replace
          regex: ([^:]+)(?::\d+)?
          replacement: $1:9965
          target_label: __address__
        - source_labels: [__meta_kubernetes_pod_node_name]
          target_label: instance
          action: replace
      metric_relabel_configs:
        - source_labels: [__name__]
          regex: '|hubble_dns_queries_total|hubble_dns_responses_total|hubble_drop_total|hubble_tcp_flags_total' # if desired, add |hubble_flows_processed_total
          action: keep
    
  2. In Destinazioni di Prometheus verificare che i network-obs-pods siano presenti.

  3. Accedere a Grafana e importare i seguenti dashboard di esempio usando gli ID riportati:

    • Cluster: mostra le metriche a livello di nodo per i cluster. (ID: 18814)
    • DNS (cluster): mostra le metriche DNS in un cluster o la selezione di nodi. (ID: 20925)
    • DNS (carico di lavoro): mostra le metriche DNS per il carico di lavoro specificato, ad esempio pod di un DaemonSet o distribuzione, come CoreDNS. (ID: [20926] https://grafana.com/grafana/dashboards/20926-kubernetes-networking-dns-workload/)
    • Elimina (carico di lavoro): mostra le eliminazioni dal carico di lavoro specificato, ad esempio pod di una distribuzione o DaemonSet.(ID: 20927).
    • Flussi pod (spazio dei nomi): mostra i flussi di pacchetti L4/L7 verso/da lo spazio dei nomi specificato, ad esempio pod nello spazio dei nomi. (ID: 20928)
    • Flussi pod (carico di lavoro): mostra i flussi di pacchetti L4/L7 verso/da il carico di lavoro specificato, ad esempio pod di una distribuzione o DaemonSet.(ID: 20929)

    Nota

    • A seconda delle impostazioni delle istanze di Prometheus/Grafana, alcuni pannelli del dashboard potrebbero richiedere modifiche per visualizzare tutti i dati.
    • Cilium attualmente non supporta metriche/dashboard DNS.

Installare l'interfaccia della riga di comando di Hubble

Installare l'interfaccia della riga di comando di Hubble per accedere ai dati raccolti usando i comandi seguenti:

# 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}

Visualizzare i flussi di Hubble

  1. Assicurarsi che i pod di Hubble siano in esecuzione usando il comando kubectl get pods.

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

    L'output dovrebbe essere simile all'esempio di output seguente:

    hubble-relay-7ddd887cdb-h6khj     1/1  Running     0       23h 
    
  2. Configurare il port-forwarding nell’Inoltro di Hubble tramite il comando kubectl port-forward.

    kubectl port-forward -n kube-system svc/hubble-relay --address 127.0.0.1 4245:443
    
  3. Il protocollo TLS reciproco (mTLS) garantisce la sicurezza del server dell’Inoltro di Hubble. Per consentire al client Hubble di recuperare i flussi, è necessario ottenere i certificati appropriati e configurare il client con essi. Applicare i certificati usando i comandi seguenti:

    #!/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. Verificare che i segreti siano stati generati usando il comando kubectl get secrets seguente:

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

    L'output dovrebbe essere simile all'esempio di output seguente:

    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. Assicurarsi che il pod dell’Inoltro di Hubble sia in esecuzione usando il comando hubble observe.

    hubble observe --pod hubble-relay-7ddd887cdb-h6khj
    

Visualizzare tramite l'interfaccia utente di Hubble

  1. Per usare l'interfaccia utente di Hubble, salvare il codice seguente in 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. Applicare il manifesto hubble-ui.yaml al cluster usando il comando seguente

    kubectl apply -f hubble-ui.yaml
    
  3. Configurare il port forwarding per l'interfaccia utente di Hubble usando il comando kubectl port-forward.

    kubectl -n kube-system port-forward svc/hubble-ui 12000:80
    
  4. Accedere all'interfaccia utente di Hubble immettendo http://localhost:12000/ nel Web browser.


Pulire le risorse

Se non si prevede di usare questa applicazione, eliminare le altre risorse create in questo articolo usando il comando az group delete.

  az group delete --name $RESOURCE_GROUP

Passaggi successivi

In questo articolo di procedura si è appreso come installare e abilitare l'osservabilità della rete dei contenitori per il cluster del servizio Azure Kubernetes.