Share via


Azure Kubernetes Services의 API 서버 및 기타 문제 해결

이 가이드는 대규모 MICROSOFT AKS(Azure Kubernetes Services) 배포에서 API 서버 내에서 발생할 수 있는 문제를 식별하고 resolve 수 있도록 설계되었습니다.

Microsoft는 5,000개의 노드와 200,000개의 Pod 규모로 API 서버의 안정성과 성능을 테스트했습니다. API 서버를 포함하는 클러스터에는 Kubernetes SLO(서비스 수준 목표)를 자동으로 스케일 아웃하고 제공할 수 있습니다. 대기 시간이 짧거나 시간 초과가 발생하는 경우 분산 etc 디렉터리(etcd)에 리소스 누수가 있거나 잘못된 클라이언트에 과도한 API 호출이 있기 때문일 수 있습니다.

필수 구성 요소

  • Azure CLI.

  • Kubernetes kubectl 도구입니다 . Azure CLI를 사용하여 kubectl을 설치하려면 az aks install-cli 명령을 실행합니다.

  • AKS는 Log Analytics 작업 영역으로 사용하도록 설정되고 전송되는 로그(특히 kube-audit 이벤트)를 진단. 리소스별 또는 Azure 진단 모드를 사용하여 로그가 수집되는지 확인하려면 Azure Portal 진단 설정 블레이드를 검사.

  • AKS 클러스터에 대한 표준 계층입니다. 무료 계층을 사용하는 경우 API 서버 및 etcd에는 제한된 리소스가 포함됩니다. 무료 계층의 AKS 클러스터는 고가용성을 제공하지 않습니다. 이는 종종 API 서버 및 기타 문제의 근본 원인입니다.

  • Kubernetes 컨트롤 플레인을 사용하지 않고 AKS 노드에서 직접 명령을 실행하기 위한 kubectl-aks 플러그 인입니다.

증상

다음 표에서는 API 서버 오류의 일반적인 증상에 대해 간략하게 설명합니다.

증상 설명
API 서버의 제한 시간 AKS API 서버 SLA에서 보장을 초과하는 잦은 시간 제한입니다. 예를 들어 kubectl 명령 제한 시간이 초과됩니다.
대기 시간이 짧음 Kubernetes SLO를 실패하게 만드는 대기 시간이 짧습니다. 예를 들어 명령은 Pod를 kubectl 나열하는 데 30초 이상 걸립니다.
상태 또는 웹후크 호출 실패에 직면한 API 서버 Pod CrashLoopbackOff API 서버에 대한 호출을 차단하는 사용자 지정 허용 웹후크(예: Kyverno 정책 엔진)가 없는지 확인합니다.

문제 해결 검사 목록

대기 시간이 긴 경우 다음 단계에 따라 잘못된 클라이언트와 실패한 API 호출 유형을 파악합니다.

1단계: 요청 수로 상위 사용자 에이전트 식별

가장 많은 요청(그리고 잠재적으로 가장 많은 API 서버 로드)을 생성하는 클라이언트를 식별하려면 다음 코드와 유사한 쿼리를 실행합니다. 다음 쿼리는 전송된 API 서버 요청 수별로 상위 10명의 사용자 에이전트를 나열합니다.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| summarize count() by UserAgent
| top 10 by count_
| project UserAgent, count_

참고

쿼리가 결과를 반환하지 않으면 잘못된 테이블을 선택하여 진단 로그를 쿼리했을 수 있습니다. 리소스별 모드에서 데이터는 리소스의 범주에 따라 개별 테이블에 기록됩니다. 진단 로그는 테이블에 기록 AKSAudit 됩니다. Azure 진단 모드에서는 모든 데이터가 테이블에 기록 AzureDiagnostics 됩니다. 자세한 내용은 Azure 리소스 로그를 참조하세요.

가장 높은 요청 볼륨을 생성하는 클라이언트를 아는 것이 유용하지만 높은 요청 볼륨만으로는 문제가 되지 않을 수 있습니다. 각 클라이언트가 API 서버에서 생성하는 실제 부하를 더 잘 나타내는 것은 해당 클라이언트가 경험하는 응답 대기 시간입니다.

2단계: 사용자 에이전트당 API 서버 요청의 평균 대기 시간 식별 및 차트

시간 차트에 표시된 대로 사용자 에이전트당 API 서버 요청의 평균 대기 시간을 식별하려면 다음 쿼리를 실행합니다.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize avg(latency) by UserAgent, bin(start_time, 5m)
| render timechart

이 쿼리는 "요청 수로 상위 사용자 에이전트 식별" 섹션의 쿼리에 대한 후속 작업입니다. 시간이 지남에 따라 각 사용자 에이전트에 의해 생성된 실제 부하에 대한 더 많은 인사이트를 제공할 수 있습니다.

이 데이터를 분석하여 AKS 클러스터 또는 애플리케이션에서 문제를 나타낼 수 있는 패턴과 변칙을 식별할 수 있습니다. 예를 들어 특정 사용자에게 높은 대기 시간이 발생하는 것을 알 수 있습니다. 이 시나리오는 API 서버 또는 etcd에서 과도한 부하를 일으키는 API 호출 유형을 나타낼 수 있습니다.

