Kubernetes 업스트림 SLOs - Amazon EKS

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Kubernetes 업스트림 SLOs

Amazon EKS는 업스트림 Kubernetes 릴리스와 동일한 코드를 실행하고 Kubernetes 커뮤니티에서 정의한 SLOs 내에서 EKS 클러스터가 작동하도록 합니다. Kubernetes SIG(Scalability Special Interest Group)는 확장성 목표를 정의하고 SLIs 및 SLOs.

SLIs는 요청 지연 시간 또는 수와 같이 시스템이 얼마나 "잘" 실행되고 있는지 결정하는 데 사용할 수 있는 지표 또는 측정치와 같은 시스템을 측정하는 방법입니다. SLOs는 시스템이 "well"을 실행할 때 예상되는 값을 정의합니다. 예를 들어 요청 지연 시간은 3초 미만으로 유지됩니다. Kubernetes SLOs 및 SLIs는 Kubernetes 구성 요소의 성능에 초점을 맞추고 EKS 클러스터 엔드포인트의 가용성에 초점을 맞춘 Amazon EKS Service SLAs와 완전히 독립적입니다.

Kubernetes에는 CSI 드라이버, 승인 웹후크 및 오토 스케일러와 같은 사용자 지정 추가 기능 또는 드라이버로 시스템을 확장할 수 있는 다양한 기능이 있습니다. 이러한 확장은 다양한 방식으로 Kubernetes 클러스터의 성능에 상당한 영향을 미칠 수 있습니다. 즉,를 사용하는 승인 웹후크는 웹후크 대상을 사용할 수 없는 경우 K8s API 요청에 지연 시간을 추가할 failurePolicy=Ignore 수 있습니다. Kubernetes Scalability SIG는 "You promise, We promise" 프레임워크를 사용하여 확장성을 정의합니다.

Kubernetes SLOs

Kubernetes SLOs는 작업자 노드 조정 또는 승인 웹후크와 같이 클러스터에 영향을 미칠 수 있는 모든 플러그인 및 외부 제한 사항을 고려하지 않습니다. 이러한 SLOs Kubernetes 구성 요소에 초점을 맞추고 Kubernetes 작업 및 리소스가 예상 내에서 작동하는지 확인합니다. SLOs는 Kubernetes 개발자가 Kubernetes 코드 변경으로 인해 전체 시스템의 성능이 저하되지 않도록 하는 데 도움이 됩니다.

Kuberntes Scalability SIG는 다음과 같은 공식 SLO/SLIs 정의합니다. Amazon EKS 팀은 이러한 SLOs/SLIs에 대해 EKS 클러스터에서 정기적으로 확장성 테스트를 실행하여 변경 사항이 적용되고 새 버전이 릴리스될 때 성능 저하를 모니터링합니다.

목표 정의 SLO

API 요청 지연 시간(변환 중)

지난 5분 동안 99번째 백분위수로 측정된 모든 (리소스, 동사) 페어의 단일 객체에 대한 변형 API 호출 처리 지연 시간

기본 Kubernetes 설치에서는 가상 및 집계 리소스와 사용자 지정 리소스 정의를 제외한 모든 (리소스, 동사) 페어에 대해 클러스터 데이당 99번째 백분위수 <= 1초

API 요청 지연 시간(읽기 전용)

지난 5분 동안 99번째 백분위수로 측정된 모든 (리소스, 범위) 페어에 대한 비스트리밍 읽기 전용 API 호출 처리 지연 시간

기본 Kubernetes 설치에서는 가상 및 집계 리소스와 사용자 지정 리소스 정의를 제외한 모든 (리소스, 범위) 페어에 대해 클러스터 데이당 99번째 백분위수: (a) <= 1s if scope=resource (b) <= 30s otherwise ( scope=namespace 또는 scope=cluster)

포드 시작 지연 시간

예약 가능한 상태 비저장 포드의 시작 지연 시간으로, 포드 생성 타임스탬프부터 모든 컨테이너가 시작으로 보고되고 감시를 통해 관찰될 때까지 측정된 이미지를 가져오고 컨테이너를 실행하는 데 걸리는 시간 제외, 지난 5분 동안 99번째 백분위수로 측정

기본 Kubernetes 설치에서 클러스터 데이당 99번째 백분위수 <= 5초

API 요청 지연 시간

