你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用高级容器网络服务设置容器网络日志(预览版)

本文将完成配置和使用 Azure Kubernetes 服务高级容器网络服务(AKS)中的容器网络日志功能的步骤。 这些日志提供专为增强容器化环境中的可见性而定制的持久网络流监视。

通过捕获容器网络日志,可以有效地跟踪网络流量、检测异常、优化性能并确保符合已建立的策略。 按照提供的详细说明为系统设置和集成容器网络日志。 有关容器网络日志功能的详细信息,请参阅 容器网络日志概述

先决条件

  • 拥有有效订阅的 Azure 帐户。 如果没有帐户,请在开始之前创建 一个免费帐户
  • 完成本文中的步骤所需的最低 Azure CLI 版本为 2.73.0。 若要查找版本,请在 Azure CLI 中运行 az --version 。 若要安装或升级,请参阅安装 Azure CLI

  • 存储日志模式下的容器网络日志仅适用于 Cilium 数据平面。

  • 按需模式下的容器网络日志可在 Cilium 及非 Cilium 数据平面中使用。

  • 如果现有群集为 <= 1.32,请将群集升级到最新的可用 Kubernetes 版本。

  • 完成本文步骤所需的最低版本 Azure CLI 扩展是 aks-preview

安装 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

为容器网络日志配置存储日志模式

注册 AdvancedNetworkingFlowLogsPreview 功能标志

首先,使用 az feature register 以下命令注册 AdvancedNetworkingFlowLogsPreview 功能标志:

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

使用 az feature show 命令验证注册是否成功。 注册需要几分钟才能完成。

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

当功能显示“已注册”时,使用Microsoft.ContainerService命令刷新资源提供程序的az provider register注册。

局限性

  • 仅当启用第 7 层策略支持时,才会捕获第 7 层流数据。 有关详细信息,请参阅 配置第 7 层策略
  • 仅当应用 Cilium 完全限定域(FQDN)网络策略时,才会捕获域名系统(DNS)流和相关指标。 有关详细信息,请参阅 配置 FQDN 策略
  • 在预览期间,只能通过 Azure CLI 和 Azure 资源管理器模板(ARM 模板)配置此功能。 目前不支持使用 Terraform 加入。
  • 如果未为日志存储配置 Log Analytics,容器网络日志将限制为最多 50 MB 的存储。 达到此限制后,新条目将覆盖旧日志。
  • 如果日志表计划设置为基本日志,则预生成的 Grafana 仪表板无法按预期工作。
  • 不支持辅助日志表计划。

在新群集上启用高级容器网络服务

使用 az aks create 命令和 --enable-acns 参数来创建一个具有所有高级容器网络服务功能的新 AKS 集群。 这些功能包括:

  • 容器网络可观测性: 提供有关网络流量的见解。 若要了解详细信息,请参阅 容器网络可观测性

  • 容器网络安全:提供 FQDN 筛选等安全功能。 若要了解详细信息,请参阅 容器网络安全

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

# Create an AKS cluster
az aks create \
    --name $CLUSTER_NAME \
    --resource-group $RESOURCE_GROUP \
    --generate-ssh-keys \
    --location uksouth \
    --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.32 \
    --enable-acns

配置用于日志筛选的自定义资源

若要在存储日志模式下配置容器网络日志,必须定义特定的自定义资源,以便为日志收集设置筛选器。 定义至少一个自定义资源时,日志将收集并存储在主机节点上 /var/log/acns/hubble/events.log

若要配置日志记录,必须定义并应用 RetinaNetworkFlowLog 自定义资源的类型。 设置命名空间、Pod、服务、端口、协议和裁定等筛选器。 多个自定义资源可以同时存在于群集中。 如果未使用无空筛选器定义任何自定义资源,则不会在指定位置保存任何日志。

以下示例定义演示如何配置 RetinaNetworkFlowLog 自定义资源的类型。

RetinaNetworkFlowLog 模板

apiVersion: acn.azure.com/v1alpha1
kind: RetinaNetworkFlowLog
metadata:
  name: sample-retinanetworkflowlog # Cluster scoped
spec:
  includefilters: # List of filters
    - name: sample-filter # Filter name
      from:
        namespacedPod: # List of source namespace/pods. Prepend namespace with /
          - sample-namespace/sample-pod
        labelSelector: # Standard k8s label selector
          matchLabels:
            app: frontend
            k8s.io/namespace: sample-namespace
          matchExpressions:
            - key: environment
              operator: In
              values:
                - production
                - staging
        ip: # List of source IPs; can be CIDR
          - "192.168.1.10"
          - "10.0.0.1"
      to:
        namespacedPod:
          - sample-namespace2/sample-pod2
        labelSelector:
          matchLabels:
            app: backend
            k8s.io/namespace: sample-namespace2
          matchExpressions:
            - key: tier
              operator: NotIn
              values:
                - dev
        ip:
          - "192.168.1.20"
          - "10.0.1.1"
      protocol: # List of protocols; can be tcp, udp, dns
        - tcp
        - udp
        - dns
      verdict: # List of verdicts; can be forwarded, dropped
        - forwarded
        - dropped

