기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
EKS 데이터 영역
가용성과 복원력이 뛰어난 애플리케이션을 운영하려면 가용성과 복원력이 뛰어난 데이터 영역이 필요합니다. 탄력적 데이터 영역은 Kubernetes가 애플리케이션을 자동으로 확장하고 복구할 수 있도록 합니다. 복원력이 뛰어난 데이터 영역은 두 개 이상의 작업자 노드로 구성되며, 워크로드에 따라 확장 및 축소할 수 있고, 장애로부터 자동으로 복구할 수 있습니다.
EKS를 사용하는 작업자 노드에는 EC2 인스턴스와 Fargate라는 두 가지 옵션이 있습니다. EC2 인스턴스를 선택하는 경우 작업자 노드를 직접 관리하거나 EKS 관리형 노드 그룹을 사용할 수 있습니다. 관리형 자체 관리형 작업자 노드와 Fargate가 혼합된 클러스터를 보유할 수 있습니다.
Fargate의 EKS는 복원력이 뛰어난 데이터 영역으로 가는 가장 쉬운 경로를 제공합니다. Fargate는 격리된 컴퓨팅 환경에서 각 포드를 실행합니다. Fargate에서 실행되는 각 포드는 자체 작업자 노드를 가져옵니다. Kubernetes가 포드를 조정하면 Fargate는 데이터 영역을 자동으로 조정합니다. 가로 포드 오토스케일러를 사용하여 데이터 영역과 워크로드를 모두 확장할 수 있습니다.
EC2 워커 노드를 확장하는 가장 좋은 방법은 Kubernetes Cluster Autoscaler
추천
EC2 Auto Scaling 그룹을 사용하여 작업자 노드 생성
개별 EC2 인스턴스를 생성하고 클러스터에 조인하는 대신 EC2 Auto Scaling 그룹을 사용하여 작업자 노드를 생성하는 것이 모범 사례입니다. Auto Scaling 그룹은 종료되거나 장애가 발생한 노드를 자동으로 교체하여 클러스터에 항상 워크로드를 실행할 수 있는 용량이 있도록 합니다.
Kubernetes Cluster Autoscaler를 사용하여 노드 규모 조정
Cluster Autoscaler는 클러스터에 리소스가 부족하여 실행할 수 없는 포드가 있을 때 데이터 영역의 크기를 조정하며, 다른 작업자 노드를 추가하면 도움이 됩니다. Cluster Autoscaler는 사후 대응 프로세스이지만 클러스터의 용량이 부족하여 포드가 보류 중 상태가 될 때까지 기다립니다. 이러한 이벤트가 발생하면 EC2 인스턴스가 클러스터에 추가됩니다. 클러스터의 용량이 부족할 때마다 작업자 노드가 추가될 때까지 새 복제본 또는 새 포드를 사용할 수 없습니다(보류 중 상태). 이러한 지연은 데이터 영역이 워크로드의 요구 사항을 충족할 만큼 빠르게 확장할 수 없는 경우 애플리케이션의 신뢰성에 영향을 미칠 수 있습니다. 작업자 노드가 지속적으로 활용도가 낮고 모든 포드를 다른 작업자 노드에서 예약할 수 있는 경우 Cluster Autoscaler는 이를 종료합니다.
Cluster Autoscaler를 사용하여 오버프로비저닝 구성
클러스터 Autoscaler는 클러스터의 포드가 이미 보류 중일 때 데이터 영역의 스케일 업을 트리거합니다. 따라서 애플리케이션에 더 많은 복제본이 필요한 시점과 실제로 더 많은 복제본을 가져오는 시점 사이에 지연이 있을 수 있습니다. 이 지연 가능성을 고려하는 옵션은 필요한 복제본을 초과하여 추가하고 애플리케이션의 복제본 수를 부풀리는 것입니다.
Cluster Autoscaler가 권장하는 또 다른 패턴은 일시 중지 포드와 우선 순위 선점 기능을
여러 Auto Scaling 그룹에서 Cluster Autoscaler 사용
--node-group-auto-discovery
플래그가 활성화된 상태에서 Cluster Autoscaler를 실행합니다. 이렇게 하면 Cluster Autoscaler가 정의된 특정 태그가 포함된 모든 Autoscaling 그룹을 찾을 수 있으며 매니페스트에서 각 Autoscaling 그룹을 정의하고 유지 관리할 필요가 없습니다.
로컬 스토리지에서 Cluster Autoscaler 사용
기본적으로 Cluster Autoscaler는 로컬 스토리지가 연결된 상태로 배포된 포드가 있는 노드를 스케일 다운하지 않습니다. --skip-nodes-with-local-storage
플래그를 false로 설정하여 Cluster Autoscaler가 이러한 노드를 스케일 다운할 수 있도록 합니다.
여러 AZs에 작업자 노드 및 워크로드 분산
여러 AZ에서 작업자 노드와 포드를 실행하여 개별 AZ의 장애로부터 워크로드를 보호할 수 AZs. 노드를 생성하는 서브넷을 사용하여 작업자 노드가 생성되는 AZ를 제어할 수 있습니다.
Kubernetes 1.18 이상을 사용하는 경우 AZs 간에 포드를 분산하는 데 권장되는 방법은 포드에 토폴로지 분산 제약 조건을
아래 배포는 가능하면 AZs에 포드를 분산시켜 해당 포드가 실행되도록 합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
replicas: 3
selector:
matchLabels:
app: web-server
template:
metadata:
labels:
app: web-server
spec:
topologySpreadConstraints:
- maxSkew: 1
whenUnsatisfiable: ScheduleAnyway
topologyKey: topology.kubernetes.io/zone
labelSelector:
matchLabels:
app: web-server
containers:
- name: web-app
image: nginx
resources:
requests:
cpu: 1
참고
kube-scheduler
는 해당 레이블과 함께 존재하는 노드를 통한 토폴로지 도메인만 인식합니다. 위의 배포가 단일 영역에 노드만 있는 클러스터에 배포되는 경우 모든 포드는 다른 영역을 인식하지 kube-scheduler
못하므로 해당 노드에서 일정을 잡습니다. 이 토폴로지가 스케줄러에서 예상대로 작동하려면 노드가 모든 영역에 이미 있어야 합니다. 이 문제는 Kubernetes 1.24에서 해결되며minDomains
, 속성 지정을 통해 스케줄러에 적격 도메인 수를 알릴 수 있는 MinDomainsInPodToplogySpread
기능 게이트
주의
whenUnsatisfiable
로 설정DoNotSchedule
하면 토폴로지 분산 제약 조건을 충족할 수 없는 경우 포드를 예약할 수 없습니다. 토폴로지 분산 제약을 위반하는 대신 포드가 실행되지 않도록 하려면 설정해야 합니다.
이전 버전의 Kubernetes에서는 포드 안티 친화도 규칙을 사용하여 여러 AZs. 아래 매니페스트는 Kubernetes 스케줄러가 개별 AZs에서 포드를 예약하는 것을 선호하도록 알려줍니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
labels:
app: web-server
spec:
replicas: 4
selector:
matchLabels:
app: web-server
template:
metadata:
labels:
app: web-server
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-server
topologyKey: failure-domain.beta.kubernetes.io/zone
weight: 100
containers:
- name: web-app
image: nginx
주의
포드를 서로 다른 AZs에 예약하도록 요구하지 마십시오. 그렇지 않으면 배포의 포드 수가 AZs 수를 초과하지 않습니다.
EBS 볼륨을 사용할 때 각 AZ의 용량 확인
Amazon EBS를 사용하여 영구 볼륨을 제공하는 경우 포드와 연결된 EBS 볼륨이 동일한 AZ에 있는지 확인해야 합니다. 작성 시 EBS 볼륨은 단일 AZ 내에서만 사용할 수 있습니다. 포드는 다른 AZ에 있는 EBS 지원 영구 볼륨에 액세스할 수 없습니다. Kubernetes 스케줄러는 작업자 노드가 있는 AZ를 알고
클러스터가 항상 필요한 EBS 볼륨과 동일한 AZ에서 포드를 예약할 수 있는 용량을 확보할 수 있도록 용량이 충분한 각 AZ에 대해 Auto Scaling 그룹을 생성합니다. 또한 Cluster Autoscaler에서 --balance-similar-node-groups
기능을 활성화해야 합니다.
EBS 볼륨을 사용하지만 고가용성 요구 사항이 없는 애플리케이션을 실행하는 경우 애플리케이션 배포를 단일 AZ로 제한할 수 있습니다. EKS에서는 작업자 노드에 AZ 이름이 포함된 failure-domain.beta.kubernetes.io/zone
레이블이 자동으로 추가됩니다. 를 실행하여 노드에 연결된 레이블을 볼 수 있습니다kubectl get nodes --show-labels
. 기본 제공 노드 레이블에 대한 자세한 내용은 여기에서
아래 예제에서는 포드가 us-west-2c
AZ에서만 예약됩니다.
apiVersion: v1
kind: Pod
metadata:
name: single-az-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: failure-domain.beta.kubernetes.io/zone
operator: In
values:
- us-west-2c
containers:
- name: single-az-container
image: kubernetes/pause
영구 볼륨(EBS 지원)은 AZ 이름으로 자동 레이블이 지정됩니다.를 실행하면 영구 볼륨이 속한 AZ를 확인할 수 있습니다kubectl get pv -L topology.ebs.csi.aws.com/zone
. 포드가 생성되고 볼륨을 클레임하면 Kubernetes는 볼륨과 동일한 AZ의 노드에서 포드를 예약합니다.
이 시나리오를 고려해 보세요. 노드 그룹이 하나인 EKS 클러스터가 있습니다. 이 노드 그룹에는 3개의 AZs. EBS 지원 영구 볼륨을 사용하는 애플리케이션이 있습니다. 이 애플리케이션과 해당 볼륨을 생성하면 해당 포드가 세 AZs 중 첫 번째 AZ에 생성됩니다. 그런 다음이 포드를 실행하는 작업자 노드가 비정상이 되어 나중에 사용할 수 없게 됩니다. Cluster Autoscaler는 비정상 노드를 새 작업자 노드로 대체합니다. 그러나 Autoscaling 그룹은 세 개의 AZs에 걸쳐 있으므로 새 작업자 노드는 두 번째 또는 세 번째 AZ에서 시작될 수 있지만 상황에 따라 첫 번째 AZ에서는 시작되지 않을 수 있습니다. AZ 제약 EBS 볼륨은 첫 번째 AZ에만 존재하지만 해당 AZ에 사용할 수 있는 작업자 노드가 없으므로 포드를 예약할 수 없습니다. 따라서 각 AZ에 하나의 노드 그룹을 생성해야 합니다. 따라서 다른 AZ에서 예약할 수 없는 포드를 실행할 수 있는 용량이 항상 충분AZs.
또는 EFS
노드 모니터링 에이전트에서 노드 문제 감지
작업자 노드에 장애가 발생하면 애플리케이션의 가용성에 영향을 미칠 수 있습니다. 노드 모니터링 에이전트를 사용하여 상태 문제를 감지하고 표시할 수 있습니다. 문제가 감지되면 노드 자동 복구를 활성화하여 노드를 자동으로 교체할 수도 있습니다.
노드 모니터링 에이전트는 모든 Amazon EKS Auto Mode 클러스터의 기능으로 포함됩니다. 다른 클러스터 유형의 경우 모니터링 에이전트를 Amazon EKS 추가 기능으로 추가할 수 있습니다. 자세한 내용은 Amazon EKS 사용 설명서의 노드 자동 복구 활성화 및 노드 상태 문제 조사를 참조하세요.
시스템 및 Kubernetes 데몬에 대한 리소스 예약
운영 체제 및 Kubernetes 데몬의 컴퓨팅 용량을 예약limits
선언되지 않은 포드는 시스템 리소스를 포화시켜 운영 체제 프로세스 및 Kubernetes 데몬(kubelet
, 컨테이너 런타임 등)이 시스템 리소스용 포드와 경쟁하는 상황에 노드를 배치할 수 있습니다. kubelet
플래그 --system-reserved
및 --kube-reserved
를 사용하여 시스템 프로세스(udev
, sshd
등) 및 Kubernetes 데몬에 대한 리소스를 각각 예약할 수 있습니다.
EKS 최적화 Linux AMI를 사용하는 경우 CPU, 메모리 및 스토리지는 기본적으로 시스템 및 Kubernetes 데몬용으로 예약됩니다. 이 AMI를 기반으로 하는 작업자 노드가 시작되면 EC2 사용자 데이터가 bootstrap.sh
스크립트KubeletConfiguration
파일에 기록됩니다/etc/kubernetes/kubelet/kubelet-config.json
.
노드에서 사용자 지정 데몬을 실행하고 기본적으로 예약된 CPU 및 메모리 양이 충분하지 않은 경우 시스템 리소스 예약을 늘려야 할 수 있습니다.
eksctl
는 시스템 및 Kubernetes 데몬에 대한 리소스 예약을
QoS 구현
중요한 애플리케이션의 경우 포드의 컨테이너에 대해 requests
=limits
를 정의하는 것이 좋습니다. 이렇게 하면 다른 포드가 리소스를 요청할 때 컨테이너가 종료되지 않습니다.
컨테이너가 실수로 시스템 리소스를 소비하여 다른 공동 위치 프로세스의 가용성에 영향을 미치는 것을 방지하므로 모든 컨테이너에 대해 CPU 및 메모리 제한을 구현하는 것이 모범 사례입니다.
모든 워크로드에 대한 리소스 요청/제한 구성 및 크기 조정
일부 일반 지침은 워크로드에 대한 리소스 요청 크기 조정 및 제한에 적용될 수 있습니다.
-
CPU에 리소스 제한을 지정하지 마십시오. 제한이 없는 경우 요청은 컨테이너가 받는 상대 CPU 시간 양
에 대한 가중치 역할을 합니다. 이를 통해 워크로드는 인공적인 제한이나 결핍 없이 전체 CPU를 사용할 수 있습니다. -
비 CPU 리소스의 경우
requests
=limits
를 구성하면 가장 예측 가능한 동작이 제공됩니다.requests
!=limits
인 경우 컨테이너의 QOS도 보장에서 버스트 가능으로 감소하여 노드 압력이 발생할 경우 제거될 가능성이 높아집니다. -
비 CPU 리소스의 경우 요청보다 훨씬 큰 제한을 지정하지 마십시오. 에 비해 더 크게
limits
구성될requests
수록 노드가 과도하게 커밋되어 워크로드 중단 가능성이 높아집니다. -
올바른 크기의 요청은 Karpenter
또는 Cluster AutoScaler 와 같은 노드 Auto Scaling 솔루션을 사용할 때 특히 중요합니다. 이러한 도구는 워크로드 요청을 검토하여 프로비저닝할 노드의 수와 크기를 결정합니다. 요청이 너무 작아서 제한이 큰 경우 워크로드가 제거되거나 노드에 밀접하게 압축된 경우 OOM이 종료될 수 있습니다.
리소스 요청을 확인하는 것은 어려울 수 있지만 Vertical Pod Autoscaler
네임스페이스에 대한 리소스 할당량 구성
네임스페이스는 많은 사용자가 여러 팀 또는 프로젝트에 분산되어 있는 환경에서 사용하기 위한 것입니다. 이름 범위를 제공하며 여러 팀, 프로젝트, 워크로드 간에 클러스터 리소스를 분할하는 방법입니다. 네임스페이스에서 집계 리소스 소비를 제한할 수 있습니다. ResourceQuota
CPU 및 메모리와 같은 컴퓨팅 리소스의 네임스페이스에 리소스 할당량이 활성화된 경우 사용자는 해당 네임스페이스의 각 컨테이너에 대한 요청 또는 제한을 지정해야 합니다.
각 네임스페이스에 대한 할당량을 구성하는 것이 좋습니다. LimitRanges
를 사용하여 네임스페이스 내의 컨테이너에 사전 구성된 제한을 자동으로 적용하는 것이 좋습니다.
네임스페이스 내에서 컨테이너 리소스 사용량 제한
Resource Quotas는 네임스페이스가 사용할 수 있는 리소스의 양을 제한하는 데 도움이 됩니다. LimitRange
객체LimitRange
수 있습니다. 이는 컴퓨팅 리소스 제한을 설정하는 것이 조직의 표준 관행이 아닌 경우 유용합니다. 이름에서 알 수 있듯이 LimitRange
는 네임스페이스의 포드 또는 컨테이너당 최소 및 최대 컴퓨팅 리소스 사용량을 적용할 수 있습니다. 또한 네임스페이스에서 PersistentVolumeClaim당 최소 및 최대 스토리지 요청을 적용합니다.
컨테이너 및 네임스페이스 수준에서 제한을 적용ResourceQuota
하려면와 LimitRange
함께를 사용하는 것이 좋습니다. 이러한 제한을 설정하면 컨테이너 또는 네임스페이스가 클러스터의 다른 테넌트가 사용하는 리소스에 영향을 주지 않습니다.
CoreDNS
CoreDNS는 Kubernetes에서 이름 확인 및 서비스 검색 기능을 수행합니다. 기본적으로 EKS 클러스터에 설치됩니다. 상호 운용성을 위해 CoreDNS용 Kubernetes Service의 이름은 여전히 kube-dnskube-system
네임스페이스의 배포의 일부로 실행되며, 기본적으로 EKS에서는 선언된 요청 및 제한과 함께 두 개의 복제본을 실행합니다. DNS 쿼리는 kube-system
네임스페이스에서 실행되는 kube-dns
서비스로 전송됩니다.
추천
CoreDNS 지표 모니터링
CoreDNS는 Prometheuscoredns_dns_request_duration_seconds_sum
이전에는 지표가 라고 함core_dns_response_rcode_count_total
), 오류(coredns_dns_responses_total
, NXDOMAIN, SERVFAIL, FormErr) 및 CoreDNS 포드의 메모리 소비를 모니터링하는 것을 고려해야 합니다.
문제 해결을 위해 kubectl을 사용하여 CoreDNS 로그를 볼 수 있습니다.
for p in $(kubectl get pods -n kube-system -l k8s-app=kube-dns -o jsonpath='{.items[*].metadata.name}'); do kubectl logs $p -n kube-system; done
NodeLocal DNSCache 사용
NodeLocal DNSCachekube-dns
서비스를 사용하는 대신 이름 확인을 위해 노드에서 실행되는 DNS 캐싱 에이전트를 사용합니다.
CoreDNS에 대한 cluster-proportional-scaler 구성
클러스터 DNS 성능을 개선하는 또 다른 방법은 클러스터의 노드 및 CPU 코어 수에 따라 CoreDNS 배포를 자동으로 수평적으로 조정
노드와 노드의 CPU 코어 집계는 CoreDNS를 확장할 수 있는 두 가지 지표입니다. 두 지표를 동시에 사용할 수 있습니다. 더 큰 노드를 사용하는 경우 CoreDNS 조정은 CPU 코어 수를 기반으로 합니다. 반면 더 작은 노드를 사용하는 경우 CoreDNS 복제본 수는 데이터 영역의 CPU 코어에 따라 달라집니다. 비례 Autoscaler 구성은 다음과 같습니다.
linear: '{"coresPerReplica":256,"min":1,"nodesPerReplica":16}'
노드 그룹이 있는 AMI 선택
EKS는 고객이 자체 관리형 노드 그룹과 관리형 노드 그룹을 모두 생성하는 데 사용하는 최적화된 EC2 AMIs를 제공합니다. 이러한 AMIs는 지원되는 모든 Kubernetes 버전에 대해 모든 리전에 게시됩니다. EKS는 CVEs 또는 버그가 발견될 때 이러한 AMIs를 더 이상 사용되지 않는 것으로 표시합니다. 따라서 노드 그룹에 대한 AMIs를 선택하는 동안 더 이상 사용되지 않는 AMI를 사용하지 않는 것이 좋습니다.
더 이상 사용되지 않는 AMIs는 아래 명령을 사용하여 Ec2 describe-images api를 사용하여 필터링할 수 있습니다.
aws ec2 describe-images --image-id ami-0d551c4f633e7679c --no-include-deprecated
설명 이미지 출력에 DeprecationTime이 필드로 포함되어 있는지 확인하여 더 이상 사용되지 않는 AMI를 인식할 수도 있습니다. 예:
aws ec2 describe-images --image-id ami-xxx --no-include-deprecated
{
"Images": [
{
"Architecture": "x86_64",
"CreationDate": "2022-07-13T15:54:06.000Z",
"ImageId": "ami-xxx",
"ImageLocation": "123456789012/eks_xxx",
"ImageType": "machine",
"Public": false,
"OwnerId": "123456789012",
"PlatformDetails": "Linux/UNIX",
"UsageOperation": "RunInstances",
"State": "available",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"DeleteOnTermination": true,
"SnapshotId": "snap-0993a2fc4bbf4f7f4",
"VolumeSize": 20,
"VolumeType": "gp2",
"Encrypted": false
}
}
],
"Description": "EKS Kubernetes Worker AMI with AmazonLinux2 image, (k8s: 1.19.15, docker: 20.10.13-2.amzn2, containerd: 1.4.13-3.amzn2)",
"EnaSupport": true,
"Hypervisor": "xen",
"Name": "aws_eks_optimized_xxx",
"RootDeviceName": "/dev/xvda",
"RootDeviceType": "ebs",
"SriovNetSupport": "simple",
"VirtualizationType": "hvm",
"DeprecationTime": "2023-02-09T19:41:00.000Z"
}
]
}