개발자의 통찰력: 수직 및 수평 Pod 자동 확장 탐색

개발자의 통찰력: 수직 및 수평 Pod 자동 확장 탐색

科技

우리는 환경 중 하나에서 리소스 부족을 겪고 있으며, 이로 인해 처리가 지연되었습니다. 이 문제는 RabbitMQ 대기열에서 부하가 갑자기 급증하여 대기열 소비를 처리하기 위해 작업자를 늘려야 하기 때문에 발생합니다.

우리 프로젝트는 마이크로서비스 기반 아키텍처를 중심으로 진행되며 Celery, RabbitMQ, Redis, MinIO, MongoDB, Postgres 등 다양한 서비스를 활용합니다.

RabbitMQ에서 대기 중인 작업 요소의 수가 증가함에 따라 단일 작업자는 증가된 부하를 처리할 수 없으며, 이는 개별 작업자의 리소스 소비에도 영향을 미칩니다. 이러한 문제를 해결하기 위해 수평 포드 자동 확장(HPA) 및 수직 포드 자동 확장(VPA)을 사용합니다.

이전에는 이 프로세스에 상당한 수동 개입이 필요했습니다. 개발자는 리소스 사용량을 지속적으로 모니터링하고 부하가 증가할 때마다 수동으로 작업자를 확장해야 했습니다. 이 접근 방식은 시간이 많이 걸리고 비효율적이어서 귀중한 개발자 시간과 주의를 다른 중요한 작업에서 돌렸습니다.

이러한 과제를 해결하기 위해 우리는 Kubernetes의 자동 확장 기능을 활용했습니다. Vertical Pod Autoscaling(VPA)과 Horizontal Pod Autoscaling(HPA)을 모두 구현하여 더욱 탄력적이고 반응성이 뛰어난 시스템을 만들고자 했습니다. VPA는 실제 사용량에 따라 Pod의 리소스 한도를 조정하여 각 Pod가 효율적으로 수행하는 데 필요한 CPU와 메모리를 확보하도록 합니다. 한편, HPA는 CPU 사용률이나 RabbitMQ 대기열 길이와 같은 사용자 지정 메트릭과 같은 메트릭을 기반으로 Pod 복제본의 수를 동적으로 확장합니다.

이러한 두 가지 접근 방식을 통해 다양한 하중을 보다 효과적으로 처리하고, 수동 개입을 줄이고, 전반적인 시스템 성능을 개선할 수 있었습니다.

수직 Pod 자동 확장(VPA) 구현

수직 Pod 자동 확장(VPA)은 Pod의 리소스 사용량, 특히 CPU와 메모리를 모니터링하는 것을 포함합니다. VPA를 구현하기 위해 사용자 정의 리소스 정의(CRD) 설치와 여러 배포를 포함하는 Kubernetes의 기본 툴셋을 활용합니다. 이러한 구성 요소는 리소스 사용량을 모니터링하고 Pod의 리소스 제한을 자동으로 조정하여 실제 수요에 따라 적절한 양의 CPU와 메모리를 확보하도록 함께 작동합니다. 이를 통해 Kubernetes 환경 내에서 최적의 성능과 리소스 효율성을 유지하는 데 도움이 됩니다.

CRD 설치: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler

위 링크는 Vertical Pod Autoscaling의 필수 요소를 설치하는 데 도움이 됩니다.

CRD를 설치한 후에는 수직적 Pod 모니터링과 자동 확장을 활성화하는 데 필요한 세 가지 주요 배포가 필요합니다.

세 가지 배포는 다음과 같습니다.

  • VPA 입학 관리자

추천인 – 현재 및 과거 리소스 소비량을 모니터링하고 이를 기반으로 컨테이너의 CPU 및 메모리 요청에 대한 권장 값을 제공합니다.

업데이터 – 관리되는 Pod 중 어느 것에 올바른 리소스가 설정되어 있는지 확인하고, 그렇지 않은 경우 Pod를 종료하여 컨트롤러가 업데이트된 요청으로 Pod를 다시 생성할 수 있도록 합니다.

입학 플러그인 – 새로운 Pod(Updater의 활동으로 인해 컨트롤러가 새로 생성하거나 다시 생성한 Pod)에 올바른 리소스 요청을 설정합니다.

