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

排查已启用 Azure Arc 的 Kubernetes 群集的扩展问题

本文介绍了与 Azure 中的 GitOps (Flux v2) 或开放式服务网格 (OSM) 等群集扩展相关的常见问题的故障排除提示。

有关排查已启用 Azure Arc 的 Kubernetes 一般问题的帮助,请参阅排查已启用 Azure Arc 的 Kubernetes 问题

GitOps (Flux v2)

注意

Flux v2 扩展可用于已启用 Azure Arc 的 Kubernetes 群集或 Azure Kubernetes Service (AKS) 群集。 这些提示通常适用于所有群集类型。

有关排查使用 fluxConfigurations 资源时遇到的一般问题的帮助,请运行带有 --debug 参数的这些 Azure CLI 命令:

az provider show -n Microsoft.KubernetesConfiguration --debug
az k8s-configuration flux create <parameters> --debug

Helm 图表配置设置错误

你可能会看到一条错误消息,其内容为“”。Unable to render the Helm chart with the provided config settings and config protected settings : Recommendation Please check if the values provided to the config settings and the config protected settings are valid for this extension type : InnerError [template: azure-k8s-flux/templates/source-controller.yaml:100:24: executing "azure-k8s-flux/templates/source-controller.yaml" at <index (lookup "v1" "ConfigMap" "kube-system" "extension-manager-config").data "AZURE_TENANT_ID">: error calling index: index of untyped nil]

若要解决此问题,请执行下列操作:

  • 如果运行的 microsoft.flux 是版本 1.15.1 或更高版本,请升级到版本 1.15.2 或更高版本。
  • 如果在美国中西部、法国中部、英国南部或西欧区域运行 microsoft.flux 版本 1.16.2,请升级到版本 1.16.3 或更高版本。

Webhook 空运行错误

Flux 可能会失败并显示类似 dry-run failed, error: admission webhook "<webhook>" does not support dry run 的错误。 要解决此问题,请访问 ValidatingWebhookConfigurationMutatingWebhookConfiguration。 在配置中,将 sideEffects 的值设置为 NoneNoneOnDryRun

有关更多信息,请参阅如何解决“webhook 不支持空运行”错误?

安装 microsoft.flux 扩展时的错误

microsoft.flux 扩展在已启用 Azure Arc 的 Kubernetes 群集或 AKS 群集中安装 Flux 控制器和 Azure GitOps 代理。 如果群集中尚未安装该扩展,且你为群集创建了 GitOps 配置资源,则会自动安装该扩展。

如果安装过程中遇到错误,或者扩展显示 Failed 状态,请确保群集没有任何限制创建 flux-system 命名空间或该命名空间中任何资源的策略。

对于 AKS 群集,请确保 Azure 订阅中已启用 Microsoft.ContainerService/AKS-ExtensionManager 功能标志:

az feature register --namespace Microsoft.ContainerService --name AKS-ExtensionManager

接下来,运行以下命令以确定是否存在其他问题。 将群集类型参数(-t)设置为 Azure Arc 启用的群集的 connectedClusters,或 AKS 群集的 managedClusters。 如果创建 GitOps 配置时自动安装了该扩展,则 microsoft.flux 扩展的名称为 flux

az k8s-extension show -g <RESOURCE_GROUP> -c <CLUSTER_NAME> -n flux -t <connectedClusters or managedClusters>

输出结果可以帮助你识别问题及其解决方法。 可能的修正操作包括:

  • 通过运行 az k8s-extension delete --force -g <RESOURCE_GROUP> -c <CLUSTER_NAME> -n flux -t <managedClusters OR connectedClusters> 强制删除该扩展。
  • 通过运行 helm uninstall flux -n flux-system 卸载 Helm 版本。
  • 通过运行 kubectl delete namespaces flux-system 从群集中删除 flux-system 命名空间。

然后,你可以创建新的 Flux 配置(会自动安装 microsoft.flux 扩展),也可以手动安装 Flux 扩展

在具有 Microsoft Entra Pod 托管标识的群集中安装 microsoft.flux 扩展时的错误

如果尝试在具有 Microsoft Entra Pod 托管标识的群集中安装 Flux 扩展,extension-agent Pod 中可能会发生错误。 输出类似于以下示例:

