현재 운영 중인 사이트는 HPA(Horizontal Pod Autoscaler) 통해서 파드를 오토스케일링 하는데,
파드가 스케일 아웃을 할 때, 필요한 자원이 없을 경우에는 CA(Cluster Autoscaler)를 통해서, 노드를 추가 하게 된다.
그런데, CA를 통해서 노드가 추가 될때, 노드가 바로 추가되지 않기 때문에,
노드가 추가되고 파드가 생성될 때 까지는 사이트 속도가 떨어지는 문제가 발생하였다.
HPA의 기준(CPU사용율)을 변경하거나, 파드나 노드의 갯수를 매우 넉넉하게 설정을 해 놓으면 문제는 없겠지만
좀 더 스마트 한 방법을 찾아 보기로 했다.
처음에는 상시적으로 여유 노드를 한 개 정도 더 확보하고 있는 방법을 생각하였으나,
자원을 낭비 되는 감이도 있고, 관련 문서도 찾을 수가 없었는데, Overprovioning 이라는것을 발견하여 적용해 보기로 하였다.
개요
- 일정 자원을 가진 pod(더미 파드)를 일정 개수 상시적으로 띄워 놓는다.
- pod 의 scale out 이 우선적으로 더미 파드를 사용하여, scale out 을 완료한다. (pod 의 priority = 0, dumy_pod = -1)
- pod 의 scale out 으로 자원을 뺏기게 되면, dumy_pod 를 지정된 수량을 맞추기 위해서 생성한다. (이 과정에서 노드가 필요할 경우 CA를 통해 노드가 추가됨)
참고 사이트 #1 : https://medium.com/scout24-engineering/cluster-overprovisiong-in-kubernetes-79433cb3ed0e
FAQ : https://medium.com/scout24-engineering/cluster-overprovisiong-in-kubernetes-79433cb3ed0e
설치 (EKS 환경에 셋팅하였음)
<RBAC-configs.yaml>
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: cluster-proportional-autoscaler
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-proportional-autoscaler
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list", "watch"]
- apiGroups: [""]
resources: ["replicationcontrollers/scale"]
verbs: ["get", "update"]
- apiGroups: ["extensions","apps"]
resources: ["deployments/scale", "replicasets/scale"]
verbs: ["get", "update"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-proportional-autoscaler
subjects:
- kind: ServiceAccount
name: cluster-proportional-autoscaler
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-proportional-autoscaler
apiGroup: rbac.authorization.k8s.io
|
<cluster-proportional-autoscaler.yaml>
---
kind: ConfigMap
apiVersion: v1
metadata:
name: overprovisioning
namespace: kube-system
data:
linear: |-
{
"coresPerReplica": 12
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: overprovisioning-autoscaler
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: overprovisioning-autoscaler
template:
metadata:
labels:
app: overprovisioning-autoscaler
spec:
containers:
name: autoscaler
command:
- /cluster-proportional-autoscaler
- --namespace=kube-system
- --configmap=overprovisioning
- --target=deployment/overprovisioning
- --logtostderr=true
- --v=2
serviceAccountName: cluster-proportional-autoscaler
|
- 더미 파드(deployment/overprovisioning) 의 수량을 조절하는 autocaler 설정
- coresPerReplica : 12 > Core 12당 한 개씩 더미 파드를 생성 (사용사 설정에 맞게 수정이 필요함)
<k8s-overprovisioning.yaml>
---
apiVersion: scheduling.k8s.io/v1beta1
kind: PriorityClass
metadata:
name: overprovisioning
value: -1
globalDefault: false
description: "Priority class used by overprovisioning."
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: overprovisioning
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
run: overprovisioning
template:
metadata:
labels:
run: overprovisioning
spec:
priorityClassName: overprovisioning
containers:
- name: reserve-resources
image: k8s.gcr.io/pause
resources:
requests:
cpu: 2500m
memory: 2560Mi
|
더미 파드의 리소스 설정 : CPU 2.5 Core, Memory 2.5GB
<CA 설정>
CA 아래의 설정을 추가한다.
- Priority -1 인 파드의 요청에도 노드 증설을 처리시키는 옵션 (기본값: 0)
- 현재 노드그룹은 2개로 standard-workers(Ondemand 2 대) 와 sport-workers(Spot 2 대)를 사용 이다.
- Ondemand 는 Max 가 2대 이기 때문에 자원이 부족할 경우에는 sport-workers (Spot 인스턴스)만 스케일 아웃 된다.
동작 확인
- 노드 가 증가되면 합산되는 코어도 늘어나므로, overprovisioning pod 갯수도 증가할수 있으므로, 사용자 환경에 맞도록 설정이 필요함
Inter-Pod Affinity 설정 추가
윗 단계까지 적용하고, 반나절 동안 모니터링 해 보았는데, 문제를 발견하였다.
- overprovisioning pod 가 여러 노드 분산되어 있어, 필요한 노드 수보다 더 많이 사용하게 되는 것을 발견하였다.
- 노드는 8 Core 이고, overprovisioning pod 의 CPU 요구량은 2.5 이다.
- overprovisioning pod 가 5개 실행되고 있는데, 3개의 노드를 사용하고 있다. (3개 모두 overprovisioning pod 만 실행 중)
- 2 개의 노드만 사용하면 되는 상황인데, 3 대를 사용하고 있으니, 아무리 Spot Instance 이지만 그대로 둘 수 없다.
아래의 설정을 deployment/overprovisioing 에 추가한다.
- pod 라벨이 run=overprovisioning 이면 가급적 같은 호스트네임에 배치해라.
최종적인 k8s-overprovisiong.yaml
<k8s-overprovisioning.yaml>
---
apiVersion: scheduling.k8s.io/v1beta1
kind: PriorityClass
metadata:
name: overprovisioning
value: -1
globalDefault: false
description: "Priority class used by overprovisioning."
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: overprovisioning
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
run: overprovisioning
template:
metadata:
labels:
run: overprovisioning
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: run
operator: In
values:
- overprovisioning
topologyKey: kubernetes.io/hostname
weight: 100
priorityClassName: overprovisioning
containers:
- name: reserve-resources
image: k8s.gcr.io/pause
resources:
requests:
cpu: 2500m
memory: 2560Mi
|
'Kubernetes' 카테고리의 다른 글
[helm] eks 저장소 추가 및 aws-node-termination-handler 업그레이드 하기 (0) | 2020.06.16 |
---|---|
간단하게 nginx 배포하기 (0) | 2020.03.17 |
kubectl 자동 완성 (0) | 2019.10.22 |
실행되고 있는 pod 를 node 기준으로 sort 하여 보고 싶을 때 (0) | 2019.08.09 |
kubernetes 노드 변경 (0) | 2019.08.05 |