이러한 배포를 설치하려면 위 링크에 언급된 프로젝트를 설치하거나 이러한 YAML 파일을 사용할 수 있습니다.

VPA 입학 관리자 Yaml:

apiVersion: apps/v1 
kind: Deployment
metadata:
name: vpa-admission-controller
namespace: kube-system
labels:
app: vpa-admission-controller
spec:
replicas: 1
selector:
matchLabels:
app: vpa-admission-controller
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
template:
metadata:
labels:
app: vpa-admission-controller
spec:
containers:
- name: admission-controller
image: registry.k8s.io/autoscaling/vpa-admission-controller:1.1.2
imagePullPolicy: Always
ports:
- containerPort: 8000
protocol: TCP
- containerPort: 8944
name: prometheus
protocol: TCP
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 50m
memory: 200Mi
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /etc/tls-certs
name: tls-certs
readOnly: true
securityContext:
runAsNonRoot: true
runAsUser: 65534
serviceAccountName: vpa-admission-controller
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes:
- name: tls-certs
secret:
secretName: vpa-tls-certs

VPA 추천자

apiVersion: apps/v1 
kind: Deployment
metadata:
name: vpa-recommender
namespace: kube-system
labels:
app: vpa-recommender
spec:
replicas: 1
selector:
matchLabels:
app: vpa-recommender
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
template:
metadata:
labels:
app: vpa-recommender
spec:
containers:
- name: recommender
image: registry.k8s.io/autoscaling/vpa-recommender:1.1.2
imagePullPolicy: Always
ports:
- containerPort: 8942
name: prometheus
protocol: TCP
resources:
limits:
cpu: 200m
memory: 1000Mi
requests:
cpu: 50m
memory: 500Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
securityContext:
runAsNonRoot: true
runAsUser: 65534
serviceAccountName: vpa-recommender
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler

VPA 업데이터

apiVersion: apps/v1 
kind: Deployment
metadata:
name: vpa-updater
namespace: kube-system
labels:
app: vpa-updater
spec:
replicas: 1
selector:
matchLabels:
app: vpa-updater
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
template:
metadata:
labels:
app: vpa-updater
spec:
containers:
- name: updater
image: registry.k8s.io/autoscaling/vpa-updater:1.1.2
imagePullPolicy: Always
ports:
- containerPort: 8943
name: prometheus
protocol: TCP
resources:
limits:
cpu: 200m
memory: 1000Mi
requests:
cpu: 50m
memory: 500Mi
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
securityContext:
runAsNonRoot: true
runAsUser: 65534
serviceAccountName: vpa-updater
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler

이러한 배포를 추가하면 배포 중 하나의 비밀에 사용되는 vpa-tls-cert.yaml이라는 비밀 파일이 필요합니다.

Vpa-tls-cert.yaml

