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

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

重要

组件重命名(从 2025 年 11 月 11 日开始)

我们正在重命名容器网络日志功能中的组件,以提高清晰度和一致性:

有什么变化

  • CRDRetinaNetworkFlowLogsContainerNetworkLog
  • CLI 标志--enable-retinanetworkflowlog--enable-container-network-logs
  • Log Analytics 表RetinaNetworkFlowLogsContainerNetworkLog

为现有用户启用新命名的拟办事项

  1. 更新 Azure CLI (必须 - 第一步!):

    az upgrade
    
  2. 更新预览版 CLI 扩展 (必须):

    az extension update --name aks-preview
    
  3. 禁用监视

    az aks disable-addons -a monitoring -n <cluster-name> -g <resource-group>
    
  4. 重新启用监视

    az aks enable-addons -a monitoring --enable-high-log-scale-mode -g <resource-group> -n <cluster-name>
    
  5. 重新启用 ACNS 容器网络日志

    az aks update --enable-acns --enable-container-network-logs -g <resource-group> -n <cluster-name>
    
  6. 应用新的 ContainerNetworkLog CRD:使用新的命名来应用更新的 CRD 配置文件。

  7. 重新导入 Grafana 仪表板:导入更新的仪表板以反映新的表名称。

注释

  • 以前收集的数据保留在旧表 RetinaNetworkFlowLogs 的工作区中。
  • 重新启用后,允许在新的表 ContainerNetworkLog 中显示新数据之前进行短暂延迟。

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

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

先决条件

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

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

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

  • 如果现有群集是版本 1.33 或更低版本,请将群集升级到最新的可用 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 策略
  • 目前不支持使用 Terraform 加入。
  • 如果未为日志存储配置 Log Analytics,容器网络日志将限制为最多 50 MB 的存储。 达到此限制后,新条目将覆盖旧日志。
  • 如果日志表计划设置为基本日志,则预生成的 Grafana 仪表板无法按预期工作。
  • 不支持辅助日志表计划。

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

部署方法

可以使用不同的部署方法载入容器网络日志:

本部分提供两个路径,用于根据当前情况设置容器网络日志:

  • 新群集:新 AKS 群集的完整设置
  • 现有群集:在现有 AKS 群集上启用容器网络日志

新集群

本部分指导你从头到尾在新 AKS 群集上设置容器网络日志。

使用高级容器网络服务创建新的 AKS 群集

使用 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>"
export LOCATION="<location>"

# Create the resource group if it doesn't already exist
az group create --name $RESOURCE_GROUP --location $LOCATION

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

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

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

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

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

ContainerNetworkLog CRD 模板

apiVersion: acn.azure.com/v1alpha1
kind: ContainerNetworkLog
metadata:
  name: sample-containernetworklog # 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)以匹配目标。 可选
  • ContainerNetworkLog应用自定义资源以在群集上启用日志收集:

    kubectl apply -f <crd.yaml>
    

    小窍门

    有关 ContainerNetworkLog 自定义资源配置的实际示例,请参阅 AKS 实验室文档中的示例 CRD

本地存储在主机节点上的日志是临时的,因为主机或节点本身不是永久性存储解决方案。 主机节点上的日志也会在大小达到 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-container-network-logs flag
  az aks update --enable-acns \
    --enable-container-network-logs \
    -g $RESOURCE_GROUP \
    -n $CLUSTER_NAME

注释

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

现有群集

注释

如果群集已启用高级容器网络服务(ACNS),只需应用 ContainerNetworkLog CRD 即可开始收集主机节点上的流日志。 但是,如果要通过 Log Analytics 工作区集成来为持久性存储和高级分析启用流日志,请按照“在现有群集中配置与 Log Analytics 的集成”部分中的步骤进行操作。

# Set environment variables for your existing cluster. Make sure you replace the placeholders with your own values.
export CLUSTER_NAME="<aks-cluster-name>"
export RESOURCE_GROUP="<aks-resource-group>"