下表描述了自定义资源定义中的字段:

字段 类型 DESCRIPTION 必选
includefilters []过滤器 定义要包含的网络流的筛选器列表。 每个筛选器指定源、目标、协议和其他匹配条件。 Include 筛选器不能为空,必须至少有一个筛选器。 强制的
filters.name 字符串 筛选器的名称。 可选
filters.protocol []字符串 要与此过滤器匹配的协议。 有效值为:tcpudpdns。 因为它是一个可选参数,如果未指定,则包含所有协议的日志。 可选
filters.verdict []字符串 要匹配的流的裁定。 有效值为 forwardeddropped。 如果未指定,因为它是一个可选参数,则日志将包含所有结果。 可选
filters.from 端点 指定网络流的源。 可以包括 IP 地址、标签选择器和命名空间/Pod 对。 可选
Endpoint.ip []字符串 它可以是单个 IP 或 CIDR。 可选
Endpoint.labelSelector 物体 标签选择器是一种基于标签筛选和查询资源的机制,因此可以识别特定的资源子集。 标签选择器可以包括两个组件: matchLabelsmatchExpressions。 使用matchLabels通过指定一个键/值对(例如{"app": "frontend"})进行简单匹配。 对于更高级的条件,请使用 matchExpressions,其中定义标签键、运算符(如 InNotInExistsDoesNotExist),以及可选的值列表。 确保 matchLabelsmatchExpressions 这两个条件同时满足,因为它们通过 AND 逻辑组合在一起。 如果未指定任何条件,选择器将匹配所有资源。 若要匹配无,请将选择器保留为空。 请仔细定义标签选择器,以定位正确的资源集。 可选
Endpoint.namespacedPod []字符串 用于匹配源的命名空间和 Pod 对的列表(格式为 namespace/pod)。 name 应与正则表达式模式 ^.+$匹配。 可选
filters.to 端点 指定网络流的目标。 可以包括 IP 地址、标签选择器或命名空间/Pod 对。 可选
Endpoint.ip []字符串 它可以是单个 IP 或 CIDR。 可选
Endpoint.labelSelector 物体 标签选择器,用于根据资源标签匹配资源。 可选
Endpoint.namespacedPod []字符串 命名空间和 Pod 对的列表(格式设置为 namespace/pod)以匹配目标。 可选
  • RetinaNetworkFlowLog应用自定义资源以在群集上启用日志收集:

    kubectl apply -f <crd.yaml>
    

本地存储在主机节点上的日志是临时的,因为主机或节点本身不是永久性存储解决方案。 此外,当主机节点上的日志大小达到 50 MB 时会轮换。 对于长期存储和分析,我们建议在群集上配置 Azure Monitor 代理,以便在 Log Analytics 工作区中收集和保留日志。

或者,可以集成合作伙伴日志记录服务(如 OpenTelemetry 收集器)以获取更多日志管理选项。

配置 Azure Monitor 代理以在 Log Analytics 工作区中抓取日志,用于新的群集(位于托管存储中)

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

# Enable azure monitor with high log scale mode
    ### To use the default Log Analytics workspace
    az aks enable-addons -a monitoring --enable-high-log-scale-mode -g $RESOURCE_GROUP -n $CLUSTER_NAME

    ### To use an existing Log Analytics workspace
    az aks enable-addons -a monitoring --enable-high-log-scale-mode -g $RESOURCE_GROUP -n $CLUSTER_NAME --workspace-resource-id <workspace-resource-id>

# Update the AKS cluster with the enable-retina-flow-logs flag
  az aks update --enable-acns \
    --enable-retina-flow-logs \
    -g $RESOURCE_GROUP \
    -n $CLUSTER_NAME

注释

启用后,当应用自定义资源/var/log/acns/hubble/events.log时,容器网络流日志将写入RetinaNetworkFlowLog。 如果稍后启用了 Log Analytics 集成,Azure Monitor 代理将开始收集该点的日志。 超过两分钟的旧日志不会被引入。 只有在开始监视后新增的条目会被收集到 Log Analytics 工作区中。

配置现有群集以将日志存储在 Log Analytics 工作区中