apiVersion: v1 
data:
caCert.pem: >-
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNRENDQWhpZ0F3SUJBZ0lVWmQvQzNURmNrbXM5eXpRMEowK2E3VVRkK0ZFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0dURVhNQlVHQTFVRUF3d09kbkJoWDNkbFltaHZiMnRmWTJFd0lCY05NalF3TlRJME1USXdPVFEwV2hnUApNakk1T0RBek1Ea3hNakE1TkRSYU1Ca3hGekFWQmdOVkJBTU1Eblp3WVY5M1pXSm9iMjlyWDJOaE1JSUJJakFOCkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXBaQjRVaHdRTXBIY25NYURvbkdLVjlnOGJrSGUKSkNVSzc0T2drTVNiL01HNUZ1T1RLRDhMaituUnZ1S3F4Sm1yaXJkTzBoRGxyR1FzSXMrM2RNaUZYS2YrYldBbwplcXNIY1o4L2hSZ1Q3SU1yNzUvbG0weTV5RGIvcHhaMS92WkNhUldoUUNEVk04bG85d0dEeTdsbWt0b0R5Q0YwCk5CNVlINjdQR3g0Y2RSa3d1S2V5ZVYyclVETmNBaDhFTnBoNWsxeW4rckFreG5xa3N5YS9iSCtUWDR0ZmZwZEMKYlNqY0pGSXlPLzRmYjRtd256NWhvSlBEdTV3aFVtc3J6UTZjQ3NRT2dpZStzWlZHaW1GZnZBWG85L2xKSGpydwppWVlKV3BJWUl1OTZWSnl0Sk5vK2hzRFdGTThCZ05LRnVOUXdjSk4yT1VxVFhtSDM1OU11cXd1NElRSURBUUFCCm8yNHdiREFkQmdOVkhRNEVGZ1FVcVF2bHJqd08zUUtPeHhvY1pnamIreW1Ja2tvd0h3WURWUjBqQkJnd0ZvQVUKcVF2bHJqd08zUUtPeHhvY1pnamIreW1Ja2tvd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBWkJnTlZIUkVFRWpBUQpnZzUyY0dGZmQyVmlhRzl2YTE5allUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFtNm9mQ0ZPN3NiMjhLdnZ2CmZBUVVlNDJnR3NZWGpCSG1ydjlIY2dqUFRVZmZRd25NSHpJblNydWRmVUZBTXNQRkw1Mm1WemVISnQ5cEkzUnMKYVJwSkF4MmRvS3pJMS9RaUxsc1RQWEp2aFJSK1RFc2wva0dxU0taQ3V3OFNIRGdhR1R0cFA1aEZkOWdIUUVrUApUYlc2NWRjd251ZG1md3RLZW15dFZUbnkxRjB5M2lHc3hwTlA1TkM0TzNVVG1pc3p4bTVkbjlOay9ncnc1dHV5Cm1IZi8ya2FUcy9Na3BoNEpGS1preVpyUTM2T2YyeE9DdUhMV1o5dzFhL0c1WGVCUHM0K1piNEhMbFJreW4xWWIKZXE3YWRGbHlmVzFJcDNVZHNVckZUbnA5WG1LY3BrVElWSWtlMU1uRDArclZMZElHOTRTeW1Za1FnRkFycWdhZQo3MXNIdnc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
caKey.pem: >-
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBcFpCNFVod1FNcEhjbk1hRG9uR0tWOWc4YmtIZUpDVUs3NE9na01TYi9NRzVGdU9UCktEOExqK25SdnVLcXhKbXJpcmRPMGhEbHJHUXNJcyszZE1pRlhLZitiV0FvZXFzSGNaOC9oUmdUN0lNcjc1L2wKbTB5NXlEYi9weFoxL3ZaQ2FSV2hRQ0RWTThsbzl3R0R5N2xta3RvRHlDRjBOQjVZSDY3UEd4NGNkUmt3dUtleQplVjJyVUROY0FoOEVOcGg1azF5bityQWt4bnFrc3lhL2JIK1RYNHRmZnBkQ2JTamNKRkl5Ty80ZmI0bXduejVoCm9KUER1NXdoVW1zcnpRNmNDc1FPZ2llK3NaVkdpbUZmdkFYbzkvbEpIanJ3aVlZSldwSVlJdTk2Vkp5dEpObysKaHNEV0ZNOEJnTktGdU5Rd2NKTjJPVXFUWG1IMzU5TXVxd3U0SVFJREFRQUJBb0lCQUhRbnpuSjA0OXhHdjB0eQpic25aOUtBNndmTHMzVWZvZ1NxVzQyQ052NDV0NzBnaXM0eUo1cmU1NklDT2tCWk1aYkIxZUtRaVhMQTh1MFpWCkNyV3hOUGRUbVVudEs1a2NRcVd4ZnlRR1Izd29idnUzNTZPMENhZHhCcDJZUVlKMkRST2lyRFhNa3llNUI1NDcKL3RaQUpibWpvUUdZanVrOTNMK2xxZ0d4ZDIraThsV1I0SXliWHMrYzdjZmdXd0ZyRmJLVnJEVUxDNXlsck13awp0RHZkNjZXdUJ1aEY1Y2RCRE9LTjlaZ1JnUHFEVlRqYUZNUTkyWHdoNEE1Q1JGZzRCK21sUmFRQ2NaZHdEZWJXCktGNGJBUjh0RDNYdjB4UUxBb0pCVkROaWRoSEQ3cERmZVdOQ0pMZTZjc0ZEUjZyeHpFcWJtMWpKTEFYNFBLMHEKUFM0MFdpMENnWUVBMmZqZnpDN1hwTk9jVXJaWFN1VmVxd2dkdHludG83QmJZdFdieVpxdnRaNklEVEpCeWp6TQpjU1VyYStLUmExZjBMYXlwaFhwOVBvUnZLRXI2ZHJXditNMHJQc01NeHVaQWFYMDg0b3hPakovK0NDMmMwa1JEClEzNldhMkUvMEpFb1A0VllwalFaWUFMbjl2UThuUWJLOWJDcG1jUkFTL3pKNWJPMjJ0NjJ3VzhDZ1lFQXduTHgKMFkzWUFMRFVBYlBpcCtMSjd1VDZ1RmZnY3hjOVY4MnFsVC9LZzBOdHJHMXB1dk41RXc1ZWQrQ051RlEvcERWVwpWS0N5bnAyaHJ0OFBvcjRwTkFFUUxzT3FOTks0ellqYm1hK3dhcHpqRkpxV3IybGczbjdEVlFicGVlbTBqa3BLCm5LZjBiNFJ6NFd2MndVVFdyRVM0eXZIRUpmMlhEZDZlUVRBeE4yOENnWUVBbXZQR1BNT3IvdnVEckhUOWR6dTUKWWNKaVJYeGorREo5dExQL2pJRVBtZi81M2MrMVgweDdWWS9EMzJ6d1RhdjM1S1JTMnBXcUJWQm1LUEdzUGNtSgpNRWpDRGxyZ2NXRHJ0MUlWZjBPWTczVXBSSzBRUjVYSmIyakZDODdWYTdKVk4xclhHMGY4SmZuSzV3N1hMQlhSCklIbVhCNzJ3cTVRbi9zZ1VIR0dvNzdjQ2dZRUFnSFd2aStGSmNpdGY1RUFTM1JiV2tSeDFCcFFIbEFFbVpYdFoKMW4vdUtnbkJ5c2Y5c2FSbnVFOGwyY3hmMUFiVWhJYzRJWENJa0lGUzcxUXQ0RFlBd25weFZuT3RYbmhYM25FcgpvcnlPcitBMXBNYjhCYVo0ZUlVR1JvWHFlTUFNcUhRc0ZwSmV5YzJYUUxVeXJ6dnJGcVBQOFVNSGNwRzEyVlBZCitQZjlpOEVDZ1lFQXpIRTFya1dSSG9XYnVjbGRXZWx1OGo1Q2o2NXJNVzVqU3poQklNR1IrZGErQ2lLR21GUGEKM1FSZnhkcHAwWGk2UlM1TGMrRndjQTFXQ1J4TmdYT0UrcGFoL3FFSG42NHJickV1MnlZVTFFTWwyT2haS3Z0QwpFS1p0YjFLcHFUaXhaZjFwMjdCRzY2cnptd0RpSUpTeExQSEh3VE55eHI5VUlYbksyZ1M4eCt3PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
serverCert.pem: >-
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNRENDQWhpZ0F3SUJBZ0lVTWlKRDEwRVdZUGVUMk5wbFJLdlcvbE05R1Uwd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0dURVhNQlVHQTFVRUF3d09kbkJoWDNkbFltaHZiMnRmWTJFd0lCY05NalF3TlRJME1USXdPVFEwV2hnUApNakk1T0RBek1Ea3hNakE1TkRSYU1DWXhKREFpQmdOVkJBTU1HM1p3WVMxM1pXSm9iMjlyTG10MVltVXRjM2x6CmRHVnRMbk4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSnFIbUNEVkplbjAKNXpSNlhKaGVJYWFBcnRGVUswa2hRYmNRTDYzelhkRzhndXpkRzF0azlRNW13UGp1OGtNKytwelZDeGhHc2hpSQpmUVJSVklGN1g2R1FydXNsS3A4a011OWhPaGFiTHNtSEpiNll2MmpydjdQSkljMFlrTmwzNHNyeWNIZFNPNjJICmh0eU9qVHprdWExT21YbGF2QzR0YzlkTU5uTTVVbE02eVhSc2FId08rOWJPZ0RuNmR0ZWJPNkhFaXoxdFVrZVMKL2VVNS9OZ3laeDhIUUUvNFpPd2tqUFhkYjFOL0lPaHBxUktqTHY0MVRFNTBMOUtzYStVRzJ4Mnk1aUZ1bXJoZQpjKzdNUmllbmxlcnJRQmcyaU5qOVNVQTdoNGhxOWRwWWIrVHREdENzKzdEczltSFZ5S3hWUktrREdkZDVoK2U5CjFzTCtzclJVNkRrQ0F3RUFBYU5oTUY4d0NRWURWUjBUQkFJd0FEQUxCZ05WSFE4RUJBTUNCZUF3SFFZRFZSMGwKQkJZd0ZBWUlLd1lCQlFVSEF3SUdDQ3NHQVFVRkJ3TUJNQ1lHQTFVZEVRUWZNQjJDRzNad1lTMTNaV0pvYjI5cgpMbXQxWW1VdGMzbHpkR1Z0TG5OMll6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFOUW9LSTNBRWUvdEdtUUhlCmxFZi92K0sxRnF1QUZrYXFDS0dYM08vcXJCVXBvdXFoY2RmMXNKSzRnRXFlejJWbEVhNmJucnAwYVBoYTNGMzgKS3VOWmNUNXJJNnl2bVZ4cWtCbTczTHUxUjNFQ2NCYk5xaDRjczd1SjZsYUV0OE0reGpuUEZ3WnV5a0NQM0t4SgpMQkJTSWRpMy9rYTMxTVdQV0JsYzdCSklvUFNtOGQ0RDh1NDVMYTJyaGtYMWVSNUluZ0lMMCtVdXFzY3pXUkdHClV4a2t2bEUwYUpBN0hzVEc1azVweHJWZ1VhdUM0VjA5enNPTkYzdHFmYWtYSmU0UUlLWmtTdEJ4bXVPRU9uWXMKUElzVHR1bEFKM3ExbHdITDh4V0RnakZZVmNHRFZBOFFHd2Y1dGJhek9RZXRyb0F2Qy83Q0hscFIxMjhxWEcrMAppbitHSXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
serverKey.pem: >-
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBbW9lWUlOVWw2ZlRuTkhwY21GNGhwb0N1MFZRclNTRkJ0eEF2cmZOZDBieUM3TjBiClcyVDFEbWJBK083eVF6NzZuTlVMR0VheUdJaDlCRkZVZ1h0Zm9aQ3U2eVVxbnlReTcyRTZGcHN1eVljbHZwaS8KYU91L3M4a2h6UmlRMlhmaXl2SndkMUk3clllRzNJNk5QT1M1clU2WmVWcThMaTF6MTB3MmN6bFNVenJKZEd4bwpmQTc3MXM2QU9mcDIxNXM3b2NTTFBXMVNSNUw5NVRuODJESm5Id2RBVC9oazdDU005ZDF2VTM4ZzZHbXBFcU11Ci9qVk1UblF2MHF4cjVRYmJIYkxtSVc2YXVGNXo3c3hHSjZlVjZ1dEFHRGFJMlAxSlFEdUhpR3IxMmxodjVPME8KMEt6N3NPejJZZFhJckZWRXFRTVoxM21INTczV3d2Nnl0RlRvT1FJREFRQUJBb0lCQUV3WXM4aVBUa0ZjMGJKZApBMVloSEs4U3RZUHR6L2NPUW44MG9GWW4veTUyaDM2L0QyYTlXNVFBODh4aVZyall2YThYbG9RWTVFRUNqWlhmCnV4NmNNNmFyU2dnUDRHSklBREV6anRodENPaEMva3BTakFmTitEUS91cjUxOTNhdisrWDI1MzFLNklwMnIrblMKNVNoMGRoOHJFcGJaSU13WW8vQUUzdGQxQmQ1bjA4STk5RzlCWktBNmdjL2ZJNEJPVk5lamVWcVEyUUNHOEovVQpRZnd5bG94Z3F0bE1vWklVNW0weS8vQWN6bTg5dGtQcjZnS3psMmh5VXN2eGNjdXBCSzMwWXhvRUUzZ0FudWxjCk44SkdSYitUZmQwYUxEOXhxdHc2aDRHcE9paDdvNkFoNURmcm5PUVlVSytwK1piK0NhMW9RNHJSYVRFekR5YUgKOExHVlVqVUNnWUVBeDdYUDVLaklCOURESkIvYWp6emVZejVBZGVhakdZSmlVOHNPSWxnSGFaK05hWE1qYXlQbQpzRCtLWXZzeEhGNW85VWlQalJKckN3ZDBPaTdvSXFuYVRwRHJmcE5VdWppWURkeXp6VkM2Zmw3NGxJZDBmdzloCkNta0JWVk81VjBUbjF2dnNDam1hM05FNmY0dUpPNm8vTlp5S2MxTVV0OCtZQ1d0NGtuLzBNZmNDZ1lFQXhoWEMKR2RMdDlCVUhDVTBwWDNsb1NSVmpVS0lDdGhjVGN0RFVkdXdyZ2dIOEhERUJpRm9wTjl5ZVNRYS9JTjF6SFRxUQpTQmt5cHNkelBQVUlFZUx2c0lQckFSMGlxWUR3dWU1d1VsVUdyblhjeUFtdGxmNlZSVUpCVUVLSnNJZHF4aXlCCkJPU2VXWXNyS2d0ZWRjSTk1ODNRZGpOaG5iWVdFOVR3OU9QVEswOENnWUJRUS81K1JHZkEzR0xSemd1bHJpMGoKYmcyeVZUUVFPSnNVV25RZjBZbUpKaHRMMm43TnZPd213aUw0alVTN3hpWWhEenpDMGpnN2dvOXdJeEloZkdyRgpVUEdWT2RtL3pxY3VTeG5vMXgxZFZRWkxpL1dDYThmd3l5dENCQmhsdnNmL1c5a09jd0NPNTNpL2NuR0JqWGRDCk1OeGtaV3ZhUkpFeW1BTXB2a3VER1FLQmdRQ2NmSWZ3MnIvOWViY3JVL2dCWXVwT0FrV0paOVA0Z2xacytDbEIKSWVabE9LZ3dwVTV1cDd1MFUrZ0FEUUpsTmsxQXBBbGp5L1JGNlg5U2dza3pTRExQSWdnL3d3S2xJaVlLM1NHRApDWVRUd216KzR4WnRUc2dpQk91UU9tQ0lReExKS0ZOc3lDZUkyZmJwcWoyZmppcFZ2RFNaakpIcmcvUUJDdEtvCnhHc0k1UUtCZ0J3UXB4T1RpNlc4OFZGZGYyRDBZTzJGYUNqV3E4Kzk1SzdUK3Q1YU9CTlhsMzJwd3JzNVI3aGMKUnFEVklZTG9MNWZHVEgyZDcvdmNXS1dwMjFCTDNvZjZldlNXNEFQNnJ0NlRUTFdBYkFjbmRTMlNlOWkrMTVlUgpTQlZibEU3VFA5ajg5UEdDc1F5STNZeWJrMWN6NERrTjJ0MHplU25WVG5aeHR3ZWdWNVVxCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
kind: Secret
metadata:
creationTimestamp: '2024-05-24T12:09:44Z'
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:caCert.pem: {}
f:caKey.pem: {}
f:serverCert.pem: {}
f:serverKey.pem: {}
f:type: {}
manager: kubectl-create
operation: Update
time: '2024-05-24T12:09:44Z'
name: vpa-tls-certs
namespace: kube-system
resourceVersion: '60147243'
uid: 51ac2807-1af8-4822-b828-0f9876f5c6a6