在现有群集上配置与 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-container-network-logs 标志更新 AKS 群集:

     az aks update --enable-acns \
         --enable-container-network-logs \
         -g $RESOURCE_GROUP \
         -n $CLUSTER_NAME
    
  5. 根据上述 ContainerNetworkLog 模板 创建 CRD,并将其应用于在 Log Analytics 工作区中启动日志收集。

    小窍门

    有关 ContainerNetworkLog 自定义资源配置的实际示例,请参阅 AKS 实验室文档中的示例 CRD

查看 L7 流和 DNS 错误

若要捕获容器网络日志中的第 7 层流数据和 DNS 错误/流,必须应用启用了 FQDN 筛选和 L7 策略支持的 Cilium 网络策略。 如果没有这些策略,将不会捕获 L7 和与 DNS 相关的流信息。

FQDN 筛选和 L7 支持的 Cilium 网络策略示例:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: l7-dns-policy
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: myapp
  egress:
    - toEndpoints:
        - matchLabels:
            "k8s:io.kubernetes.pod.namespace": kube-system
            "k8s:k8s-app": kube-dns
      toPorts:
        - ports:
            - port: "53"
              protocol: UDP
          rules:
            dns:
              - matchPattern: "*.example.com"
    - toFQDNs:
        - matchPattern: "*.example.com"
      toPorts:
        - ports:
            - port: "443"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/1"

使用以下方法应用策略:

kubectl apply -f l7-dns-policy.yaml

有关详细信息,请参阅 配置第 7 层策略配置 FQDN 策略

用于验证配置的常见安装后步骤

以下步骤适用于新的和现有的群集设置。

获取群集凭据

使用 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":{
  "enableContainerNetworkLogs": "True"
 }
}

检查为流日志安装了哪些自定义资源定义:

  kubectl get containernetworklog 

此命令列出在群集中创建的所有 ContainerNetworkLog 自定义资源。

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

   k describe containernetworklog <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

用户可以在群集中应用多个 ContainerNetworkLog 自定义资源。 每个自定义资源都有自己的状态。

在 Log Analytics 仪表板中查询容器网络流日志

使用 Log Analytics 工作区启用容器网络流日志时,可以访问历史日志,以便一段时间内分析网络流量模式。 可以使用表查询这些日志 ContainerNetworkLog ,以执行详细的取证分析和故障排除。

客户可以使用 Kusto 查询语言 (KQL) 分析 Log Analytics 中的网络数据。 此历史数据对于了解网络行为模式、识别安全事件、排查连接问题以及长时间执行根本原因分析非常有用。 跨时间关联网络事件的功能有助于检测间歇性问题并了解实时监视中可能不明显的流量流。

若要查看可用于排查连接问题的示例查询,请参阅 AKS 实验室文档中 使用流日志进行渐进式诊断

Azure 托管 Grafana

可以通过 Azure 门户访问预生成的 Grafana 仪表板。 导航到 Azure Monitor 资源或 Azure Kubernetes 服务 (AKS) 群集,查看这些仪表板并与之交互。 但在此之前:

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

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

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

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

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

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

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

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

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

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

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

Grafana 仪表板中的可视化效果

借助 Grafana 的 Azure Monitor 仪表板,可以在 Azure Monitor 中收集的指标和日志上使用 Grafana 的查询、转换和可视化功能。 可以使用此选项来可视化容器网络流日志。

  1. 在 Azure 门户中导航到 Kubernetes 群集的左窗格。
  2. 选择“使用 Grafana 的仪表板(预览版)”
  3. 浏览 Azure Monitor 或 Azure 托管 Prometheus 列表中提供的仪表板的列表。
  4. 选择仪表板,例如 Azure |见解 |容器 |网络 |流日志

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

为了简化日志分析,我们提供了两个预配置的 Azure 托管 Grafana 仪表板:

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

    Azure Monitor 中 Grafana 仪表板的屏幕截图。

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

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

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

配置按需日志模式

网络流的按需日志模式适用于 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.33 \
    --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-container-network-logs

    产生错误消息:

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

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

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

    其中 %s 是你的 Kubernetes 版本。

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

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

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

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

    确保先安装自定义资源。

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

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

若要禁用 Azure Monitor 代理的容器网络日志收集,请运行:

 az aks update -n $CLUSTER_NAME -g $RESOURCE_GROUP --disable-container-network-logs

清理资源

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

  az group delete --name $RESOURCE_GROUP