해당 내용은 Udemy의 Certified Kubernetes Administrator (CKA) with Practice Tests 강의를 공부한 내용입니다. 내용을 그대로 번역하기보다는, 제가 이해하기 쉬운 대로 수정한 부분들이 있습니다.
⚠️ 영어 독해가 많이 부족합니다. 틀린 내용이 있으면 알려주시면 감사하겠습니다.
쿠버네티스 컨트롤러에 대해 얘기해보고자 합니다. 컨트롤러는 쿠버네티스의 두뇌입니다. 쿠버네티스 오브젝트를 모니터링하고 반응하는 프로세스입니다. 이번 강의에서는 특히 컨트롤러 중 하나인 Replication controller에 대해 다루어보겠습니다.
What is a Replica and Why do we need a replication controller?
첫 번째 시나리오로 돌아가 보겠습니다. 애플리케이션을 실행하는 단일 파드가 있습니다. 어떤 이유로 애플리케이션과 파드가 죽었다고 합시다. 유저는 더 이상 애플리케이션에 접근할 수 없습니다. 우리는 이런 상황에서도 유저가 애플리케이션 접근 권한을 잃지 않도록 동시에 실행되는 둘 이상의 인스턴스 또는 파드를 가지고 싶습니다. 그러면 하나가 실패해도 여전히 다른 애플리케이션에서 실행 중인 애플리케이션이 있으니까요.
Replication controller은 클러스터에서 파드의 여러 인스턴스를 실행하는 데 도움이 됩니다. 이는 곧 고가용성(High Availity)을 제공합니다. 만약 파드 한 개만 사용할 예정이라면 Replication controller를 사용할 수 없는 걸까요? 아닙니다. 파드가 하나만 있어도 Replication controller이 도움이 될 수 있습니다. Replication controller는 기존 파드가 죽었을 때, 새로운 파드를 자동으로 불러와서 지정된 수의 파드가 항상 실행 중이라는 것을 보장합니다.
Replication controller가 필요한 또다른 이유는 부하를 분산하기 위해 여러 파드를 생성해야하기 때문입니다. 예를 들어, 유저들에게 서비스를 제공하는 하나의 파드가 있다고 합시다. 유저가 늘어나면 로드밸런싱을 위해 추가 파드를 배포합니다. 해당 노드의 리소스가 부족해지면 클러스터의 다른 노드에 추가 파드를 배포할 수 있습니다. Replication controller는 클러스터의 여러 노드에 걸쳐있기 때문에 여러 노드에서 파드와 애플리케이션의 로드 밸런싱하는 데 도움이 됩니다.
Difference between ReplicaSet and Replication Controller
Replication controller와 ReplicaSet을 비교해보도록 하겠습니다. 둘 다 같은 목적을 가지고 있지만 같은 것은 아닙니다.
- Replication controller는 더 오래된 기술이며, ReplicaSet에 의해 대체되었습니다.
- ReplicaSet은 replication을 설정하는 새로운 권장 방법입니다. 따라서 앞으로 모든 데모 및 구현에서는 ReplicaSet을 사용하도록 노력하겠습니다. 위에서 논의한 내용(High Availity, Load Balancing & Scaling)은 두 기술 모두 적용 가능합니다. 각각의 작동 방식에는 약간의 차이가 있는데, 잠시 후에 살펴보겠습니다.
Creating a Replication Controller
지금은 Replication controller를 만드는 방법을 살펴보겠습니다.
Replication Controller Definition File
지난 강의와 마찬가지로, Replication controller Definition File을 생성하며 시작합니다.
1. yaml 파일 생성
이름을 rc-definition.yaml
로 하겠습니다. vim rc-definition.yaml
로 파일을 생성합니다.
2. 4개의 루트 레벨 속성 작성
Kubernetes Definition File과 마찬가지로 apiVersion
, kind
, metadata
, spec
네 개의 섹션이 있습니다.
apiVersion
: API 버전은 우리가 만드는 항목에 따라 다릅니다. 지금은 Replication controller를 만드는데, Replication controller은 Kubernetes API 버전 v1에서지원됩니다. 따라서apiVersion
은v1
으로 설정하겠습니다.
kind
:ReplicationController
입니다.
metadata
: metadata는 딕셔너리입니다. 여기에 파드의 이름과 label을 정의할 수 있습니다. -name
:myapp-rc
로 지정합니다. -labels
: labels 또한 딕셔너리 입니다. 여기에 원하는 만큼 label을 추가할 수 있습니다. 지금은app: myapp
와type: front-end
을 지정해주었습니다.
지금까지는 pod를 생성할 때와 매우 유사했습니다. 달라지는 부분은 spec
부분 부터입니다. Kubernetes Definition file의 경우, spec
섹션은 오브젝트 내부에 무엇이 있는지 정의합니다. 우리는 지금 ReplicationController을 창조하고 있습니다. spec
섹션에는 ReplicationController가 Pod를 복제하는데 필요한 Pod 템플릿을 정의하면 됩니다. Pod 템플릿은 Pod생성 시 사용했던 Definition file내용을 재사용하면 됩니다. Pod Definition File에서 apiVersion
, kind
를 제외한 내용이 template
아래에 들어갑니다.
spec
: spec도 딕셔너리 이며, ReplicationController Definition File에서의 spec안에는 template이 있습니다.template
: 복제할 Pod의 템플릿이 들어가며, 템플릿 아래에는 파드의metadata
,spec
이 들어갑니다.
replicas
: 복제본 수가 들어갑니다.
완성된 ReplicationController Definition File은 아래와 같습니다.
apiVersion: v1
kind: ReplicationController
metadata:
name: myapp-rc
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
3. 파일 저장
이제 Esc:wq
를 눌러서 파일을 저장하고 나오겠습니다.
4. YAML파일 kubectl create
아래 커맨드로 yaml파일을 적용하여 Replication controller를 생성합니다.
$ kubectl create -f rc-definition.yaml
Replication controller이 생성되면서 Pod 3개(replicas
에 입력한 수)도 생성됩니다.
5. Replication controller 생성 확인
$ kubectl get replicationcontroller
6. Replication controller로 시작된 Pod 확인
$ kubectl get pods
세 개의 파드가 실행되는 것을 볼 수 있습니다. 파드는 모두 replication controller의 이름으로 시작합니다. 이는 모두 replication controller에 의해 자동으로 생성되었음을 나타냅니다.
Creating a ReplicaSet
이제 ReplicaSet을 살펴보겠습니다.
ReplicaSet Definition File
1. yaml 파일 생성
이름을 replicaset-definition.yaml
로 하겠습니다. vim replicaset-definition.yaml
로 파일을 생성합니다.
2. 4개의 루트 레벨 속성 작성
Replication Controller와 매우 유사하며, 마찬가지로 apiVersion
, kind
, metadata
, spec
네 개의 섹션이 있습니다.
apiVersion
: apps/v1 입니다. Replication controller을 생성할 때에는 v1을 입력했습니다. 이 부분 유의해주세요. 만약 잘못 입력하면 해당 Kubernetes API version이 ReplicaSet을 지원하지 않는다고 아래와 같은 에러가 날 것입니다.error: unable to recognize "replicaset-difinition.yaml": no matches for /, kind=RedplicaSet
kind
:ReplicaSet
입니다.
metadata
: metadata는 딕셔너리입니다. 여기에 파드의 이름과 label을 정의할 수 있습니다.-
name
:myapp-replicaset
로 지정합니다.
labels
: labels 또한 딕셔너리 입니다. 여기에 원하는 만큼 label을 추가할 수 있습니다. 지금은app: myapp
와type: front-end
을 지정해주었습니다.
-
spec
: spec도 딕셔너리 이며, ReplicaSet Definition File의 spec안에는ReplicationController Definition File과 유사하게 template이 있습니다.template
: 복제할 Pod의 템플릿이 들어가며, 템플릿 아래에는 파드의metadata
,spec
이 들어갑니다.
replicas
: 복제본 수가 들어갑니다.
selector
: ReplicationController와 ReplicaSet 사이에는 한 가지 중요한 차이점이 있습니다. 바로 ReplicaSet에서는selector
섹션을 작성해야 한다는 것입니다.selector
섹션은 어떤 파드가 ReplicaSet 아래에 있는지 식별하는 역할을 합니다.그런데 이미 우리는 Pod의 Definition file내용을
spec
섹션의template
에 포함시켰습니다. 그런데도 왜selector
섹션을 작성해야 할까요? 그 이유는 ReplicaSet이 ReplicaSet을 생성할 때 함께 만들어진 파드가 아닌 파드도 관리가 가능하기 때문입니다. 예를 들어서, ReplicaSet 생성 전에 있었던 파드들이 있습니다. 이 파드들을selector
의labels
와 매칭시켜 주면, ReplicaSet이 Replica(복제본)을 만들 때 해당 파드들도 고려하여 Replica를 만들게 됩니다. 해당 내용은 뒤에서 더 자세히 설명하겠습니다.selector
는 ReplicationController와 ReplicaSet 사이의 주요 차이점 중 하나입니다.selector
는 ReplicationController에서는 필수 필드는 아니지만 사용가능합니다. ReplicationController에서selector
를 사용하지 않으면, pod definition file에서 제공된 labels와 동일하다고 가정합니다. ReplicaSet에서selector
는 필수이며matchLabels
를 작성해야 합니다.matchLabels
은 파드의labels
와 매칭되는 정보입니다. ReplicaSet의selector
는 또한matchLabels
에서 사용할 수 있는 다른 많은 (ReplicationController에서는 사용하지 못하는)옵션도 제공합니다.
완성된 ReplicaSet Definition File은 아래와 같습니다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-replicaset
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
3. 파일 저장
이제 Esc:wq
를 눌러서 파일을 저장하고 나오겠습니다.
4. YAML파일 kubectl create
ReplicaSet을 생성하려면 아래 커맨드를 입력하면 됩니다.
$ kubectl create -f replicaset-definition.yaml
5. ReplicaSet 생성 확인
ReplicaSet을 확인하려면 아래 커맨드를 입력하시면 됩니다.
$ kubectl get replicaset
6. ReplicaSet 으로 Pod 시작된 확인
ReplicaSet으로 시작된 파드들을 확인하려면 아래 커맨드를 입력하시면 됩니다. (사실 이건 그냥 파드 확인하는 커맨드긴 하지만 ReplicaSet으로 시작된 파드도 이 커맨드로 확인이 가능할 것입니다.)
$ kubectl get pods
Labels and Selectors
labels
과 selectors
는 어떻게 다를까요? Kubernetes에서 파드와 오브젝트에 labels
를 지정하는 이유는 무엇인지 잠시 생각해봅시다. 그럼 간단한 시나리오를 살펴보겠습니다.
프론트엔드 웹 애플리케이션의 인스턴스 3개를 배포했다고 가정해 보겠습니다. 우리는 Replication Controller 이나 ReplicaSet을 생성해서 항상 3개의 파드가 실행중인 상태로 만들고 싶습니다. 이러한 사례가 ReplicaSet을 사용하는 사례 중 하나입니다. ReplicaSet을 사용해서 기존에 이미 존재하고 있는 파드를 모니터링할 수 있습니다. 만약 파드가 기존에 없다면 ReplicaSet은 자동으로 파드를 생성해줍니다. ReplicaSet의 역할은 파드를 모니터링하고 그들 중 하나라도 실패하면 새로운 파드를 배포하는 것입니다. ReplicaSet은 사실 파드를 모니터링하는 프로세스입니다. 그런데 ReplicaSet은 어떤 파드를 모니터링할 지 어떻게 알 수 있을까요? 클러스터에 각자의 애플리케이션을 실행하고 있는 수백 개의 파드가 있을텐데요. 바로 여기서 파드의 label이 편리하게 작용합니다.
labels
을 ReplicaSet에 대한 필터로 제공할 수 있습니다. selector
섹션에서 matchLabels
필터를 사용했고, 파드를 생성할 때도 동일한 label
을 사용했습니다. 이렇게 하면 ReplicaSet이 모니터링할 파드를 알 수 있습니다.labels
와 selector
의 같은 컨셉은 Kubernetes 전체의 다른 많은 곳에서도 사용됩니다. 이제 같은 맥락에서 질문을 드리겠습니다. ReplicaSet의 spec
섹션에서 우리는 세 가지 섹션(template
, replicas
, selector
)이 있다는 것을 배웠습니다. 이전 시나리오에서 우리는 3개의 replicas가 필요하기 때문에, selector
에 그 내용을 추가했습니다. 이전 시나리오에서와 같이 이미 생성된 3개의 기존 파드가 있는 경우, 그 파드가 항상 3개가 실행되는 것을 모니터링하기 위해 ReplicaSet를 생성해야 합니다. 만약 Replication Controller가 생성된다면(?확인필요) 해당 레이블이 있는 파드가 3개가 이미 존재하기 때문에 파드의 새 인스턴스를 배포하지 않습니다. 새 파드를 배포하지 않는 이러한 경우에도 우리는 ReplicaSet의 spec
섹션에서 template
섹션을 작성해야 할까요? 네 그렇습니다. 파드 중 하나가 죽을 경우에 ReplicaSet이 파드 수를 유지하기 위해 새 파드를 만들어야 하기 때문에 그 경우를 대비하여 작성해야 합니다.
How to scale replicaset
이제 ReplicaSet을 확장하는 방법을 살펴보겠습니다. 세 개의 replicas가 있는 상태에서 시작했다고 가정해 보겠습니다. 그리고 이제는 6개로 확장하기로 결정했습니다. 6개의 replicas로 확장하기 위해 ReplicaSet를 어떻게 업데이트할까요? 여러 가지 방법이 있습니다.
첫 번째 방법
첫 번째 방법은 아래와 같이 Definition file에서 replicas 수를 6으로 업데이트하는 것입니다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-replicaset
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 6
selector:
matchLabels:
type: front-end
그런 다음 kubectl replace
혹은 kubectl apply
커맨드를 실행합니다. -f
옵션을 사용하면 쿠버네티스 리소스가 구성되어 있는 파일을 지정할 수 있습니다.
$ kubectl replace -f replicaset-definition.yaml
혹은
$ kubectl apply -f replicaset-definition.yaml
커맨드를 실행하면 6개의 replicas를 갖도록 ReplicaSet을 업데이트합니다.
두 번째 방법
두 번째 방법은 kubectl scale --replicas=6
커맨드를 실행하는 것입니다.
$ kubectl scale --replicas=6 -f replicaset-definition.yaml
세 번째 방법
세 번째 방법은 type
(replicaset)과 name
(myapp-replicaset)을 사용하여 kubectl scale
커맨드을 실행하는 것입니다.
$ kubectl scale --replicas=6 replicaset myapp-replicaset
그러나 이렇게 하면 파일이 자동으로 바뀌지는 않습니다. 여전히 Definition File 에는 replica가 3개로 정의되어 있을 것입니다.
부하에 따라 ReplicaSet을 자동으로 확장시켜주는 옵션도 있습니다. 그러나 그것은 고급 주제이므로 나중에 논의하도록 하겠습니다.
'MLOps > Doker & Kubernetes' 카테고리의 다른 글
Udemy CKA 강의 정리 30: Practice Test - ReplicaSets - Solution (Optional) (0) | 2023.01.04 |
---|---|
Udemy CKA 강의 정리 29: Practice Test - ReplicaSets (0) | 2023.01.04 |
Udemy CKA 강의 정리 27: Practice Test - Solution (Optional) (0) | 2023.01.03 |
Udemy CKA 강의 정리 26: Practice Test - Pods (0) | 2023.01.03 |
Udemy CKA 강의 정리 25: Accessing the Labs (0) | 2023.01.03 |
댓글