이제 설치 부분이 완료되었습니다. 이제 필요한 것은 배포를 위한 VPA YAML입니다.

예제-vpa.yaml

apiVersion: autoscaling.k8s.io/v1 

kind: VerticalPodAutoscaler

metadata:

name: pod-name-vpa

namespace: default

spec:

resourcePolicy:

containerPolicies:

- containerName: '*'

controlledResources:

- cpu

- memory

minAllowed:

cpu: 50m

memory: 100Mi

maxAllowed:

cpu: 2000m

memory: 4096Mi

targetRef:

apiVersion: "apps/v1"

kind: Deployment

name: pod-name

updatePolicy:

updateMode: "Off"

위의 예에서 우리는 Pod에 허용되는 최소 리소스 사용량과 허용되는 최대 리소스 사용량을 설정했습니다.

VPA는 이제 허용된 최소 리소스로 Pod를 모니터링합니다. 여기에는 다양한 업데이트 모드로 구성된 주요 호출 updatePolicy가 있습니다.

모드:

  • “자동”: VPA는 포드 생성 시 리소스 요청을 할당하고 선호하는 업데이트 메커니즘을 사용하여 기존 포드에 업데이트합니다. 현재 이는 “재생성”(아래 참조)과 동일합니다. 포드 요청의 재시작 무료(“인플레이스”) 업데이트가 가능하면 “자동” 모드에서 선호하는 업데이트 메커니즘으로 사용할 수 있습니다.
  • “재생성”: VPA는 포드 생성 시 리소스 요청을 할당하고 요청된 리소스가 새 권장 사항과 크게 다를 때 기존 포드를 퇴거하여 업데이트합니다(정의된 경우 포드 중단 예산을 준수). 이 모드는 드물게 사용해야 하며, 리소스 요청이 변경될 때마다 포드가 다시 시작되도록 해야 하는 경우에만 사용해야 합니다. 그렇지 않은 경우, 사용 가능해지면 다시 시작하지 않아도 되는 업데이트를 활용할 수 있는 “자동” 모드를 선호합니다.
  • “초기”: VPA는 Pod 생성 시에만 리소스 요청을 할당하고 나중에는 절대 변경하지 않습니다.
  • “Off”: VPA는 포드의 리소스 요구 사항을 자동으로 변경하지 않습니다. 권장 사항은 계산되어 VPA 객체에서 검사할 수 있습니다.