{"Message":"2021/12/02 10:24:56 Error: in getting auth header : error {adal: Refresh request failed. Status Code = '404'. Response body: no azure identity found for request clientID <REDACTED>\n}","LogType":"ConfigAgentTrace","LogLevel":"Information","Environment":"prod","Role":"ClusterConfigAgent","Location":"westeurope","ArmId":"/subscriptions/<REDACTED>/resourceGroups/<REDACTED>/providers/Microsoft.Kubernetes/managedclusters/<REDACTED>","CorrelationId":"","AgentName":"FluxConfigAgent","AgentVersion":"0.4.2","AgentTimestamp":"2021/12/02 10:24:56"}

扩展状态返回为 Failed

"{\"status\":\"Failed\",\"error\":{\"code\":\"ResourceOperationFailure\",\"message\":\"The resource operation completed with terminal provisioning state 'Failed'.\",\"details\":[{\"code\":\"ExtensionCreationFailed\",\"message\":\" error: Unable to get the status from the local CRD with the error : {Error : Retry for given duration didn't get any results with err {status not populated}}\"}]}}",

在这种情况下,extension-agent Pod 尝试从群集上的 Azure 实例元数据服务获取令牌,但令牌请求被 Pod 标识拦截。 要解决此问题,请升级microsoft.flux 扩展的最新版本。

安装 microsoft.flux 扩展的内存和 CPU 资源要求

安装 microsoft.flux 扩展时在 Kubernetes 群集中安装的控制器必须有足够的 CPU 和内存资源,才能在 Kubernetes 群集节点上正确调度。 确保你的群集满足最低内存和 CPU 资源要求。

下表列出了此场景下潜在的 CPU 和内存资源要求的最低和最高限制:

容器名称 最小 CPU 数量 最小内存量 最大 CPU 数量 最大内存
fluxconfig-agent 5米 30 英里 50米 150 Mi
fluxconfig-controller 5米 30 Mi 100 m 150 Mi
fluent-bit 5米 30 英里 20 m 150 Mi
helm-controller 100 m 64 Mi 1,000 m 1 Gi
source-controller 50米 64 Mi 1,000 m 1 Gi
kustomize-controller 100 m 64 Mi 1,000 m 1 Gi
notification-controller 100 m 64 Mi 1,000 m 1 Gi
image-automation-controller 100 m 64 Mi 1,000 m 1 Gi
image-reflector-controller 100 m 64 Mi 1,000 m 1 Gi

如果启用了限制 Kubernetes 群集上容器资源的自定义或内置 Azure Policy Gatekeeper 策略,请确保该策略上的资源限制大于上表所示的限制,或者 flux-system 命名空间是策略分配中 excludedNamespaces 参数的一部分。 此场景中的策略示例为 Kubernetes cluster containers CPU and memory resource limits should not exceed the specified limits

Azure Monitor 容器见解

本部分提供有关排查已启用 Azure Arc 的 Kubernetes 群集的 Azure Monitor 容器见解相关问题的帮助。

为 Canonical Charmed Kubernetes 群集启用特权模式

Azure Monitor 容器见解要求其 Kubernetes DaemonSet 以特权模式运行。 如果要成功设置用于监视的 Canonical Charmed Kubernetes 群集,请运行以下命令:

juju config kubernetes-worker allow-privileged=true

无法在 Oracle Linux 9.x 上安装 AMA Pod

如果尝试在 Oracle Linux (Red Hat Enterprise Linux (RHEL)) 9.x Kubernetes 群集上安装 Azure Monitor 代理 (AMA),由于 Pod 中的 addon-token-adapter 容器,AMA Pod 和 AMA-RS Pod 可能无法正常工作。 检查 ama-logs-rs Pod 的日志(位于 addon-token-adapter container 中)时,你会看到类似以下示例的输出:

Command: kubectl -n kube-system logs ama-logs-rs-xxxxxxxxxx-xxxxx -c addon-token-adapter
 
Error displayed: error modifying iptable rules: error adding rules to custom chain: running [/sbin/iptables -t nat -N aad-metadata --wait]: exit status 3: modprobe: can't change directory to '/lib/modules': No such file or directory

iptables v1.8.9 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

出现此错误的原因是安装扩展需要 iptable_nat 模块,但该模块不会自动加载到 Oracle Linux (RHEL) 9.x 发行版中。

要解决此问题,必须在群集的每个节点上显式加载 iptables_nat 模块。 使用 modprobe 命令 sudo modprobe iptables_nat。 登录到每个节点并手动添加 iptable_nat 模块后,请重试 AMA 安装。

注意

执行此步骤不会使 iptables_nat 模块持久化。

启用了 Azure Arc 的开放式服务网格

本部分演示可用于验证和排查群集上开放式服务网格 (OSM) 扩展组件部署的命令。