kube-apiserver1m0s 기본적으로 로 --request-timeout 정의되어 있습니다. 즉, 제한 시간이 초과되고 취소되기 전에 최대 1분(60초) 동안 요청을 실행할 수 있습니다. 지연 시간에 대해 정의된 SLOs는 변경되거나 읽기 전용일 수 있는 요청 유형에 따라 구분됩니다.

변경

Kubernetes에서 요청을 변경하면 생성, 삭제 또는 업데이트와 같은 리소스가 변경됩니다. 업데이트된 객체가 반환되기 전에 이러한 변경 사항을 etcd 백엔드에 작성해야 하므로 이러한 요청은 비용이 많이 듭니다. Etcd는 모든 Kubernetes 클러스터 데이터에 사용되는 분산 키-값 저장소입니다.

이 지연 시간은 Kubernetes 리소스의 (리소스, 동사) 페어에 대해 5분 동안 99번째 백분위수로 측정됩니다. 예를 들어, 이는 포드 생성 요청 및 노드 업데이트 요청의 지연 시간을 측정합니다. SLO를 충족하려면 요청 지연 시간이 <= 1초여야 합니다.

읽기 전용

읽기 전용 요청은 단일 리소스(예: 포드 X 가져오기) 또는 컬렉션(예: "네임스페이스 X에서 모든 포드 가져오기")을 검색합니다. 는 객체의 캐시를 kube-apiserver 유지하므로 요청된 리소스가 캐시에서 반환되거나 먼저 etcd에서 검색해야 할 수 있습니다. 이러한 지연 시간은 5분 동안 99번째 백분위수로도 측정되지만 읽기 전용 요청에는 별도의 범위가 있을 수 있습니다. SLO는 두 가지 목표를 정의합니다.

  • 단일 리소스(예: kubectl get pod -n mynamespace my-controller-xxx )에 대한 요청의 경우 요청 지연 시간은 <= 1초로 유지되어야 합니다.

  • 네임스페이스 또는 클러스터(예: kubectl get pods -A)의 여러 리소스에 대해 이루어진 요청의 경우 지연 시간은 <= 30초로 유지되어야 합니다.

Kubernetes 리소스 목록에 대한 요청은 요청의 모든 객체에 대한 세부 정보를 SLO 내에서 반환할 것으로 예상하기 때문에 SLO의 요청 범위는 서로 다릅니다. 대규모 클러스터 또는 대규모 리소스 모음에서 이로 인해 응답 크기가 커져 반환하는 데 다소 시간이 걸릴 수 있습니다. 예를 들어 JSON으로 인코딩될 때 각 포드가 약 1KiB인 수만 개의 포드를 실행하는 클러스터에서 클러스터의 모든 포드를 반환하는 작업은 10MB 이상으로 구성됩니다. Kubernetes 클라이언트는 APIListChunking을 사용하여 대규모 리소스 컬렉션을 검색하여이 응답 크기를 줄이는 데 도움이 될 수 있습니다.

포드 시작 지연 시간

이 SLO는 주로 포드 생성부터 해당 포드의 컨테이너가 실제로 실행을 시작하는 데 걸리는 시간과 관련이 있습니다. 이를 측정하기 위해 포드에 기록된 생성 타임스탬프와 차이를 측정하고 해당 포드의 WATCH가 컨테이너가 시작되었음을 보고하는 시점을 계산합니다(컨테이너 이미지 가져오기 및 컨테이너 실행 시작 시간 제외). SLO를 충족하려면이 포드 시작 지연 시간의 클러스터-일당 99번째 백분위수가 <=5초로 유지되어야 합니다.

이 SLO는 포드를 예약할 준비가 된 상태로이 클러스터에 작업자 노드가 이미 있다고 가정합니다. 이 SLO는 이미지 가져오기 또는 컨테이너 실행 시작을 고려하지 않으며 테스트를 영구 스토리지 플러그인을 활용하지 않는 "상태 비저장 포드"로 제한합니다.

Kubernetes SLI 지표

또한 Kubernetes는 시간 경과에 따라 이러한 SLIs 추적하는 Kubernetes 구성 요소에 Prometheus 지표를 추가하여 SLIs에 대한 관찰성을 개선하고 있습니다. Prometheus 쿼리 언어(PromQL)를 사용하면 Prometheus 또는 Grafana 대시보드와 같은 도구에서 시간 경과에 따른 SLI 성능을 표시하는 쿼리를 구축할 수 있습니다. 다음은 위의 SLOs에 대한 몇 가지 예입니다.

