본문 바로가기
MLOps/Doker & Kubernetes

Udemy CKA 강의 정리 28: Recap - ReplicaSets

by 공부하는 무니 2023. 1. 4.
반응형

해당 내용은 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과 마찬가지로 apiVersionkindmetadataspec 네 개의 섹션이 있습니다.

  • apiVersion: API 버전은 우리가 만드는 항목에 따라 다릅니다. 지금은 Replication controller를 만드는데, Replication controller은 Kubernetes API 버전 v1에서지원됩니다. 따라서 apiVersion은 v1으로 설정하겠습니다.
  • kindReplicationController입니다.
  • metadata: metadata는 딕셔너리입니다. 여기에 파드의 이름과 label을 정의할 수 있습니다. - namemyapp-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에서 apiVersionkind를 제외한 내용이 template 아래에 들어갑니다.

  • spec: spec도 딕셔너리 이며, ReplicationController Definition File에서의 spec안에는 template이 있습니다.
    • template : 복제할 Pod의 템플릿이 들어가며, 템플릿 아래에는 파드의 metadataspec 이 들어갑니다.
    • 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와 매우 유사하며, 마찬가지로 apiVersionkindmetadataspec 네 개의 섹션이 있습니다.

  • apiVersion: apps/v1 입니다. Replication controller을 생성할 때에는 v1을 입력했습니다. 이 부분 유의해주세요. 만약 잘못 입력하면 해당 Kubernetes API version이 ReplicaSet을 지원하지 않는다고 아래와 같은 에러가 날 것입니다.
    error: unable to recognize "replicaset-difinition.yaml": no matches for /, kind=RedplicaSet
  • kindReplicaSet입니다.
  • metadata: metadata는 딕셔너리입니다. 여기에 파드의 이름과 label을 정의할 수 있습니다.
    • namemyapp-replicaset로 지정합니다.
    • labels: labels 또한 딕셔너리 입니다. 여기에 원하는 만큼 label을 추가할 수 있습니다. 지금은 app: myapp와 type: front-end을 지정해주었습니다.
  • spec: spec도 딕셔너리 이며, ReplicaSet Definition File의 spec안에는ReplicationController Definition File과 유사하게 template이 있습니다.
    • template : 복제할 Pod의 템플릿이 들어가며, 템플릿 아래에는 파드의 metadataspec 이 들어갑니다.
    • 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섹션에서 우리는 세 가지 섹션(templatereplicasselector)이 있다는 것을 배웠습니다. 이전 시나리오에서 우리는 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을 자동으로 확장시켜주는 옵션도 있습니다. 그러나 그것은 고급 주제이므로 나중에 논의하도록 하겠습니다.

반응형

댓글