사용량을 모니터링하는 가장 좋은 방법은 “끄기” 모드로 설정하는 것입니다. 이 모드에서는 리소스 사용량을 추적하고 리소스를 자동으로 변경하지 않습니다.

위의 이미지에서 권장 사항은 VPA에 의해 업데이트됩니다. 예시 vpa yaml 파일에서 볼 수 있듯이, 우리는 최소 허용 리소스를 설정하고 권장 사항은 그에 따라 업데이트되며, 메모리는 바이트 값입니다.

권장 사항에 확신이 생기면 배포에 리소스를 할당할 수 있습니다.

수평 Pod 자동 확장(HPA) 구현

수평적 Pod 자동 확장(HPA)은 구성 요소의 인스턴스 수를 늘리는 것을 포함합니다. 예를 들어, 작업을 완료하는 데 1분이 걸리는 작업자 Pod가 있습니다. 작업자가 동시에 처리해야 할 작업이 10개 있는 무거운 부하에서는 모든 작업이 순차적으로 완료될 때까지 10분을 기다리고 싶지 않을 것입니다. 바로 이 부분에서 HPA가 중요해집니다. HPA는 작업자 Pod 인스턴스 수를 자동으로 늘려 여러 작업을 동시에 처리할 수 있도록 하여 전체 처리 시간을 크게 줄이고 무거운 부하에서 성능을 개선합니다.