API 서버 요청 지연 시간

지표 정의

apiserver_request_sli_duration_seconds

각 동사, 그룹, 버전, 리소스, 하위 리소스, 범위 및 구성 요소에 대한 응답 지연 시간 분포(웹후크 기간 및 우선 순위 및 공정성 대기열 대기 시간은 계산하지 않음)입니다.

apiserver_request_duration_seconds

각 동사, 드라이 런 값, 그룹, 버전, 리소스, 하위 리소스, 범위 및 구성 요소에 대한 응답 지연 시간 분포(초 단위).

참고: apiserver_request_sli_duration_seconds 지표는 Kubernetes 1.27부터 사용할 수 있습니다.

이러한 지표를 사용하여 API 서버 응답 시간과 Kubernetes 구성 요소 또는 기타 플러그인/구성 요소에 병목 현상이 있는지 조사할 수 있습니다. 아래 쿼리는 커뮤니티 SLO 대시보드를 기반으로 합니다.

API 요청 지연 시간 SLI(변환 중) -이 시간에는 웹후크 실행 또는 대기열 대기 시간이 포함되지 않습니다. histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

API 요청 지연 시간 합계(변환) - 요청이 API 서버에서 소요된 총 시간입니다.이 시간은 웹후크 실행과 API 우선 순위 및 공정성 대기 시간을 포함하므로 SLI 시간보다 길 수 있습니다. histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

이러한 쿼리에서는 kubectl port-forward 또는 요청(subresource!~"proxy|attach|log|exec|portforward")과 같이 즉시 반환되지 않는 스트리밍 API kubectl exec 요청을 제외하며 객체를 수정하는 Kubernetes 동사()에 대해서만 필터링합니다verb=~"CREATE|DELETE|PATCH|POST|PUT". 그런 다음 지난 5분 동안 해당 지연 시간의 99번째 백분위수를 계산합니다.

읽기 전용 API 요청에 유사한 쿼리를 사용할 수 있으며, 필터링하려는 동사를 수정하여 읽기 전용 작업 LIST 및를 포함할 수 있습니다GET. 요청 범위에 따라 단일 리소스를 가져오거나 여러 리소스를 나열하는 등 다양한 SLO 임계값도 있습니다.

API 요청 지연 시간 SLI(읽기 전용) -이 시간에는 웹후크 실행 또는 대기열 대기 시간이 포함되지 않습니다. 단일 리소스의 경우(범위=리소스, 임계값=1초) histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

동일한 네임스페이스(scope=namespace, threshold=5s)에 있는 리소스 모음의 경우 histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

전체 클러스터의 리소스 모음(범위=클러스터, 임계값=30초) histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

API 요청 지연 시간 합계(읽기 전용) - API 서버에서 요청이 걸린 총 시간입니다.이 시간은 웹후크 실행 및 대기 시간을 포함하므로 SLI 시간보다 길 수 있습니다. 단일 리소스의 경우(범위=리소스, 임계값=1초) histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

동일한 네임스페이스(scope=namespace, threshold=5s)에 있는 리소스 모음의 경우 histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

전체 클러스터의 리소스 모음(범위=클러스터, 임계값=30초) histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

SLI 지표는 요청이 API 우선 순위 및 공정성 대기열에서 대기하거나 승인 웹후크 또는 기타 Kubernetes 확장을 통해 작업하는 데 소요되는 시간을 제외하여 Kubernetes 구성 요소가 어떻게 작동하는지에 대한 인사이트를 제공합니다. 총 지표는 애플리케이션이 API 서버의 응답을 기다리는 시간을 반영하므로 보다 전체적인 보기를 제공합니다. 이러한 지표를 비교하면 요청 처리 지연이 발생하는 위치를 파악할 수 있습니다.

포드 시작 지연 시간

지표 정의

kubelet_pod_start_sli_duration_seconds

포드 생성 타임스탬프부터 모든 컨테이너가 시작됨으로 보고되고 감시를 통해 관찰될 때까지 측정된 이미지를 가져오고 초기화 컨테이너를 실행하는 시간을 제외하고 포드를 시작하는 초 단위의 기간

