2023. 6. 13. 01:40ㆍ쿠버네티스 (Kubernetes)
Replica
지금까지 우리는 하나의 Pod에 하나의 컨테이너를 만들어왔습니다.
사실 단순하게 바라본다면 이렇게 만들어도 원하는 서비스를 구동하는 데 문제는 없습니다.
이 장에서 말하는 레플리카(replica)는 쉽게 말해 복제본입니다.
레플리카를 만들어야 하는 이유는 다음과 같습니다.
- Redundancy : 실패에 꽤나 관용적입니다.
- Scale : 규모를 확장하거나 축소하는 데 편리합니다.
- Sharding : 병렬 연산에 유용합니다.
사실 위에 언급한 이유는 어떤 어플리케이션을 구동하냐에 따라 레플리카를 만들지 말아야 하는 이유가 될 수 있습니다.
당연하게도 레플리카는 그 개수 만큼 시스템 자원을 사용하기도 하고,
극단적으로는 어플리케이션의 복제본을 100개 만든다고 해서 100배 좋은 게 아니기 때문입니다.
또한 일회성(one-off)으로 만든 어플리케이션에 대해서 레플리카는 하등 의미가 없습니다.
즉, 본인이 제공할 서비스가 레플리카를 만듦으로써 얻을 수 있는 이득이 더 클 때 사용해야 합니다.
동일한 레플리카들을 묶어서 레플리카셋(ReplicaSet)이라고 부릅니다.
물론 본인이 동일 어플리케이션에 대해 팟을 여러 개 생성해서 직접 관리하여 레플리카셋을 운용한다고 해도 되겠지만,
이 방법은 나름 지루하고 어딘가 구멍이 있을 수 있습니다.
쿠버네티스 세계에 온 만큼, 쿠버네티스를 활용해 레플리카를 만들고 관리해봅시다.
Reconciliation Loops
먼저 원하는 상태(desired state)와 현재 상태(current state)의 차이를 알아야 합니다.
원하는 상태는 말 그대로 본인이 이러한 상태를 원하는 것인데,
레플리카 성격으로 바라보면 'pod 안에 3개의 레플리카들이 구동되길 바래'처럼 얼마만큼의 레플리카가 어떤 팟에 존재하기를 원하는 지를 의미합니다.
현재 상태도 말 그대로 지금 바라본 상태인데,
이 또한 레플리카 성격으로 바라보면 'pod 안에 2개의 레플리카들만 구동되고 있음'과 같습니다.
여기서 현재 상태에서 원하는 상태로 바꾸려면 pod에 1개 레플리카를 추가로 생성하면 됩니다.
reconciliation은 우리 말로는 호환, 하모니 같은 느낌인데 그냥 현재 상태를 원하는 상태로 만드는 것이라고 보면 됩니다
쿠버네티스는 레플리카를 만들 때 이러한 접근법을 사용합니다.
이는 꽤나 합리적인데 처음부터 3개를 만들어주고 끝내버리면 그 이후의 유지보수를 하기 위해서 별도의 로직을 정의해야 하기 때문에 쓸데없이 복잡한 시스템이 되는 반면, 이러한 접근법은 심플하게 원하는 상태로 계속 되게끔만 하면 되기 때문입니다.
loop을 붙인 이유도 이와 같습니다. 쿠버네티스는 원하는 상태와 현재 상태의 차이를 계속 감지해서 맞춰주기 때문입니다.
예를 들어 원하는 상태가 3개의 레플리카들일 때 만일 현재 3개의 레플리카 중 1개가 실패해서 2개가 되었다 한들 원하는 상태가 아님을 감지하고 1개를 추가로 만들어 줍니다. 더 나아가 규모(scale)를 축소하거나 확장할 때도 동일하게 적용됩니다.
ReplicaSet Spec
아래 레플리카를 적용한 yaml 파일을 만들어봅니다.
frontend-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
spec.replicas 에서 레플리카 수를 정의하고 template에서 구동할 어플리케이션 및 컨테이너를 정의합니다.
아래 명령어를 통해 레플리카셋이 적용된 pod을 생성할 수 있습니다.
중요한 점은 레플리카 3개를 뚝딱하고 만들어주는 게 아닙니다. 레플리카셋 컨트롤러(ReplicaSet controller)가 파일에 정의된 원하는 상태를 확인하는데, 현재 상태는 frontend pod이 없으므로 원하는 상태(3개의 레플리카)가 될 때 까지 pod을 생성해줍니다.
kubectl apply -f frontend-rs.yaml
replicaset.apps/frontend created
생성한 레플리카에 대한 정보를 얻고 싶다면 rs describe 명령어를 실행하면 됩니다.
kubectl describe rs frontend
Name: frontend
Namespace: default
Selector: tier=frontend
Labels: app=guestbook
tier=frontend
Annotations: <none>
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: tier=frontend
Containers:
php-redis:
Image: gcr.io/google_samples/gb-frontend:v3
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 82s replicaset-controller Created pod: frontend-nvdx2
Normal SuccessfulCreate 82s replicaset-controller Created pod: frontend-psfdp
Normal SuccessfulCreate 82s replicaset-controller Created pod: frontend-blmbl
여담으로 pod을 조회하면 3개가 등장합니다.
kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-blmbl 1/1 Running 0 8m51s
frontend-nvdx2 1/1 Running 0 8m51s
frontend-psfdp 1/1 Running 0 8m51s
아래처럼 레이블로 찾을 수도 있습니다.
kubectl get pods -l tier=frontend
Scaling
scale 명령어를 통해 레플리카 수를 조절할 수 있습니다.
kubectl scale replicasets frontend --replicas=4
pod을 조회해보면 4개가 등장합니다.
kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-blmbl 1/1 Running 0 17m
frontend-nvdx2 1/1 Running 0 17m
frontend-psfdp 1/1 Running 0 17m
frontend-wbs7m 1/1 Running 0 26s
이 방법은 응급할 때 사용하면 좋고, 쿠버네티스의 철학에 맞는 방법은 yaml 파일을 고쳐서 적용하는 것입니다.
(참고 : [Kubernetes] 4. POD - Pod Manifest)
...
spec:
replicas: 4
...
Autoscaling based on CPU
때로는 레플리카 수를 상황에 맞게 알아서 조절하기 원할 수 있습니다.
예를 들어 CPU를 80%까지 쓰는 제한 아래서 레플리카를 2 ~ 5개로 만들고 싶다면
kubectl autoscale rs frontend --min=2 --max=5 --cpu-percent=80
처럼 실행하면 됩니다.
그리고 당연하게도 yaml에서 명시할 수도 있습니다.
...
spec:
scaleTargetRef:
kind: ReplicaSet
name: frontend
minReplicas: 3
maxReplicas: 5
targetCPUUtilizationPercentage: 80
autoscaling은 horizontalpodautoscalers 가 이를 수행해주는 데, 해당 정보를 얻고 싶다면 hpa를 조회하면 됩니다.
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
frontend ReplicaSet/frontend <unknown>/80% 2 5 4 41s
중요한 점은 여태 설명했던 autoscaling은 Horizontal Pod Autoscaling 방식을 따른다는 것입니다.
이는 pod 자체를 만들거나 지우는 것인데 반대로 Vertical은 pod 내부에 설계된 자원들을 조정하는 것입니다.
(Vertical Pod Autoscaling은 아직 구현되지 않았다고 합니다)
참고로 autoscaling은 직접 레플리카를 지정하는 것과 함께 쓰는 것을 권장하지 않는데, 둘이 함께 레플리카를 만들고 지우다보면 예기치못한 동작을 이끌어낼 수 있다고 합니다.
Deleting ReplicaSets
레플리카셋을 제거하려면 아래처럼 delete 명령어에 rs를 추가로 붙여서 실행합니다.
kubectl delete rs frontend
만일 pod은 남기고 싶다면(쓸 일은 없을 듯) --cascade=orphan 옵션을 주면 됩니다.
kubectl delete rs frontend --cascade=orphan
Alternatives of ReplicaSets
실컷 설명해놓고 어딘가 먹이는 것 같지만서도...
레플리카셋을 직접 만들어 운용하는 것보다 좋은 대안을 소개하려고 합니다.
- Deployment (권장)
- Basic Pod
- Job
- DaemonSet
- Replication Controllor
위에 명시된 내용들 중 일부는 향후 포스팅에서 다룰 예정입니다.
'쿠버네티스 (Kubernetes)' 카테고리의 다른 글
[Kubernetes] 8. 설정 (0) | 2023.06.20 |
---|---|
[Kubernetes] 7. 배포 (0) | 2023.06.19 |
[Kubernetes] 5. 서비스 검색 (0) | 2023.06.12 |
[Kubernetes] 4. POD (0) | 2023.06.03 |
[Kubernetes] 3. 팁 (0) | 2023.06.01 |