若要在现有群集上启用容器网络日志,请执行以下作:

  1. 检查是否已在该群集上启用监视加载项:

     az aks addon list -g $RESOURCE_GROUP -n $CLUSTER_NAME
    
  2. 如果启用了监视加载项,请禁用监视加载项:

     az aks disable-addons -a monitoring -g $RESOURCE_GROUP -n $CLUSTER_NAME
    

    完成此步骤是因为可能已启用监视加载项,但无法实现大规模监视。 有关详细信息,请参阅 “大规模”模式

  3. 将 Azure Monitor 设置为 enable-high-log-scale-mode

     ### Use default Log Analytics workspace
     az aks enable-addons -a monitoring --enable-high-log-scale-mode -g $RESOURCE_GROUP -n $CLUSTER_NAME 
     ### Use existing Log Analytics workspace
     az aks enable-addons -a monitoring --enable-high-log-scale-mode -g $RESOURCE_GROUP -n $CLUSTER_NAME --workspace-resource-id <workspace-resource-id>
    
  4. 使用 enable-retina-flow-logs 标志更新 AKS 群集:

     az aks update --enable-acns \
         --enable-retina-flow-logs \
         -g $RESOURCE_GROUP \
         -n $CLUSTER_NAME
    

获取群集凭据

使用 az aks get-credentials 以下命令获取群集凭据:

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

验证设置

验证是否已启用 retina 网络流日志功能:

   az aks show -g $RESOURCE_GROUP -n $CLUSTER_NAME

预期输出:

"networkProfile":{
 "advancedNetworking": {
  "enabled": true,
  "observability":{
    "enabled": true
     }
 }
}
----------------------------
"osmagent":{
 "config":{
  "enableRetinaNetworkFlags": "True"
 }
}

RetinaNetworkFlowLog验证是否已应用自定义资源:

   kubectl describe retinanetworkflowlogs <cr-name>

预计会看到一个包含Spec节点和Include filters节点的Status节点。 其Status>State值应为CONFIGURED(而不是)。FAILED

Spec:
  Includefilters:
    From:
      Namespaced Pod:
        namespace/pod-
    Name:  sample-filter
    Protocol:
      tcp
    To:
      Namespaced Pod:
        namespace/pod-
    Verdict:
      dropped
Status:
  State:      CONFIGURED
  Timestamp:  2025-05-01T11:24:48Z

Azure 托管 Grafana

如果没有现有的 Azure 托管 Grafana 实例,则必须创建一个实例来可视化预先生成的网络流日志仪表板。

创建 Azure 托管 Grafana 实例

使用 az grafana create 创建托管 Grafana 实例。 实例的名称必须唯一。

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

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

确保 Managed Grafana 工作区能够访问并搜索相关订阅中的所有监控数据。 若要访问网络流日志的预生成仪表板,需要执行此步骤。

用例 1:如果你是订阅所有者或用户访问管理员,则创建托管 Grafana 工作区时,它附带对订阅中所有 Azure Monitor 数据和 Log Analytics 资源授予的“监视读取者”角色。 新的托管 Grafana 工作区可以访问和搜索订阅中的所有监视数据。 它可以查看所有资源的 Azure Monitor 指标和日志,并查看订阅中 Log Analytics 工作区中存储的任何日志。

用例 2:如果你不是订阅所有者或用户访问管理员,或者 Log Analytics 和托管 Garfana 工作区位于不同的订阅中,Grafana 无法访问 Log Analytics 和订阅。 Grafana 工作区必须在相关订阅中具有监视读取者角色才能访问预生成的 Grafana 仪表板。 在此方案中,请完成以下步骤以提供访问权限:

  1. 在托管 Grafana 工作区中,转到 “设置>身份”。

    托管 Grafana 实例中身份选项的屏幕截图。

  2. 选择 “Azure 角色分配>添加角色分配”。

    在 Grafana 实例中选择 Azure 角色分配的屏幕截图。

  3. 范围 中输入 订阅。 选择订阅。 将 角色 设置为 “监视读取者”,然后选择“ 保存”。

    在托管 Grafana 实例中输入订阅详细信息的屏幕截图。

  4. 验证托管 Grafana 实例的数据源。 若要验证 Grafana 仪表板数据源的订阅,请检查托管 Grafana 实例中的 “数据源 ”选项卡:

    在托管 Grafana 实例中检查数据源的屏幕截图。

Grafana 仪表板中的可视化效果

可以使用两个预生成的 Grafana 仪表板可视化容器网络流日志进行分析。 可以通过 Azure 托管 Grafana 或在 Azure 门户中访问仪表板。

使用 Azure 托管 Grafana 进行数据可视化

  1. 确保 Azure 日志 Pod 正在运行:

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

    输出应类似于以下示例:

    ama-logs-9bxc6                                   3/3     Running   1 (39m ago)   44m
    ama-logs-fd568                                   3/3     Running   1 (40m ago)   44m
    ama-logs-rs-65bdd98f75-hqnd2                     2/2     Running   1 (43m ago)   22h
    
    
  2. 为了简化日志分析,我们提供了预配置的两个 Azure 托管 Grafana 仪表板:

    • 转到 Azure>Insights>容器>网络>流日志。 此仪表板提供 AKS 工作负载相互通信的可视化效果,包括网络请求、响应、删除和错误。 目前,必须使用 ID 23155 导入这些仪表板。

      托管 Grafana 实例中的流日志 Grafana 仪表板的屏幕截图。

    • 转到 Azure>Insights>容器>网络>流日志(外部流量)。 此仪表板提供 AKS 工作负载从 AKS 群集外部发送和接收通信(包括网络请求、响应、删除和错误)的可视化效果。 使用 ID 23156

    托管 Grafana 实例中流日志(外部)Grafana 仪表板的屏幕截图。