우리의 경우, 우리는 여러 작업을 포함하는 마이크로서비스 아키텍처 기반 시스템을 가지고 있습니다. 모든 작업은 작업이 호출되고 유휴 상태가 될 때 실행되는 마이크로서비스입니다. 이 작업 실행은 브로커 RabbitMQ가 처리합니다.

따라서 RabbitMQ에서 대기열 수에 따라 포드 크기를 자동으로 조정하기 위해 Keda라는 도구를 사용합니다.

설치: https://keda.sh/docs/2.14/deploy/#install

우리의 경우, 프로젝트를 관리하기 위해 헬름 차트를 사용해 왔으며, 이 차트를 헬름에 통합했습니다.

HPA 배포 YAML 파일은 다음과 같습니다.

{{- if (($.Values.autoscale).enabled) }} 

{{- range $groupName, $group := .Values.deploymentGroups }}

{{- range $componentName, $component := $group.components }}

{{- $config := deepCopy $group.config }}

{{- $config := deepCopy $component | mergeOverwrite $config }}

{{- if and $config.enabled ($config.autoscale).enabled }}

---

apiVersion: keda.sh/v1alpha1

kind: ScaledObject

metadata:

name: {{$groupName}}-{{$componentName | toString | replace "_" "-"}}-scaler

