你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
设置 Azure Kubernetes 服务 (AKS) 的容器网络可观测性 - Azure 托管的 Prometheus 和 Grafana
本文介绍如何使用托管的 Prometheus 和 Grafana 与 BYO Prometheus 和 Grafana 设置为 Azure Kubernetes 服务 (AKS) 设置容器网络可观测性,以可视化已抓取的指标
可以使用容器网络可观测性收集有关 AKS 群集的网络流量数据。 高级网络可观测性支持用于监视应用程序和网络运行状况的集中式平台。 目前,可使用 Prometheus 存储指标并使用 Grafana 可视化它们。 容器网络可观测性还提供启用 Hubble 的功能。 Cilium 和非 Cilium 群集都支持这些功能。
容器网络可观测性是高级容器网络服务的功能之一。 有关 Azure Kubernetes 服务 (AKS) 的高级容器网络服务的详细信息,请参阅什么是 Azure Kubernetes 服务 (AKS) 的高级容器网络服务。
先决条件
- 具有活动订阅的 Azure 帐户。 如果还没有该订阅,可以在开始前创建一个免费帐户。
在 Azure Cloud Shell 中使用 Bash 环境。 有关详细信息,请参阅 Azure Cloud Shell 中的 Bash 快速入门。
如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。
如果使用的是本地安装,请使用 az login 命令登录 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录。
出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用 Azure CLI 的扩展。
运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。
- 本文中的步骤所需的 Azure CLI 最低版本为 2.56.0。 运行
az --version
即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。
安装 aks-preview Azure CLI 扩展
使用 az extension add
或 az 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
启用高级容器网络服务
若要继续,必须有一个启用了高级容器网络服务的 AKS 群集。
具有高级容器网络服务标志 --enable-acns
的 az aks create
命令创建一个新的 AKS 群集,它具有所有高级容器网络服务功能。 这些功能包括:
注意
从 Kubernetes 版本 1.29 开始,具有 Cilium 数据平面的群集支持容器网络可观测性和容器网络安全。
# 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
在现有群集上启用高级容器网络服务
具有高级容器网络服务标志 --enable-acns
的 az aks update
命令使用所有高级容器网络服务功能(包括容器网络可观测性和容器网络安全功能)更新现有 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
Azure 托管的 Prometheus 和 Grafana
如果使用 BYO Prometheus 和 Grafana,请跳过本部分
使用以下示例为 AKS 群集安装并启用 Prometheus 和 Grafana。
创建 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 '{}'
创建 Azure 托管 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
将 Azure 托管 Grafana 和 Azure Monitor 资源 ID 放在变量中
使用 az grafana show 将 Grafana 资源 ID 放在变量中。 使用 az resource show 将 Azure Monitor 资源 ID 放在变量中。 将 myGrafana 替换为 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)
将 Azure Monitor 和 Azure 托管 Grafana 链接到 AKS 群集
使用 az aks update 将 Azure Monitor 和 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
可视化效果
使用 Azure 托管 Grafana 实现可视化
如果使用 BYO Grafana,请跳过此步骤
注意
由于大规模集群中的指标基数较高,因此默认情况下不会抓取 hubble_flows_processed_total
指标。
因此,“Pod 流”仪表板中的面板缺少数据。 若要更改此问题,可以修改 AMA 指标设置,使其在指标保留列表中包括 hubble_flows_processed_total
。 若要了解如何执行此操作,请参阅最小引入文档。
使用
kubectl get pods
命令确保 Azure Monitor 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
我们已创建示例仪表板。 可以在“仪表板”>“Azure 托管 Prometheus”文件夹下找到它们。 它们的名称类似于“Kubernetes/Networking/
<name>
”。 仪表板套件包括:- 群集:显示群集的节点级指标。
- DNS(群集):显示群集上的 DNS 指标或节点选择。
- DNS(工作负载):显示指定工作负载(例如 DaemonSet 或 CoreDNS 等部署的 Pod)的 DNS 指标。
- 删除(工作负载):显示从指定工作负载(例如部署或 DaemonSet 的 Pod)拖放。
- Pod 流(命名空间):显示传入/传出指定命名空间(即命名空间中的 Pod)的 L4/L7 数据包流。
- Pod 流(工作负载):显示传入/传出指定工作负载(例如部署或 DaemonSet 的 Pod)的 L4/L7 数据包流。
使用 BYO Grafana 进行可视化
如果使用 Azure 托管 Grafana,请跳过此步骤
将以下抓取作业添加到现有 Prometheus 配置,并重启 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
在 Prometheus 的“目标”中,验证 network-obs-pods 是否存在。
登录到 Grafana 并使用以下 ID 导入以下示例仪表板:
- 群集:显示群集的节点级指标。 (ID 18814)
- DNS(群集):显示群集上的 DNS 指标或节点选择。(ID 20925)
- DNS(工作负载):显示指定工作负载(例如 DaemonSet 或 CoreDNS 等部署的 Pod)的 DNS 指标。 (ID [20926] https://grafana.com/grafana/dashboards/20926-kubernetes-networking-dns-workload/)
- 删除(工作负载):显示从指定工作负载(例如部署或 DaemonSet 的 Pod)拖放。(ID 20927)。
- Pod 流(命名空间):显示传入/传出指定命名空间(即命名空间中的 Pod)的 L4/L7 数据包流。 (ID 20928)
- Pod 流(工作负载):显示传入/传出指定工作负载(例如部署或 DaemonSet 的 Pod)的 L4/L7 数据包流。(ID 20929)
注意
- 根据 Prometheus/Grafana 实例的设置,某些仪表板面板可能需要调整才能显示所有数据。
- Cilium 目前不支持 DNS 指标/仪表板。
安装 Hubble CLI
使用以下命令安装 Hubble CLI 以访问它收集的数据:
# 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}
可视化 Hubble 流
使用
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
使用
kubectl port-forward
命令进行 Hubble Relay 端口转发。kubectl port-forward -n kube-system svc/hubble-relay --address 127.0.0.1 4245:443
使用双向 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
使用以下
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
使用
hubble observe
命令确保 Hubble Relay pod 正在运行。hubble observe --pod hubble-relay-7ddd887cdb-h6khj
使用 Hubble UI 进行可视化
若要使用 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
使用以下命令将 hubble-ui.yaml 清单应用到群集
kubectl apply -f hubble-ui.yaml
使用
kubectl port-forward
命令为 Hubble UI 设置端口转发。kubectl -n kube-system port-forward svc/hubble-ui 12000:80
通过在 Web 浏览器中输入
http://localhost:12000/
来访问 Hubble UI。
清理资源
如果不打算使用此应用程序,请使用 az group delete
命令删除本文中创建的其他资源。
az group delete --name $RESOURCE_GROUP
后续步骤
本操作指南文章介绍了如何为 AKS 群集安装和启用容器网络可观测性。
有关 Azure Kubernetes 服务 (AKS) 的高级容器网络服务的详细信息,请参阅什么是 Azure Kubernetes 服务 (AKS) 的高级容器网络服务。
有关容器网络安全及其功能的详细信息,请参阅什么是容器网络安全?。