警告

Microsoft已于 2027 年 9 月 30 日宣布停用 AKS 开放服务网格(OSM)加载项 。 上游 OSM 项目也已由 Cloud Native Computing Foundation (CNCF) 停用。

检查 OSM 控制器部署

kubectl get deployment -n arc-osm-system --selector app=osm-controller

如果 OSM 控制器运行正常,则会看到如下输出:

NAME             READY   UP-TO-DATE   AVAILABLE   AGE
osm-controller   1/1     1            1           59m

检查 OSM 控制器 Pod

kubectl get pods -n arc-osm-system --selector app=osm-controller

如果 OSM 控制器运行正常,会出现类似以下示例的输出:

NAME                            READY   STATUS    RESTARTS   AGE
osm-controller-b5bd66db-wglzl   0/1     Evicted   0          61m
osm-controller-b5bd66db-wvl9w   1/1     Running   0          31m

尽管某个控制器在某个时刻的状态为 Evicted,但另一个控制器的 READY 状态为 1/1Running,且重启次数为 0。 如果 READY 状态不是 1/1,则服务网格处于故障状态。 如果 READY0/1,则控制平面容器正在崩溃。

使用以下命令检查控制器日志:

kubectl logs -n arc-osm-system -l app=osm-controller

如果斜杠 (/) 后的 READY 状态是大于 1 的数字,则表示已安装挎斗。 附加挎斗时,OSM 控制器通常无法正常工作。

检查 OSM 控制器服务

要检查 OSM 控制器服务,请运行以下命令:

kubectl get service -n arc-osm-system osm-controller

如果 OSM 控制器运行正常,会出现类似以下示例的输出:

NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)              AGE
osm-controller   ClusterIP   10.0.31.254   <none>        15128/TCP,9092/TCP   67m

注意

CLUSTER-IP 的实际值将与此示例不同。 NAMEPORT(S) 的值应与本示例中显示的值匹配。

检查 OSM 控制器终结点

kubectl get endpoints -n arc-osm-system osm-controller

如果 OSM 控制器运行正常,会出现类似以下示例的输出:

NAME             ENDPOINTS                              AGE
osm-controller   10.240.1.115:9092,10.240.1.115:15128   69m

如果群集中没有值为 osm-controllerENDPOINTS,则控制平面运行不正常。 这种运行不正常的状态意味着控制器 Pod 崩溃或者从未正确部署。

检查 OSM 注入器部署

kubectl get deployments -n arc-osm-system osm-injector

如果 OSM 注入器运行正常,会出现类似以下示例的输出:

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
osm-injector   1/1     1            1           73m

检查 OSM 注入器 Pod

kubectl get pod -n arc-osm-system --selector app=osm-injector

如果 OSM 注入器运行正常,会出现类似以下示例的输出:

NAME                            READY   STATUS    RESTARTS   AGE
osm-injector-5986c57765-vlsdk   1/1     Running   0          73m

READY 状态必须为 1/1。 任何其他值都表示 OSM 注入程序 pod 运行不正常。

检查 OSM 注入器服务

kubectl get service -n arc-osm-system osm-injector

如果 OSM 注入器运行正常,会出现类似以下示例的输出:

NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
osm-injector   ClusterIP   10.0.39.54   <none>        9090/TCP   75m

确保为osm-injector服务列出的 IP 地址是9090EXTERNAL-IP 不应列出任何值。

检查 OSM 注入程序终结点

kubectl get endpoints -n arc-osm-system osm-injector

如果 OSM 注入器运行正常,会出现类似以下示例的输出:

NAME           ENDPOINTS           AGE
osm-injector   10.240.1.172:9090   75m

要使 OSM 正常工作,osm-injector 必须至少有一个终结点。 OSM 注入器终结点的 IP 地址各不相同,但端口值 9090 必须相同。

检查 Webhook:验证型和变异型

通过运行以下命令检查验证型 Webhook:

kubectl get ValidatingWebhookConfiguration --selector app=osm-controller

如果验证型 Webhook 运行正常,会出现类似以下示例的输出:

NAME                     WEBHOOKS   AGE
osm-validator-mesh-osm   1          81m

通过运行以下命令检查变异型 Webhook:

kubectl get MutatingWebhookConfiguration --selector app=osm-injector

如果变异型 Webhook 运行正常,会出现类似以下示例的输出:

NAME                  WEBHOOKS   AGE
arc-osm-webhook-osm   1          102m