kubelet_pod_start_duration_seconds

포드가 처음 표시되는 kubelet부터 포드가 실행되기 시작하는 시점까지의 초 단위 기간입니다. 여기에는 포드를 예약하거나 작업자 노드 용량을 스케일 아웃하는 데 걸리는 시간은 포함되지 않습니다.

참고: kubelet_pod_start_sli_duration_seconds는 Kubernetes 1.27부터 사용할 수 있습니다.

위의 쿼리와 마찬가지로 이러한 지표를 사용하여 Kubelet 작업과 비교하여 노드 크기 조정, 이미지 가져오기 및 초기화 컨테이너가 포드 시작을 지연시키는 시간을 파악할 수 있습니다.

포드 시작 지연 시간 SLI - 포드가 생성된 시점부터 애플리케이션 컨테이너가 실행 중인 것으로 보고된 시점까지의 시간입니다. 여기에는 작업자 노드 용량을 사용할 수 있는 데 걸리는 시간과 포드를 예약하는 데 걸리는 시간이 포함되지만 이미지를 가져오거나 초기화 컨테이너를 실행하는 데 걸리는 시간은 포함되지 않습니다. histogram_quantile(0.99, sum(rate(kubelet_pod_start_sli_duration_seconds_bucket[5m])) by (le))

포드 시작 지연 시간 합계 - 포드를 처음 시작하는 데 kubelet이 걸리는 시간입니다. 이는 작업자 노드 조정 또는 예약 시간이 포함되지 않은 WATCH를 통해 kubelet이 포드를 수신하는 시점부터 측정됩니다. 여기에는 이미지를 가져오고 실행할 컨테이너를 초기화하는 시간이 포함됩니다. histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket[5m])) by (le))

클러스터SLOs

EKS 클러스터의 Kubernetes 리소스에서 Prometheus 지표를 수집하는 경우 Kubernetes 컨트롤 플레인 구성 요소의 성능에 대한 심층적인 인사이트를 얻을 수 있습니다.

성능 테스트 리포지토리에는 테스트 중에 클러스터의 지연 시간 및 중요 성능 지표를 표시하는 Grafana 대시보드가 포함되어 있습니다. 성능 테스트 구성은 Kubernetes 지표를 수집하도록 구성된 오픈 소스 프로젝트인 kube-prometheus-stack을 활용하지만 Amazon Managed Prometheus 및 Amazon Managed Grafana를 사용할 수도 있습니다.

kube-prometheus-stack 또는 유사한 Prometheus 솔루션을 사용하는 경우 동일한 대시보드를 설치하여 클러스터의 SLOs를 실시간으로 관찰할 수 있습니다.

  1. 먼저에서 대시보드에 사용되는 Prometheus 규칙을 설치해야 합니다kubectl apply -f prometheus-rules.yaml. https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/pkg/prometheus/manifests/prometheus-rules.yaml 규칙 사본을 다운로드할 수 있습니다.

    1. 파일의 네임스페이스가 환경과 일치하는지 확인합니다.

    2. 를 사용하는 경우 레이블이 prometheus.prometheusSpec.ruleSelector helm 값과 일치하는지 확인합니다. kube-prometheus-stack

  2. 그런 다음 Grafana에 대시보드를 설치할 수 있습니다. json 대시보드와 이를 생성하는 python 스크립트는 https://github.com/kubernetes/perf-tests/tree/master/clusterloader2/pkg/prometheus/manifests/dashboards 확인할 수 있습니다.

    1. slo.json 대시보드는 Kubernetes SLOs

SLOs는 클러스터에 있는 Kubernetes 구성 요소의 성능에 초점을 맞추고 있지만 클러스터에 다양한 관점이나 인사이트를 제공하는 추가 지표를 검토할 수 있습니다. Kube-state-metrics 커뮤니티 프로젝트는 클러스터의 추세를 빠르게 분석하는 데 도움이 될 수 있습니다. Kubernetes 커뮤니티의 대부분의 일반적인 플러그인 및 드라이버는 Prometheus 지표도 생성하므로 오토스케일러 또는 사용자 지정 스케줄러와 같은 항목을 조사할 수 있습니다.

관찰성 모범 사례 가이드에는 추가 인사이트를 얻는 데 사용할 수 있는 다른 Kubernetes 지표의 예가 나와 있습니다.