Compartilhar via


Configurar a Observabilidade de Rede de Contêiner para o Serviço de Kubernetes do Azure (AKS) - Prometheus e Grafana gerenciados pelo Azure

Este artigo mostra como configurar a Observabilidade de Rede de Contêiner para o Serviço de Kubernetes do Azure (AKS) usando Prometheus e Grafana gerenciados e BYO Prometheus e Grafana e visualizar as métricas coletadas

Você pode usar a Observabilidade de Rede de Contêiner para recolher dados sobre o tráfego de rede dos seus clusters do AKS. Ele habilita uma plataforma centralizada para monitorar a integridade do aplicativo e da rede. Atualmente, as métricas são armazenadas no Prometheus e o Grafana pode ser usado para visualizá-las. A Observabilidade de Rede de Contêiner também oferece a capacidade de habilitar o Hubble. Esses recursos têm suporte para clusters Cilium e não Cilium.

A Observabilidade de Rede de Contêiner é um dos recursos dos Serviços Avançados de Rede de Contêiner. Para obter mais informações sobre os Serviços Avançados de Rede de Contêineres para o AKS (Serviço de Kubernetes do Azure), consulte O que são serviços avançados de rede de contêineres para o AKS (Serviço de Kubernetes do Azure)?.

Pré-requisitos

  • Uma conta do Azure com uma assinatura ativa. Se você não tiver uma, crie uma conta gratuita antes de começar.
  • A versão mínima da CLI do Azure necessária para as etapas neste artigo é 2.56.0. Execute az --version para encontrar a versão. Se você precisa instalar ou atualizar, consulte Instalar a CLI do Azure.

Instalar a extensão aks-preview da CLI do Azure

Instale ou atualize a extensão de visualização da CLI do Azure usando o comando az extension add ou 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

Habilitar os Serviços Avançados de Rede de Contêineres

Para continuar, você deve ter um cluster do AKS com os Serviços Avançados de Rede de Contêineres habilitados.

O comando az aks create com o sinalizador dos Serviços Avançados de Rede de Contêiner, --enable-acns, cria um cluster do AKS com todos os recursos dos Serviços Avançados de Rede de Contêiner. Esses recursos incluem:

Observação

Clusters com o plano de dados Cilium dão suporte à Observabilidade de Rede de Contêiner e a segurança de rede de contêiner a partir da versão 1.29 do Kubernetes.

# 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

Habilitar Serviços Avançados de Rede de Contêineres em um cluster existente

O comando az aks update com o sinalizador dos Serviços Avançados de Rede de Contêiner, --enable-acns, atualiza um cluster do AKS existente com todos os recursos dos Serviços Avançados de Rede de Contêiner, que inclui Observabilidade de Rede de Contêiner e o recurso Segurança de Rede de Contêiner.

Observação

Somente clusters com o plano de dados Cilium dão suporte para os recursos de Segurança de Rede de Contêiner dos Serviços Avançados de Rede de Contêiner.

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

Obter credenciais do cluster

Depois de obter suas credenciais de cluster usando o comando az aks get-credentials.

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

Prometheus e Grafana gerenciados pelo Azure

Ignore esta Seção se estiver usando BYO Prometheus e Grafana

Use o exemplo a seguir para instalar e ativar o Prometheus e o Grafana em seu cluster do AKS.

Criar um recurso do Azure Monitor

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

Criar instância do Espaço Gerenciado do Azure para Grafana

Use az grafana create para criar uma instância do Grafana. O nome da instância do Grafana deve ser exclusivo.

# 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 

Coloque as IDs de recurso do Espaço Gerenciado do Azure para Grafana e do Azure Monitor em variáveis

Use az grafana show para colocar a ID do recurso Grafana em uma variável. Use az resource show para colocar a ID do recurso Azure Monitor em uma variável. Substitua myGrafana pelo nome da sua instância do 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)

Use az aks update para vincular os recursos do Azure Monitor e do Grafana ao seu cluster do 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

Visualização

Visualização usando o Espaço Gerenciado do Azure para Grafana

Ignore esta etapa se estiver usando o BYO Grafana

Observação