通过以下命令检查验证型 Webhook 的服务和证书颁发机构捆绑包(CA 捆绑包):

kubectl get ValidatingWebhookConfiguration osm-validator-mesh-osm -o json | jq '.webhooks[0].clientConfig.service'

配置良好的验证型 Webhook 会有类似以下示例的输出:

{
  "name": "osm-config-validator",
  "namespace": "arc-osm-system",
  "path": "/validate",
  "port": 9093
}

通过以下命令检查变异型 Webhook 的服务和 CA 捆绑包:

kubectl get MutatingWebhookConfiguration arc-osm-webhook-osm -o json | jq '.webhooks[0].clientConfig.service'

配置良好的变异型 Webhook 会有类似以下示例的输出:

{
  "name": "osm-injector",
  "namespace": "arc-osm-system",
  "path": "/mutate-pod-creation",
  "port": 9090
}

通过以下命令检查 OSM 控制器是否已为验证型(或变异型)Webhook 提供 CA 捆绑包:

kubectl get ValidatingWebhookConfiguration osm-validator-mesh-osm -o json | jq -r '.webhooks[0].clientConfig.caBundle' | wc -c
kubectl get MutatingWebhookConfiguration arc-osm-webhook-osm -o json | jq -r '.webhooks[0].clientConfig.caBundle' | wc -c

示例输出:

1845

输出中的数字表示字节数,即 CA 捆绑包的大小。 如果输出为空、0 或小于 1000 的数字,则表示 CA 捆绑包未正确配置。 没有正确的 CA 捆绑包,ValidatingWebhook 会抛出错误。

检查 osm-mesh-config 资源

检查资源是否存在:

kubectl get meshconfig osm-mesh-config -n arc-osm-system

检查 OSM meshconfig 设置的值:

kubectl get meshconfig osm-mesh-config -n arc-osm-system -o yaml

查找类似以下示例的输出:

apiVersion: config.openservicemesh.io/v1alpha1
kind: MeshConfig
metadata:
  creationTimestamp: "0000-00-00A00:00:00A"
  generation: 1
  name: osm-mesh-config
  namespace: arc-osm-system
  resourceVersion: "2494"
  uid: 6c4d67f3-c241-4aeb-bf4f-b029b08faa31
spec:
  certificate:
    certKeyBitSize: 2048
    serviceCertValidityDuration: 24h
  featureFlags:
    enableAsyncProxyServiceMapping: false
    enableEgressPolicy: true
    enableEnvoyActiveHealthChecks: false
    enableIngressBackendPolicy: true
    enableMulticlusterMode: false
    enableRetryPolicy: false
    enableSnapshotCacheMode: false
    enableWASMStats: true
  observability:
    enableDebugServer: false
    osmLogLevel: info
    tracing:
      enable: false
  sidecar:
    configResyncInterval: 0s
    enablePrivilegedInitContainer: false
    logLevel: error
    resources: {}
  traffic:
    enableEgress: false
    enablePermissiveTrafficPolicyMode: true
    inboundExternalAuthorization:
      enable: false
      failureModeAllow: false
      statPrefix: inboundExtAuthz
      timeout: 1s
    inboundPortExclusionList: []
    outboundIPRangeExclusionList: []
    outboundPortExclusionList: []
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

下表列出了 osm-mesh-config 资源值:

密钥 类型 默认值 Kubectl 补丁命令示例
spec.traffic.enableEgress bool false kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"enableEgress":false}}}' --type=merge
spec.traffic.enablePermissiveTrafficPolicyMode bool true kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"enablePermissiveTrafficPolicyMode":true}}}' --type=merge
spec.traffic.outboundPortExclusionList 数组 [] kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"outboundPortExclusionList":[6379,8080]}}}' --type=merge
spec.traffic.outboundIPRangeExclusionList 数组 [] kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"outboundIPRangeExclusionList":["10.0.0.0/32","1.1.1.1/24"]}}}' --type=merge
spec.traffic.inboundPortExclusionList 数组 [] kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"inboundPortExclusionList":[6379,8080]}}}' --type=merge
spec.certificate.serviceCertValidityDuration 字符串 "24h" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"certificate":{"serviceCertValidityDuration":"24h"}}}' --type=merge
spec.observability.enableDebugServer bool false kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"observability":{"enableDebugServer":false}}}' --type=merge
spec.observability.osmLogLevel 字符串 "info" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"observability":{"tracing":{"osmLogLevel": "info"}}}}' --type=merge
spec.observability.tracing.enable bool false kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"observability":{"tracing":{"enable":true}}}}' --type=merge
spec.sidecar.enablePrivilegedInitContainer bool false kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"sidecar":{"enablePrivilegedInitContainer":true}}}' --type=merge
spec.sidecar.logLevel 字符串 "error" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"sidecar":{"logLevel":"error"}}}' --type=merge
spec.featureFlags.enableWASMStats bool "true" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableWASMStats":"true"}}}' --type=merge
spec.featureFlags.enableEgressPolicy bool "true" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableEgressPolicy":"true"}}}' --type=merge
spec.featureFlags.enableMulticlusterMode bool "false" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableMulticlusterMode":"false"}}}' --type=merge
spec.featureFlags.enableSnapshotCacheMode bool "false" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableSnapshotCacheMode":"false"}}}' --type=merge
spec.featureFlags.enableAsyncProxyServiceMapping bool "false" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableAsyncProxyServiceMapping":"false"}}}' --type=merge
spec.featureFlags.enableIngressBackendPolicy bool "true" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableIngressBackendPolicy":"true"}}}' --type=merge
spec.featureFlags.enableEnvoyActiveHealthChecks bool "false" kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableEnvoyActiveHealthChecks":"false"}}}' --type=merge

