分享方式:


針對已啟用 Azure Arc 的 Kubernetes 叢集延伸模組問題進行疑難排解

本文件提供叢集延伸模組相關問題的疑難排解秘訣,例如 GitOps (Flux v2) 和 Open Service Mesh。

如需針對已啟用 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

Webhook/試執行錯誤

如果您看到 Flux 無法協調並出現如 dry-run failed, error: admission webhook "<webhook>" does not support dry run 的錯誤,您可尋找 ValidatingWebhookConfigurationMutatingWebhookConfiguration 並將 sideEffects 設定為 NoneNoneOnDryRun,藉以解決問題:

如需詳細資訊,請參閱如何解決 webhook does not support dry run 錯誤?

安裝 microsoft.flux 延伸模組時發生錯誤

microsoft.flux 擴充功能會將 Flux 控制器和 Azure GitOps 代理程式安裝至已啟用 Azure Arc 的 Kubernetes 或 Azure Kubernetes Service (AKS) 叢集。 如果尚未在叢集中安裝延伸模組,但您針對該叢集建立 GitOps 設定資源,則將會自動安裝延伸模組。

如果您在安裝期間遇到錯誤,或延伸模組處於失敗狀態,請確定叢集沒有任何原則會限制在該命名空間中建立 flux-system 命名空間或資源。

針對 AKS 叢集,請確定訂用帳戶已啟用 Microsoft.ContainerService/AKS-ExtensionManager 功能旗標。

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

之後,請執行此命令來判斷是否有其他問題。 將叢集類型 -t 參數設定為 connectedClusters (針對已啟用 Arc 的叢集) 或設定為 managedClusters (針對 AKS 叢集)。 如果已在建立 GitOps 設定期間自動安裝 microsoft.flux 延伸模組,則延伸模組名稱會是「flux」。 如需相關資訊,請查看 statuses 物件。

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 命名空間

之後,您可以重新建立可自動安裝 microsoft.flux 延伸模組的 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}}\"}]}}",

在此情況下,延伸模組代理程式 Pod 會嘗試從叢集上的 IMDS 取得其權杖。 但 Pod 身分識別會攔截權杖要求)。 若要修正此問題,請升級至最新版本microsoft.flux 延伸模組。

在 AKS 叢集中安裝 microsoft.flux 延伸模組時,kubelet 身分識別的問題

使用 AKS 叢集時,其中一個驗證選項是使用使用者指派的受控識別的 kubelet 身分識別。 使用 kubelet 身分識別可降低作業額外負荷,並在連線至 Azure Container Registry 等 Azure 資源時提高安全性。

若要讓 Flux 使用 kubelet 身分識別,請在安裝 Flux 延伸模組時新增 --config useKubeletIdentity=true 參數。

az k8s-extension create --resource-group <resource-group> --cluster-name <cluster-name> --cluster-type managedClusters --name flux --extension-type microsoft.flux --config useKubeletIdentity=true

確保符合 microsoft.flux 延伸模組安裝的記憶體和 CPU 需求

使用 microsoft.flux 延伸模組安裝在 Kubernetes 叢集中的控制器需要 CPU 和記憶體資源,才能在 Kubernetes 叢集節點上正確排程。 請確定您的叢集能夠符合可能要求的最小記憶體和 CPU 資源。 另請注意,這裡顯示的潛在 CPU 和記憶體資源需求上限。

容器名稱 最小 CPU 最小記憶體 最大 CPU 記憶體上限
fluxconfig-agent 5 公尺 30 Mi 50 m 150 Mi
fluxconfig-controller 5 公尺 30 Mi 100 m 150 Mi
fluent-bit 5 公尺 30 Mi 20 m 150 Mi
helm-controller 100 m 64 Mi 1000 m 1 Gi
source-controller 50 m 64 Mi 1000 m 1 Gi
kustomize-controller 100 m 64 Mi 1000 m 1 Gi
notification-controller 100 m 64 Mi 1000 m 1 Gi
image-automation-controller 100 m 64 Mi 1000 m 1 Gi
image-reflector-controller 100 m 64 Mi 1000 m 1 Gi