namespace: {{$.Release.Namespace}}

annotations:

"helm.sh/hook": post-install,post-upgrade

"autoscaling.keda.sh/paused": "{{ $.Values.autoscale.paused }}"

spec:

scaleTargetRef:

name: {{$groupName}}-{{$componentName | toString | replace "_" "-"}}

envSourceContainerName: {{$groupName}}-{{$componentName | toString | replace "_" "-"}}

pollingInterval: {{ $.Values.autoscale.pollingInterval }}

cooldownPeriod: {{ $.Values.autoscale.cooldownPeriod }}

minReplicaCount: {{ $config.autoscale.minReplicaCount | default $.Values.autoscale.defaultMinReplicaCount}}

maxReplicaCount: {{ $config.autoscale.maxReplicaCount | default $.Values.autoscale.defaultMaxReplicaCount}}

{{ if (($config.autoscale).scaleToZero | default $.Values.autoscale.defaultScaleToZero) -}}

idleReplicaCount: 0

{{- end }}

fallback:

failureThreshold: 5

replicas: 1

advanced:

restoreToOriginalReplicaCount: true

horizontalPodAutoscalerConfig:

name: {{$groupName}}-{{$componentName | toString | replace "_" "-"}}-hpa

behavior:

scaleDown:

stabilizationWindowSeconds: {{ $.Values.autoscale.stabilizationWindowSeconds }}