有关如何使用此仪表板的详细信息,请参阅 容器网络日志概述

Azure 门户中容器网络日志的可视化

可以在 Azure 门户中可视化、查询和分析流日志。 转到群集的 Log Analytics 工作区:

Log Analytics 中容器网络日志的屏幕截图。

配置按需日志模式

网络流的按需日志模式适用于 Cilium 和非 Cilium 数据平面。

若要继续,必须有一个启用了高级容器网络服务的 AKS 群集。

具有高级容器网络服务标志 az aks create--enable-acns 命令创建一个新的 AKS 群集,它具有所有高级容器网络服务功能。 这些功能包括:

  • 容器网络可观测性:提供对您的网络流量的深入见解。 若要了解详细信息,请访问容器网络可观测性

  • 容器网络安全:提供 FQDN 筛选等安全功能。 若要了解详细信息,请访问容器网络安全

注释

具有 Cilium 数据平面的群集支持 Kubernetes 版本 1.29 及更高版本中的容器网络可观测性和容器网络安全功能。

# Set an environment variable for the AKS cluster name. Make sure you 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

在现有群集上启用高级容器网络服务

az aks update 命令与 --enable-acns 标志一起更新现有 AKS 群集,包含所有高级容器网络服务的功能。 这些功能包括容器网络可观测性和容器网络安全

注释

只有具有 Cilium 数据平面的群集才支持高级容器网络服务的容器网络安全功能。

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

接下来,使用 az aks get-credentials 以下命令获取群集凭据:

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

安装 Hubble CLI

安装 Hubble CLI 以访问它收集的数据。 运行以下命令:

# Set environment variables
export HUBBLE_VERSION=v1.16.3
export HUBBLE_ARCH=amd64

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

可视化哈勃流动

  1. 确保 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. 将 Hubble 中继服务器的端口转发:

    kubectl port-forward -n kube-system svc/hubble-relay --address 127.0.0.1 4245:443
    
  3. 使用双向 TLS (mTLS) 确保 Hubble Relay 服务器的安全。 若要使 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 -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 Pod 是否正在运行:

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

使用 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:
          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. 为 Hubble UI 设置端口转发:

    kubectl -n kube-system port-forward svc/hubble-ui 12000:80
    
  4. 在 Web 浏览器中,输入 http://localhost:12000/ 以访问 Hubble UI。

基本故障排除

  • 高级容器网络服务是启用 Azure Monitor 代理日志收集功能的先决条件。

    尝试在群集上启用容器网络流日志功能而不启用高级容器网络服务,例如:

    az aks update -g test-rg -n test-cluster --enable-retina-flow-logs

    产生错误消息:

    Flow logs requires '--enable-acns', advanced networking to be enabled, and the monitoring addon to be enabled.

  • 如果群集 Kubernetes 版本低于版本 1.32.0,则尝试运行 --enable-retina-flow-logs 会导致错误消息:

    The specified orchestrator version %s is not valid. Advanced Networking Flow Logs is only supported on Kubernetes version 1.32.0 or later.

    其中 %s 是你的 Kubernetes 版本。

  • 在未启用 Azure 功能公开控制(AFEC)标志的订阅上运行 --enable-retina-flow-logs 时,如果尝试这样做,将显示一条错误消息:

    Feature Microsoft.ContainerService/AdvancedNetworkingFlowLogsPreview is not enabled. Please see https://aka.ms/aks/previews for how to enable features.

  • 如果尝试在未启用高级容器网络服务的群集上应用 RetinaNetworkFlowLog 自定义资源,将显示一条错误消息:

    error: resource mapping not found for <....>": no matches for kind "RetinaNetworkFlowLog" in version "acn.azure.com/v1alpha1"

    确保先安装自定义资源。

禁用容器网络日志:现有群集上的存储日志模式

如果删除了所有自定义资源,流日志收集将停止,因为未为收集定义筛选器。

若要禁用 Azure Monitor 代理的 retina 流日志收集,请运行:

 az aks update -n $CLUSTER_NAME -g $RESOURCE_GROUP --disable-retina-flow-logs

清理资源

如果不打算使用此示例应用程序,请使用此命令删除本文 az group delete 中创建的资源。

  az group delete --name $RESOURCE_GROUP