如果您已啟用自訂或內建 Azure Gatekeeper 原則 (其會限制 Kubernetes 叢集上容器的資源,例如 Kubernetes cluster containers CPU and memory resource limits should not exceed the specified limits),請確定原則上的資源限制大於此處顯示的限制,或 flux-system 命名空間屬於原則指派中 excludedNamespaces 參數的一部分。

Flux v1

注意

建議您盡快移轉至 Flux v2。 在 2024 年 1 月 1 日之前建立的 Flux v1 型叢集設定資源支援,將於 2025 年 5 月 24 日結束。 從 2024 年 1 月 1 日起,您將無法建立新的 Flux v1 型叢集設定資源。

若要協助疑難排解 Flux v1 中 sourceControlConfigurations 資源的問題,請使用已指定 --debug 參數來執行下列 Azure CLI 命令:

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

Azure 監視器容器深入解析

本節提供針對已啟用 Azure Arc 的 Kubernetes 叢集的 Azure 監視器容器深入解析問題進行疑難排解的協助。

啟用 Canonical Charmed Kubernetes 叢集的特殊權限模式

Azure 監視器容器深入解析需要其 DaemonSet 以在特殊權限模式中執行。 若要成功設定 Canonical Charmed Kubernetes 叢集以進行監視,請執行下列命令:

juju config kubernetes-worker allow-privileged=true

無法在 Oracle Linux 9.x 上安裝 Azure 監視器代理程式 (AMA)

嘗試在 Oracle Linux (RHEL) 9.x Kubernetes 叢集上安裝 Azure 監視器代理程式 (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 發行版本中自動載入。

若要修正此問題,您必須使用 modprobe 命令 sudo modprobe iptables_nat,在叢集中的每個節點上明確載入 iptables_nat 模組。 登入每個節點並手動新增 iptable_nat 模組之後,請重試 AMA 安裝。

注意

執行此步驟並不會讓 iptables_nat 模組持續運作。

已啟用 Azure Arc 的 Open Service Mesh

本節提供的命令可用來驗證叢集上 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

即使一個控制器在某個時間點遭到收回,則仍會有 READY 1/1Running 另一個控制器且 0 次重新啟動。 如果資料行 READY 並非 1/1,服務網格會處於中斷狀態。 0/1 的資料行 READY 表示控制平面容器損毀。

使用下列命令檢查控制器記錄:

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

/ 之後,數字高於 1 的資料行 READY 會表示已安裝 Sidecar。 OSM 控制器通常不適用於附加的 Sidecar。

檢查 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 位址為 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

kubectl get ValidatingWebhookConfiguration --selector app=osm-controller

如果驗證 Webhook 狀況良好,您會看到類似下列的輸出:

NAME                     WEBHOOKS   AGE
osm-validator-mesh-osm   1          81m
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 控制器是否已向 CA 套件組合提供 驗證 (或變動) Webhook:

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 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 string "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 string "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 string "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 Sidecar。

注意

呼叫 osm namespace add 之後,只有新的 Pod 才會插入 Envoy Sidecar。 現有的 Pod 必須透過 kubectl rollout restart deployment 命令來重新啟動。

驗證 SMI CRD

使用下列命令,檢查叢集是否有必要的自訂資源定義 (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,請使用下列命令來在叢集上安裝。 視需要取代這些命令中的版本 (例如,v1.1.0 會是 release-v1.1)。

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 Proxy 發放和管理憑證的資訊,請參閱 OSM 文件網站

升級 Enovy

在附加元件監視的命名空間中建立新的 Pod 時,OSM 會在該 Pod 中插入 Envoy Proxy Sidecar。 如果必須更新 Envoy 版本,請遵循 OSM 文件網站上升級指南的步驟。

下一步