检查命名空间

注意

arc-osm-system 命名空间从不参与服务网格,也从不使用此处显示的键/值对进行标记或注释。

你可以使用 osm namespace add 命令将命名空间加入特定服务网格。 当 Kubernetes 命名空间是网格的一部分时,完成以下步骤以确认满足要求。

查看 bookbuyer 命名空间的注释:

kubectl get namespace bookbuyer -o json | jq '.metadata.annotations'

必须存在以下注释:

{
  "openservicemesh.io/sidecar-injection": "enabled"
}

查看 bookbuyer 命名空间的标签:

kubectl get namespace bookbuyer -o json | jq '.metadata.labels'

必须存在以下标签:

{
  "openservicemesh.io/monitored-by": "osm"
}

如果不使用 osm CLI,你可以手动将这些注释添加到命名空间。 如果命名空间未使用 "openservicemesh.io/sidecar-injection": "enabled" 进行注释,或未使用 "openservicemesh.io/monitored-by": "osm" 进行标记,则 OSM 注入器不会添加 Envoy 挎斗。

注意

在调用 osm namespace add 之后,只有新的 Pod 才会与 Envoy 挎斗一起注入。 必须使用 kubectl rollout restart deployment 命令重启现有 Pod。

验证 SMI CRD

对于 OSM 服务网格接口 (SMI),检查群集是否具有所需的自定义资源定义 (CRD):

kubectl get crds

确保 CRD 与发布分支中可用的版本对应。 要确认正在使用的 CRD 版本,请参阅 SMI 支持的版本,并在“发布”菜单中选择你的版本。

使用以下命令获取已安装 CRD 的版本:

for x in $(kubectl get crds --no-headers | awk '{print $1}' | grep 'smi-spec.io'); do
    kubectl get crd $x -o json | jq -r '(.metadata.name, "----" , .spec.versions[].name, "\n")'
done

如果缺少 CRD,请使用以下命令在群集上安装它们。 根据需要替换这些命令中的版本(例如,可用 release-v1.1 替代 v1.1.0)。

kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm/release-v1.0/cmd/osm-bootstrap/crds/smi_http_route_group.yaml

kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm/release-v1.0/cmd/osm-bootstrap/crds/smi_tcp_route.yaml

kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm/release-v1.0/cmd/osm-bootstrap/crds/smi_traffic_access.yaml

kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm/release-v1.0/cmd/osm-bootstrap/crds/smi_traffic_split.yaml

要了解 CRD 版本在各版本之间的变化,请参阅 OSM 发行说明

排查证书管理问题

有关 OSM 如何向运行在应用程序 Pod 上的 Envoy 代理颁发和管理证书的信息,请参阅 OSM 文档

升级 Envoy

当在扩展所监视的命名空间中创建新 Pod 时,OSM 会在该 Pod 中注入 Envoy 代理挎斗。 如果需要更新 Envoy 版本,请按照 OSM 文档中升级指南的步骤操作。

Azure Kubernetes 舰队管理器

根据环境和配置,将已启用 Arc 的 Kubernetes 群集连接到 Azure Kubernetes 机群管理器中心时,可能会应用某些限制。 查看 Azure Kubernetes 舰队管理器针对已启用 Arc 的 Kubernetes 群集成员的重要注意事项,获取完整的要求和注意事项列表。