3단계: 지정된 사용자 에이전트에 대한 잘못된 API 호출 식별

다음 쿼리를 실행하여 지정된 클라이언트에 대해 여러 리소스 유형에서 API 호출의 99번째 백분위수(P99) 대기 시간을 표로 작성합니다.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend HttpMethod = Verb
| extend Resource = tostring(ObjectRef.resource)
| where UserAgent == "DUMMYUSERAGENT" // Filter by name of the useragent you are interested in
| where Resource != ""
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize p99latency=percentile(latency, 99) by HttpMethod, Resource
| render table

이 쿼리의 결과는 업스트림 Kubernetes SLO에 실패한 API 호출의 종류를 식별하는 데 유용할 수 있습니다. 대부분의 경우 잘못된 클라이언트가 너무 큰 개체 또는 개체 집합에 대해 너무 많은 LIST 호출을 할 수 있습니다. 아쉽게도 사용자에게 API 서버 확장성에 대해 안내하는 하드 확장성 제한을 사용할 수 없습니다. API 서버 또는 기타 확장성 제한은 Kubernetes 확장성 임계값에 설명된 다양한 요인에 따라 달라집니다.

원인 1: 네트워크 규칙이 에이전트 노드에서 API 서버로의 트래픽을 차단합니다.

네트워크 규칙은 에이전트 노드와 API 서버 간의 트래픽을 차단할 수 있습니다.

잘못 구성된 네트워크 정책이 API 서버와 에이전트 노드 간의 통신을 차단하는지 확인하려면 다음 kubectl-aks 명령을 실행합니다.

kubectl aks config import \
    --subscription <mySubscriptionID> \
    --resource-group <myResourceGroup> \
    --cluster-name <myAKSCluster>

kubectl aks check-apiserver-connectivity --node <myNode>

구성 가져오기 명령은 클러스터의 모든 노드에 대한 Virtual Machine Scale Set 정보를 검색합니다. 그런 다음, 검사-apiserver-connectivity 명령은 이 정보를 사용하여 API 서버와 지정된 노드 간의 네트워크 연결, 특히 기본 확장 집합 instance 대한 네트워크 연결을 확인합니다.

참고

명령의 출력에 check-apiserver-connectivity 메시지가 포함된 Connectivity check: succeeded 경우 네트워크 연결은 방해받지 않습니다.

해결 방법 1: 트래픽 차단을 제거하는 네트워크 정책 수정

명령 출력에 연결 오류가 발생했음을 나타내는 경우 에이전트 노드와 API 서버 간의 트래픽을 불필요하게 차단하지 않도록 네트워크 정책을 다시 구성합니다.

원인 2: 잘못된 클라이언트가 etcd 개체를 누출하여 etcd 속도가 느려집니다.

일반적인 문제는 etcd 데이터베이스에서 사용되지 않는 개체를 삭제하지 않고 개체를 지속적으로 만드는 것입니다. 따라서 etcd가 모든 형식의 개체(10,000개 이상)를 너무 많이 처리하는 경우 성능 문제가 발생할 수 있습니다. 이러한 개체의 변경이 급격히 증가하면 etcd 데이터베이스 크기(기본적으로 4기가바이트)를 초과할 수도 있습니다.

etcd 데이터베이스 사용량을 검사 Azure Portal 문제 진단 및 해결로 이동합니다. 검색 상자에서 "etcd"를 검색하여 Etcd 가용성 문제 진단 도구를 실행합니다. 진단 도구는 사용 현황 분석 및 총 데이터베이스 크기를 보여 줍니다.

