Kubbernetes Custom Controller를 만들었습니다.
18458 단어 Kubernetestech
개시하다
Kubbernetes에는 Pod를 수평으로 축소Horizontal Pod Autoscaler(이하 HPA)하는 자원이 있습니다.HPA는 매우 편리하며 노드의 규모Cluster Autoscaler와 조합해 사용하는 곳이 많죠.
하지만 이 HPA도 만능은 아니에요.팟과 노드 규모에 시간이 얼마나 걸리느냐에 따라 이른바 스파이크 방문 등 돌발적인 방문에 대응하기가 쉽지 않기 때문이다.이 경우 어떻게 해야 하는지, 특정 시간에 스파이크 방문이 발생할 수 있다는 것을 알았다면 평소보다 자원을 더 많이 준비했을 것이다.HPA로서는 스매시
minReplicas
가 안정적일 때보다 커지는 것을 막기 위한 것이라는 인상을 준다.다음은 이 대응을 Scheduled Scoling이라고 합니다.그러나 상술
minReplicas
의 대응을 미리 늘리는 것도 문제다.그것은 원가적인 문제 때문에 스파이크가 발생하기 전에 Cluster에 적용하고 싶지만, 이를 위해 반드시 어떤 구조와 이런 점을 만들어야 한다.실현된 메커니즘 자체는 HDAminReplicas
를 간단하게 업데이트하는 메커니즘만 있으면 된다.대충 설치하면 CronJob이 API를 직접 두드려 업데이트하는 구조를 생각해 낼 수 있다.실제로 비슷한 일을 이루는 Kubbernetes의 Custom Controller가 이미 존재합니다.
그러나 GitOps를 실천하는 경우 Git에 놓인 manifest를 업데이트해야 하며, Cluster에서 API를 사용하여 업데이트하는 것만으로는 부족하다.이 동기에 대응할 수 있는 Custom Controller(당시)는 관측 범위를 찾지 못했다.이에 따라 자체 커스텀 컨트롤러를 제작해 깃옵스도 사용할 수 있는 스cheduled Scoling을 구현했다.
scheduled-pod-autoscaler
두 개의 Custom Resource로 구성됩니다.
친자 관계는 다음과 같다.
$ kubectl tree scheduledpodautoscaler nginx
NAMESPACE NAME READY REASON AGE
default ScheduledPodAutoscaler/nginx - 6m5s
default ├─HorizontalPodAutoscaler/nginx - 6m5s
default ├─Schedule/test-1 - 6m4s
default ├─Schedule/test-2 - 6m4s
default └─Schedule/test-3 - 6m4s
ScheduledPodAutoscaler
ScheduledPodAutoscaler
는 HPA로 싸인 커스텀 리소스다.ScheduledPodAutoscaler
Controller는 리소스에서 일반 HPA를 사용합니다.여기에 정의된 HPA의 스펙은 Scheduled Sccalling을 실행하지 않을 때 사용됩니다.
왜 HPA에 신선도를 유지해야 하는지를 말하자면 schedule-pod-autooscaller는 특정한 시간 안에 HPA
maxReplicas
/minReplicas
를 바꾸는 방법으로 Scheduled Scoling을 실현했다.Giit에서 HPA를 관리하는 manifest의 경우 Controller에서 Kubernetes API로만 HPA의 스펙을 변경했다면 Giit의 manifest는 변경되지 않았기 때문에 GitOps가 불편할 수 있습니다.HPA를 둘러싼 자원을 사용했기 때문에 HPA의 manifest 자체는 Git에서 관리되지 않고 API를 통해 HPA의 스펙을 변경하는 것도 문제없다.랩 HPA의 스펙v2beta2의 API을 사용할 수 있습니다.
apiVersion: autoscaling.d-kuro.github.io/v1
kind: ScheduledPodAutoscaler
metadata:
name: nginx
spec:
horizontalPodAutoscalerSpec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
$ kubectl get spa # You can use spa as a short name of scheduledpodautoscaler.
NAME MINPODS MAXPODS STATUS AGE
nginx 3 10 Available 6m52s
Schedule
Schedule
는 Scheduled Scoling을 정의하는 데 사용되는 Custom Resouce입니다.부모ScheduledPodAutoscaler
에 대해 여러 개Schedule
를 정의할 수 있다.ScheduledPodAutoscaler
의 Controller 참조Schedule
는 Scheduled Scoling의 시간이 되었을 때maxReplicas
의 스펙트럼에 따라generate가 만든 HPA의minReplicas
/Schedule
를 고쳤다.이때 주의해야 할 것은 HPA의 replicas가 변경된 후 Pod가 실제로 시작되기 전에 시간이 걸린다는 것이다.따라서 스파이크가 발생하는 시간에 스cheduled Sccalling을 하지 말고 스파이크가 조금 여유를 가지도록 미리 스cheduled Scoling을 하는 것이 좋다.여러 개
Schedule
의 시간 범위가 충돌하는 경우 각각의 Schedule
가 정의한 maxReplicas
/minReplicas
의 최대치를 사용한다.$ kubectl get schedule -o wide
NAME REFERENCE TYPE STARTTIME ENDTIME STARTDAYOFWEEK ENDDAYOFWEEK MINPODS MAXPODS STATUS AGE
test-1 nginx Weekly 20:10 20:15 Saturday Saturday 1 1 Available 4m49s
test-2 nginx Daily 20:20 20:25 2 2 Available 4m49s
test-3 nginx OneShot 2020-10-31T20:30 2020-10-31T20:35
Schedule
는 3개의 Schedule Type을 지원합니다.type: Weekly
시간을
HH:mm
형식으로 설명하고 요일을 지정합니다.apiVersion: autoscaling.d-kuro.github.io/v1
kind: Schedule
metadata:
name: nginx-push-notification
spec:
scaleTargetRef:
apiVersion: autoscaling.d-kuro.github.io/v1
kind: ScheduledPodAutoscaler
name: nginx
minReplicas: 10
maxReplicas: 20
type: Weekly
startDayOfWeek: Monday
startTime: "11:50"
endDayOfWeek: Wednesday
endTime: "13:00"
timeZone: Asia/Tokyo
type: Daily
HH:mm
의 형식으로 시간을 기술하다.apiVersion: autoscaling.d-kuro.github.io/v1
kind: Schedule
metadata:
name: nginx-push-notification
spec:
scaleTargetRef:
apiVersion: autoscaling.d-kuro.github.io/v1
kind: ScheduledPodAutoscaler
name: nginx
minReplicas: 10
maxReplicas: 20
type: Daily
startTime: "11:50"
endTime: "13:00"
timeZone: Asia/Tokyo
type: OneShot
yyyy-MM-ddTHH:mm
의 형식으로 시간을 기술하다.apiVersion: autoscaling.d-kuro.github.io/v1
kind: Schedule
metadata:
name: nginx-push-notification
spec:
scaleTargetRef:
apiVersion: autoscaling.d-kuro.github.io/v1
kind: ScheduledPodAutoscaler
name: nginx
minReplicas: 10
maxReplicas: 20
type: OneShot
startTime: "2020-09-01T10:00"
endTime: "2020-09-10T19:00"
timeZone: Asia/Tokyo
Install
다음 명령을 사용하여 설치할 수 있습니다.
# Kubernetes v1.16+
$ kubectl apply -f https://raw.githubusercontent.com/d-kuro/scheduled-pod-autoscaler/v0.0.3/manifests/install/install.yaml
# Kubernetes < v1.16
$ kubectl apply -f https://raw.githubusercontent.com/d-kuro/scheduled-pod-autoscaler/v0.0.3/manifests/install/legacy/install.yaml
기타 상세한 API 스펙과 export의metrics 등은 README를 참조하십시오.조금 안쪽이면...
schedule-pod-autooscaller는 kubebuilder로 제작되었습니다.
kubebuilder를 사용하여 Custom Controller를 만드는 방법@zoetrope의창조하고 배우는 Kubilder 아주 좋아요. 꼭 참고하세요.
Controller
schedule-pod-autooscaller에서 이동하는 Controller는
ScheduledPodAutoscaler
의 Controller와 Schedule
의 Controller 두 개가 있다.기본적으로 주 논리는 ScheduledPodAutoscaler
의 Controller 측면쓰여 있다에 있다.그렇다면
Schedule
의 Controller는 무엇을 하고 있을까요?.spec.scaleTargetRef
는 지정된 부모ScheduledPodAutoscaler
와의 친자관계owner Reference 부여를 표현하기 위해서입니다.여기 주어진 ownerReference
중색인 추가, ScheduledPodAutoscaler
의 Controller에서 아이Schedule
를 모을 때 사용합니다.나는 개인적으로 이곳의 처리가 매우 마음에 든다. 분명히 일반 자원ownerReference
이 아닌데 나중에 지불하면 어떻고, 게다가 ownerReference
하면 부모를 없앨 때ScheduledPodAutoscaler
일 때 아이Schedule
도 소장되기 때문에 별로 좋지 않다.만약 누가 이렇게 하는 것이 비교적 좋다는 것을 알았다면 나는 매우 기뻤을 것이다.CRD용 API Version
설치의 예를 보면 Kubbernetes의version은 두 가지 설치 방법을 따로 제공했다.
# Kubernetes v1.16+
$ kubectl apply -f https://raw.githubusercontent.com/d-kuro/scheduled-pod-autoscaler/v0.0.3/manifests/install/install.yaml
# Kubernetes < v1.16
$ kubectl apply -f https://raw.githubusercontent.com/d-kuro/scheduled-pod-autoscaler/v0.0.3/manifests/install/legacy/install.yaml
왜 두 가지를 제공했을까.16 CRD에서 GA가 진행돼 API version이 달라졌기 때문이다.# Kubernetes v1.16+
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
...
# Kubernetes < v1.16
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
...
CRD 등 manifest는 List 도구를 사용하여generate를 진행하는데, 이 버전에 따라generate의 manifest의 API version이 달라진다.그래서 controller-gen 저는generate manifest에 있어요.Kubbernetes에 업로드된 버젼도 약 3개월에 한 번씩 업데이트되고 각종 클라우드 공급자가 지원하는 버젼도 편차가 있기 때문에 Custom Controller를 쓸 때 어느 버젼을 지원하는지 주의해야 한다. 정말 쉽지 않다.그렇습니다.(v1.16 이하 버전의 지원을 끊고 싶습니다)
향후
기본적으로 하고 싶었던 일이 이뤄졌기 때문에 잦은 추가 기능을 한다는 점은 별로 고려하지 않았지만, 굳이 말하자면 스틸 투 제로를 지원해주면 좋겠다고 생각했다.Sciele to Zero가 지원되면 야간 등 특정 시간에 리플릭스를 0으로 설정해 비용 절감 등을 할 수 있다.
Scale to Zero를 할 수 있다면 좋겠지만 왜 움츠러들었을까
schedule-pod-autooscaller의 구조는generate의 HPA
maxReplicas
/minReplicas
를 제어하여ScheduledScoling을 실현하는 것이다.사실 HPA 자체 Sciele to Zero의 지원이 알파에서 피처 게이트를 사용하지 않으면 사용할 수 없기 때문이다.HPA의 Sciele to Zero의 KEP:
두 가지 버전 사용
따라서 현재는 HPA를 사용한 상태에서 리플릭스를 0으로 설정할 수 없다.그렇다면 어떻게 해야 할까. Scalle to Zero Scheduled Scarling의 경우 일반 HPA를 삭제하고 직접 Scare API를 사용해 0으로 만들고, Scheduled Scaring이 끝나면 HPA를 다시 일반 반환하는 등의 실현은 쉽게 생각할 수 있지만, 복잡화도 그다지 예쁘지 않다.좋은 생각이 있는 사람이 나에게 알려주면 나는 매우 기쁠 것이다.(이 블로그는 이것을 말하고 싶다.)
기타 기능 추가 요구사항과 버그의 보고 등이 지아이허브 이슈에 보고되면 반응할 것으로 보인다.
Reference
이 문제에 관하여(Kubbernetes Custom Controller를 만들었습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/d_kuro/articles/bb75adeba67d60텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)