triggers:

- type: rabbitmq

metadata:

mode: QueueLength

value: "{{$config.autoscale.queueLength | default $.Values.autoscale.queueLength}}"

queueName: {{$config.autoscale.queueName | default $componentName}}

authenticationRef:

name: pointing-fish-rabbitmq-auth-trigger

{{- end -}}

{{- end -}}

{{- end -}}

{{- end -}}

위의 YAML은 Values.yaml에서 키를 가져오고 있으며, 이 아래에 autoscale이라는 키가 있습니다.

autoscale: 

enabled: true

paused: "false"

stabilizationWindowSeconds: 30

cooldownPeriod: 120

pollingInterval: 15

queueLength: 20

defaultMaxReplicaCount: 10

defaultminReplicaCount: 1

defaultScaleToZero: false

이러한 키를 이해하기 위한 참고 자료: https://keda.sh/docs/2.14/reference/scaledobject-spec/

위에서 언급한 몇 가지 중요한 핵심 사항을 안내해 드리겠습니다.

이 플래그는 각 배포에 대한 수평 포드 자동 확장을 일시 중지합니다. 기본값인 false를 유지합니다.

각 작업에 대해 이 제한을 설정해야 합니다. 예를 들어, 작업을 완료하는 데 1분이 걸리는 경우 전체 처리가 완료될 때까지 10분을 기다리고 싶지 않을 것입니다. 이를 해결하려면 queueLength를 구성할 수 있습니다. 이 예에서는 4로 설정해 보겠습니다. 대기열 길이가 이 임계값을 초과하면 HPA는 하나의 복제본을 추가하여 작업자를 확장합니다. 즉, 이 설정된 숫자의 배수(이 경우 4)마다 추가 복제본이 생성됩니다. 따라서 대기열 길이가 4를 초과하면 복제본이 하나 추가되고, 8을 초과하면 다른 복제본이 추가되며, 이 패턴은 대기열 길이가 증가함에 따라 계속됩니다.

  • 기본 최대 복제본 수: 10

이 키는 최대 인스턴스 수를 늘려야 합니다.

  • 기본 최소 복제본 수: 1

이 키는 더 이상 크기 조절이 필요하지 않을 때 포드 크기를 해당 숫자로 줄입니다.

  • defaultScaleToZero: 거짓

이 플래그를 true로 설정하면 포드가 IdleReplicaCount로 조정됩니다. 어떤 시나리오에서는 포드가 사용되지 않을 수 있으며, 우리는 여전히 낭비하고 싶지 않은 리소스를 소모하기 때문에 포드를 계속 실행하지 않는 것을 선호합니다.

이것은 가장 중요한 키입니다. HPA가 RabbitMQ에서 지정된 큐를 모니터링할 수 있게 해줍니다. 이 큐 이름을 사용하면 HPA가 필요에 따라 확장 및 축소할 수 있습니다.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *