你当前正在访问 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)
注意
可以在已启用 Azure Arc 的 Kubernetes 群集或 Azure Kubernetes 服务 (AKS) 群集中使用 Flux v2 扩展。 这些故障排除提示基本适用于所有群集类型。
如需常规性帮助来排查使用 fluxConfigurations
资源时遇到的问题,可使用 --debug
参数运行以下 Azure CLI 命令:
az provider show -n Microsoft.KubernetesConfiguration --debug
az k8s-configuration flux create <parameters> --debug
Webhook 试运行错误
Flux 有可能失败并显示类似 dry-run failed, error: admission webhook "<webhook>" does not support dry run
的错误。 要解决此问题,请转到 ValidatingWebhookConfiguration
或 MutatingWebhookConfiguration
。 在配置中,将 sideEffects
的值设置为 None
或 NoneOnDryRun
。
有关详细信息,请参阅如何解决“Webhook 不支持试运行”错误?。
安装 microsoft.flux 扩展时出错
microsoft.flux
扩展将 Flux 控制器和 Azure GitOps 代理安装到已启用 Azure Arc 的 Kubernetes 群集或 Azure Kubernetes 服务 (AKS) 群集中。 如果尚未在群集中安装该扩展,并且为该群集创建了 GitOps 配置资源,则会自动安装该扩展。
如果在安装过程中遇到错误,或者扩展显示处于 Failed
状态,请确保群集没有任何限制创建 flux-system
命名空间或该命名空间中任何资源的策略。
对于 AKS 群集,确保在 Azure 订阅中启用了 Microsoft.ContainerService/AKS-ExtensionManager
功能标志:
az feature register --namespace Microsoft.ContainerService --name AKS-ExtensionManager
接下来,运行以下命令以确定是否存在其他问题。 对于已启用 Azure Arc 的群集,将群集类型参数 (-t
) 设置为 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 m | 30 Mi | 50 m | 150 Mi |
fluxconfig-controller |
5 m | 30 Mi | 100 m | 150 Mi |
fluent-bit |
5 m | 30 Mi | 20 m | 150 Mi |
helm-controller |
100 m | 64 Mi | 1,000 m | 1 Gi |
source-controller |
50 m | 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 |
如果启用了自定义或内置 Azure Policy Gatekeeper 策略来限制 Kubernetes 群集上的容器的资源,请确保策略上的资源限制大于前表中显示的限制,或者确保 flux-system
命名空间是策略分配中的 excludedNamespaces
参数的一部分。 此方案中策略的一个示例是 Kubernetes cluster containers CPU and memory resource limits should not exceed the specified limits
。
Flux v1
注意
建议尽快迁移到 Flux v2。 对在 2024 年 1 月 1 日之前创建的基于 Flux v1 的群集配置资源的支持将于 2025 年 5 月 24 日结束。 从 2024 年 1 月 1 日开始,你将无法创建新的基于 Flux v1 的群集配置资源。
如需相关帮助来排查 Flux v1 中 sourceControlConfigurations
资源的问题,请运行以下 Azure CLI 命令,并在其中包含 --debug
参数:
az provider show -n Microsoft.KubernetesConfiguration --debug
az k8s-configuration flux create <parameters> --debug
Azure Monitor 容器见解
本部分提供有关排查 Azure Monitor 中已启用 Azure Arc 的 Kubernetes 群集的容器见解的相关问题的帮助。
为 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 Agent (AMA),AMA Pod 和 AMA-RS Pod 可能会由于 Pod 中存在 addon-token-adapter
容器而无法正确工作。 检查 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 的开放式服务网格
本部分展示的命令可用于验证群集上的 Open Service Mesh (OSM) 扩展组件的部署并对其进行故障排除。
检查 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/1
,且具有 0
的 Running
重启。 如果 READY
状态不是 1/1
,则服务网格处于中断状态。 如果 READY
为 0/1
,表示控制平面容器崩溃。
使用以下命令检查控制器日志:
kubectl logs -n arc-osm-system -l app=osm-controller
如果 READY
状态是一个大于正斜杠 (/
) 后 1
的数字,则安装了跨斗。 附加了 sidecars 时,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
的实际值与此示例不同。 NAME
和 PORT(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-controller
的 ENDPOINTS
,则表示控制平面运行不正常。 这种运行不正常的状态意味着控制器 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 地址为 9090
。 不应列出任何用于 EXTERNAL-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 Patch 命令示例 |
---|---|---|---|
spec.traffic.enableEgress |
布尔 | false |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"enableEgress":false}}}' --type=merge |
spec.traffic.enablePermissiveTrafficPolicyMode |
布尔 | true |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"enablePermissiveTrafficPolicyMode":true}}}' --type=merge |
spec.traffic.outboundPortExclusionList |
array | [] |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"outboundPortExclusionList":[6379,8080]}}}' --type=merge |
spec.traffic.outboundIPRangeExclusionList |
array | [] |
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 |
array | [] |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"inboundPortExclusionList":[6379,8080]}}}' --type=merge |
spec.certificate.serviceCertValidityDuration |
string | "24h" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"certificate":{"serviceCertValidityDuration":"24h"}}}' --type=merge |
spec.observability.enableDebugServer |
布尔 | false |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"observability":{"enableDebugServer":false}}}' --type=merge |
spec.observability.osmLogLevel |
string | "info" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"observability":{"tracing":{"osmLogLevel": "info"}}}}' --type=merge |
spec.observability.tracing.enable |
布尔 | false |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"observability":{"tracing":{"enable":true}}}}' --type=merge |
spec.sidecar.enablePrivilegedInitContainer |
布尔 | false |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"sidecar":{"enablePrivilegedInitContainer":true}}}' --type=merge |
spec.sidecar.logLevel |
string | "error" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"sidecar":{"logLevel":"error"}}}' --type=merge |
spec.featureFlags.enableWASMStats |
布尔 | "true" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableWASMStats":"true"}}}' --type=merge |
spec.featureFlags.enableEgressPolicy |
布尔 | "true" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableEgressPolicy":"true"}}}' --type=merge |
spec.featureFlags.enableMulticlusterMode |
布尔 | "false" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableMulticlusterMode":"false"}}}' --type=merge |
spec.featureFlags.enableSnapshotCacheMode |
布尔 | "false" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableSnapshotCacheMode":"false"}}}' --type=merge |
spec.featureFlags.enableAsyncProxyServiceMapping |
布尔 | "false" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableAsyncProxyServiceMapping":"false"}}}' --type=merge |
spec.featureFlags.enableIngressBackendPolicy |
布尔 | "true" |
kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"featureFlags":{"enableIngressBackendPolicy":"true"}}}' --type=merge |
spec.featureFlags.enableEnvoyActiveHealthChecks |
布尔 | "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 Arc 的 Kubernetes 的一般故障排除提示。