AKS(Azure Kubernetes Service 대한 Etcd 가용성 진단을 보여 주는 Azure Portal 스크린샷

etcd 데이터베이스의 현재 크기를 바이트 단위로 빠르게 보려면 다음 명령을 실행합니다.

kubectl get --raw /metrics | grep -E "etcd_db_total_size_in_bytes|apiserver_storage_size_bytes|apiserver_storage_db_total_size_in_bytes"

참고

이전 명령의 메트릭 이름은 다른 Kubernetes 버전에 대해 다릅니다. Kubernetes 1.25 이하의 경우 를 사용합니다 etcd_db_total_size_in_bytes. Kubernetes 1.26~ 1.28의 경우 를 사용합니다 apiserver_storage_db_total_size_in_bytes.

해결 방법 2: 개체 만들기에 대한 할당량 정의, 개체 삭제 또는 etcd에서 개체 수명 제한

etcd가 용량에 도달하고 클러스터 가동 중지 시간이 발생하지 않도록 하려면 생성된 최대 리소스 수를 제한할 수 있습니다. 리소스 인스턴스에 대해 생성된 수정 버전 수를 늦출 수도 있습니다. 만들 수 있는 개체 수를 제한하려면 개체 할당량을 정의할 수 있습니다.

더 이상 사용되지 않지만 리소스를 사용하는 개체를 식별한 경우 삭제하는 것이 좋습니다. 예를 들어 완료된 작업을 삭제하여 공간을 확보할 수 있습니다.

kubectl delete jobs --field-selector status.successful=1

자동 정리를 지원하는 개체의 경우 TTL(Time to Live) 값을 설정하여 이러한 개체의 수명을 제한할 수 있습니다. 레이블 선택기를 사용하여 특정 형식의 모든 개체를 대량으로 삭제할 수 있도록 개체에 레이블을 지정할 수도 있습니다. 개체 간에 소유자 참조를 설정하면 부모 개체가 삭제된 후 종속 개체가 자동으로 삭제됩니다.

원인 3: 잘못된 클라이언트가 과도한 LIST 또는 PUT 호출을 수행합니다.

etcd가 너무 많은 개체로 오버로드되지 않는다고 판단하면 클라이언트가 너무 많이 LIST 만들거나 PUT API 서버를 호출할 수 있습니다.

해결 방법 3a: API 호출 패턴 조정

컨트롤 플레인의 압력을 줄이기 위해 클라이언트의 API 호출 패턴을 조정하는 것이 좋습니다.

해결 방법 3b: 컨트롤 플레인을 압도하는 클라이언트 제한

클라이언트를 튜닝할 수 없는 경우 Kubernetes의 우선 순위 및 공정성 기능을 사용하여 클라이언트를 제한할 수 있습니다. 이 기능은 컨트롤 플레인의 상태를 유지하고 다른 애플리케이션의 실패를 방지하는 데 도움이 될 수 있습니다.

다음 절차에서는 5개의 동시 호출로 설정된 잘못된 클라이언트의 LIST Pods API를 제한하는 방법을 보여 줍니다.

  1. 잘못된 클라이언트의 API 호출 패턴과 일치하는 FlowSchema를 Create.

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: FlowSchema
    metadata:
      name: restrict-bad-client
    spec:
      priorityLevelConfiguration:
        name: very-low-priority
      distinguisherMethod:
        type: ByUser
      rules:
      - resourceRules:
        - apiGroups: [""]
          namespaces: ["default"]
          resources: ["pods"]
          verbs: ["list"]
        subjects:
        - kind: ServiceAccount
          serviceAccount:
            name: bad-client-account
            namespace: default 
    
  2. 클라이언트의 잘못된 API 호출을 제한하려면 우선 순위가 낮은 구성을 Create.

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: PriorityLevelConfiguration
    metadata:
      name: very-low-priority
    spec:
      limited:
        assuredConcurrencyShares: 5
        limitResponse:
          type: Reject
      type: Limited
    
  3. API 서버 메트릭에서 제한된 호출을 관찰합니다.

    kubectl get --raw /metrics | grep "restrict-bad-client"
    

원인 4: 사용자 지정 웹후크로 인해 API 서버 Pod에 교착 상태가 발생할 수 있습니다.

Kyverno와 같은 사용자 지정 웹후크가 API 서버 Pod 내에서 교착 상태를 일으킬 수 있습니다.

API 서버와 관련된 이벤트를 확인합니다. 다음 텍스트와 유사한 이벤트 메시지가 표시될 수 있습니다.

내부 오류가 발생했습니다. webhook "mutate.kyverno.svc-fail"을 호출하지 못했습니다. webhook를 호출하지 못했습니다. Post "https://kyverno-system-kyverno-system-svc.kyverno-system.svc:443/mutate/fail?timeout=10s": write unix @-/tunnel-uds>/proxysocket: write: broken pipe

이 예제에서 유효성 검사 웹후크는 일부 API 서버 개체의 생성을 차단합니다. 이 시나리오는 부트스트랩 시간 동안 발생할 수 있으므로 API 서버 및 Konnectivity Pod를 만들 수 없습니다. 따라서 웹후크는 해당 Pod에 연결할 수 없습니다. 이 이벤트 시퀀스는 교착 상태와 오류 메시지를 발생합니다.

해결 방법 4: 웹후크 구성 삭제

이 문제를 해결하려면 유효성 검사 및 변경 웹후크 구성을 삭제합니다. Kyverno에서 이러한 웹후크 구성을 삭제하려면 Kyverno 문제 해결 문서를 검토하세요.

타사 연락처 고지

Microsoft는 이 항목에 대한 추가 정보를 찾는 데 도움이 되는 타사 연락처 정보를 제공합니다. 이 연락처 정보는 공지 없이 변경될 수 있습니다. Microsoft는 타사 연락처 정보의 정확성을 보장하지 않습니다.

타사 정보 고지 사항

이 문서에 나와 있는 다른 공급업체 제품은 Microsoft와 무관한 회사에서 제조한 것입니다. Microsoft는 이들 제품의 성능이나 안정성에 관하여 명시적이든 묵시적이든 어떠한 보증도 하지 않습니다.

도움을 요청하십시오.

질문이 있거나 도움이 필요한 경우 지원 요청을 생성하거나Azure 커뮤니티 지원에 문의하세요. Azure 피드백 커뮤니티에 제품 피드백을 제출할 수도 있습니다.