A métrica de hubble_flows_processed_total não é raspada por padrão devido à alta cardinalidade métrica em clusters de grande escala. Por isso, os Fluxos de pods painéis têm painéis com dados ausentes. Para alterar isso, você pode modificar as configurações de métricas ama para incluir hubble_flows_processed_total na lista de manter a métrica. Para saber como fazer isso, consulte a Documentação de Ingestão Mínima.

  1. Verifique se os pods do Azure Monitor estão em execução usando o comando kubectl get pods.

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

    Seu resultado deve ser semelhante ao seguinte exemplo de saída:

    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. Criamos painéis de exemplo. Eles podem ser encontrados na pasta Dashboards> Prometheus Gerenciado do Azure. Eles têm nomes como "Kubernetes/Rede/<name>". O conjunto de painéis inclui:

    • Clusters: mostra métricas no nível do nó para seus clusters.
    • DNS (Cluster): mostra métricas DNS em um cluster ou seleção de nós.
    • DNS (Carga de Trabalho): mostra métricas DNS para a carga de trabalho especificada (por exemplo, pods de um DaemonSet ou implantação, como CoreDNS).
    • Drops (Carga de Trabalho): mostra quedas de/para a carga de trabalho especificada (por exemplo, pods de uma implantação ou DaemonSet).
    • Fluxos de Pod (Namespace): mostra fluxos de pacote L4/L7 de/para o namespace especificado (ou seja, Pods no Namespace).
    • Fluxos de Pod (Carga de Trabalho): mostra fluxos de pacote L4/L7 de/para a carga de trabalho especificada (por exemplo, Pods de uma Implantação ou DaemonSet).

Visualização usando o BYO Grafana

Ignore esta etapa se estiver usando o Grafana gerenciado pelo Azure

  1. Adicione o seguinte trabalho de extração à configuração existente do Prometheus e reinicie o servidor do 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. Em Destinos do prometheus, verifique se os cilium-pods estão presentes.

  3. Entre no Grafana e importe os seguintes painéis de exemplo usando as seguintes IDs:

    • Clusters: mostra métricas no nível do nó para seus clusters. (ID: 18814)
    • DNS (Cluster): mostra métricas DNS em um cluster ou seleção de nós. (ID: 20925)
    • DNS (Carga de Trabalho): mostra métricas DNS para a carga de trabalho especificada (por exemplo, pods de um DaemonSet ou implantação, como CoreDNS). (ID: [20926] https://grafana.com/grafana/dashboards/20926-kubernetes-networking-dns-workload/)
    • Drops (Carga de Trabalho): mostra quedas de/para a carga de trabalho especificada (por exemplo, pods de uma implantação ou DaemonSet). (ID: 20927).
    • Fluxos de Pod (Namespace): mostra fluxos de pacote L4/L7 de/para o namespace especificado (ou seja, Pods no Namespace). (ID: 20928)
    • Fluxos de Pod (Carga de Trabalho): mostra fluxos de pacote L4/L7 de/para a carga de trabalho especificada (por exemplo, Pods de uma Implantação ou DaemonSet). (ID: 20929)

    Observação

    • Dependendo das configurações de instâncias do Prometheus/Grafana, alguns painéis de painel podem exigir ajustes para exibir todos os dados.
    • Atualmente, o Cilium não dá suporte a métricas/dashboards de DNS.

Instalar a CLI do Hubble

Instale a CLI do Hubble para acessar os dados coletados usando os seguintes comandos:

# Set environment variables
export HUBBLE_VERSION=v1.16.3
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}

Visualizar os fluxos do Hubble

  1. Verifique se os pods do Hubble estão em execução usando o comando kubectl get pods.

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

    Seu resultado deve ser semelhante ao seguinte exemplo de saída:

    hubble-relay-7ddd887cdb-h6khj     1/1  Running     0       23h 
    
  2. Encaminhar a retransmissão do Hubble usando o comando kubectl port-forward.

    kubectl port-forward -n kube-system svc/hubble-relay --address 127.0.0.1 4245:443
    
  3. O TLS mútuo (mTLS) garante a segurança do servidor de Retransmissão do Hubble. Para permitir que o cliente Hubble recupere fluxos, você precisa obter os certificados apropriados e configurar o cliente com eles. Aplique os certificados usando os seguintes comandos:

    #!/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. Verifique se os segredos foram gerados usando o seguinte comando kubectl get secrets:

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

    Seu resultado deve ser semelhante ao seguinte exemplo de saída:

    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. Verifique se o pod de Retransmissão do Hubble está em execução usando o comando hubble observe.

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

Visualizar usando a interface do usuário do Hubble

  1. Para usar a interface do usuário do Hubble, salve o seguinte em 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:
          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. Aplique o manifesto hubble-ui.yaml ao cluster usando o comando a seguir

    kubectl apply -f hubble-ui.yaml
    
  3. Configure o encaminhamento de porta para a interface do usuário do Hubble usando o comando kubectl port-forward.

    kubectl -n kube-system port-forward svc/hubble-ui 12000:80
    
  4. Acesse a interface do usuário do Hubble inserindo http://localhost:12000/ no navegador da Web.


Limpar os recursos

Se você não planeja usar esse aplicativo, exclua os outros recursos criados neste artigo usando o comando az group delete.

  az group delete --name $RESOURCE_GROUP

Próximas etapas

Nesse artigo de instruções, você aprendeu como instalar e habilitar a Observabilidade de Rede de Contêiner para o seu cluster do AKS.