본문 바로가기

DevOps/쿠버네티스(Kubernetes)

[CKA] Kubernetes Replication Controller/ReplicaSets

# Kubernetes ReplicaSets

Controller 는 쿠버네티스의 두뇌이다. 그것들은 쿠버네티스 객체를 모니터링하고 그에 따라 반응하는 과정이다.
복제 컨트롤러에 대해 말해보자 그렇다면 복제본이란 무엇이며 복제 컨트롤러(replication controller)가 필요한 이유는 무엇일까?

1. HA-High Availability

애플리케이션을 실행하는 단일 Pod가 있었던 첫 번째 시나리오로 돌아가 보자. 어떤 이유로 인해 응용프로그램이 고장나면 어떻게 될까?
응용프로그램이 고장나게 되면 사용자는 더 이상 애플리케이션에 접근 할 수 없다.
사용자가 응용프로그램에 대한 접근 권한을 잃지 않도록 하기 위해 두 개 이상의 인스턴스 또는 Pod을 동시에 실행하려고 한다.
이렇게 하면, 한 개가 실패하더라도 다른 한 개에서 애플리케이션을 계속 실행할 수 있다.
복제 컨트롤러를 사용하면 Kubernetes 클러스터에서 단일 부품의 여러 인스턴스를 실행할 수 있으므로 고가용성(HA-High Availability)을 제공할 수 있다.

그렇다면 단일 Pod를 사용하려는 경우 복제 컨트롤러를 사용할 수 없다는 의미일까?
아니다, 단일 Pod가 있더라도 복제 컨트롤러는 기존 Pod가 실패할 때 자동으로 새 Pod를 불러올 수 있다. 따라서 복제 컨트롤러는 지정된 수의 Pod가 1개 또는 100개일 경우에도 항상 실행되도록 한다.

2. Load Balancing & Scaling

복제 컨트롤러가 필요한 또 다른 이유는 여러 Pod을 만들어 여러 Pod 간에 길를 공유하기 위해서이다. 예를 들어, 특정한 사용자들에세 서비스를 지원하는 단일 Pod가 있다. 사용자 수가 증가하면 추가 Pod를 배포하여 두 Pod 간에 부하를 분산한다.
수요가 더 증가하고 첫 번째 노드의 리소스가 부족할 경우 클러스터의 다른 노드에 추가 Pod를 배포할 수 있다. 복제 컨트롤러는 클러스터의 여러 노드에 걸쳐 있다. 이는 서로 다른 노드의 여러 부분에 걸쳐 부하분산을 수행하고 수요가 증가할 때 애플리케이션을 확장할 수 있도록 지원한다.

# Replication Controller ? ReplicaSet ?

Replication Controller, ReplicaSet 유사한 두 개의 용어가 있다. 둘 다 같은 목적을 가지고 있지만, 같은 것은 아니다. Replication ControllerReplicaSet으로 대체되는 이전 기술이다. ReplicaSet은 복제를 설정하는 새로운 권장 방법이다. replicaset은 replication controller와 똑같이 동작하지만 더 풍부한 표현식 pod selector를 지원해준다.

앞서 설명한 내용은 이 두 가지 기술 모두에 적용할 수 있다. 각각의 작업 방식에는 약간의 차이가 있다. 따라서 향후 모든 구현에서는ReplicaSet를 주로 사용할것이다.


# Replication Controller 작성법

rc-definition.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp-rc
  labels:
    app: myapp
    type: front-end
spec:
  template: 
    만들고 싶은 pod 내용


이제 복제 컨트롤러를 만드는 방법을 살펴보자. 복제 컨트롤러 정의 yaml 파일을 만드는 것으로 시작한다.
API 버전은 우리가 만드는 것에 따라 다르다. 복제 컨트롤러는 KubernetesAPI버전 v1 지원되므로 v1으로 설정한다.
kind는 ReplicationController 이다. metadata 아래에 이름을 추가하고 몇 개의 레이블 앱을 추가하고 값을 입력하여 할당한다.

지금까지는 Pod를 만드는 방법과 매우 유사하다.
다음은 정의 파일에서 가장 중요한 부분이고 그것은 spec으로 작성된 사양이다. 모든 Kubernetes 정의 파일의 경우, spec 섹션은 우리가 만들고 있는 개체 내부에 무엇이 있는지 정의한다.

pod-definition.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    type: front-end
spec:
  containers: 
  - name: nginx-container
    image: nginx


이 경우 복제 컨트롤러가 Pod 인스턴스를 여러 개 생성한다. 어떤 Pod를 생성할까? 복제 컨트롤러가 복제본을 작성하는 데 사용할 Pod 템플릿을 제공하기 위해 spec아래에 template 섹션을 작성한다.
Pod 템플릿을 어떻게 정의할까? 이전 연습에서 Pod 정의 파일을 만들었다. 파일 내용을 다시 사용하여 템플릿 섹션을 채울 수 있다. Pod API 버전 및 종류인 처음 몇 줄을 제외하고 정의 파일의 모든 내용을 복제 컨트롤러의 템플릿 섹션으로 이동하자. 이동되는 모든 항목은 템플릿 섹션 아래에 있어야 한다. 즉, 템플릿 선 자체보다 오른쪽에 배치하고 앞에 더 많은 공백을 두어 템플릿 섹션의 하위 항목으로 넣어야한다.


rc-definition.yaml

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


지금 우리의 파일을 보면, 우리는 두 개의 메타데이터 섹션이 있다. 하나는 복제 컨트롤러용이고 다른 하나는 Pod용이다. 그리고 우리는 두 가지 spec을 각각 하나씩 가지고 있다. 두 개의 정의 파일을 함께 중첩했다. 복제 컨트롤러가 상위이고 포드 정의가 하위이다.


rc-definition.yaml

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


하지만 여전히 부족한 것이 있다. 복제 컨트롤러에 필요한 복제본 수에 대해서는 언급하지 않았다. 복제본이라는 다른 특성을 spec에 추가하고 그 아래에 필요한 복제본 수를 입력한다. template와 replicas은 spec 섹션의 직계 하위이므로 형제이며 동일한 수직선에 있어야 한다. 즉, template앞에 동일한 수의 공백을 두어야 한다.


$ kubectl create -f rc-definition.yml

-f 매개 변수를 사용하여 파일을 입력하여 생성한다. 복제 컨트롤러는 복제 컨트롤러가 생성될 때 생성된다. 먼저 필요한 수만큼 Pod 정의 템플릿을 사용하여 Pod를 생성한다.(이 경우 3)

$ kubectl get replicationcontroller


생성된 복제 컨트롤러 목록을 보려면 위의 명령어를 실행하면 복제 컨트롤러 목록을 볼 수 있다. 또한 원하는 복제본 수 또는 Pod, 현재 복제본 수 및 실행 된 복제본 수를 볼 수 있다.

$ kubectl get pods
NAME            READY STATUS RESTARTS AGE
myapp-rc-djkfjd  1/1   Running  0    20s
myapp-rc-wekwrk  1/1   Running  0    20s
myapp-rc-sfmdmf  1/1   Running  0    20s


복제 컨트롤러에서 만든 Pod를 보려면 위의 명령어를 샐행하면 된다. 세 개의 Pod가 실행 중임을 확인할 수 있다. 모두 복제 컨트롤러의 이름으로 복제 컨트롤러에 의해 자동으로 생성됨을 나타내는 myapp-rc으로 시작한다.


# Replica Set 작성법

replicaset-definition.yml

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

이제 Replica Set을 살펴보자. 복제 컨트롤러와 매우 유사하다. 먼저 API 버전 종류의 메타데이터와 스펙이 있다. 하지만 API 버전은 조금 다르다. apps/v1 으로, 이전에 v1이었던 ReplicationController와 다르다. 만약 이것을 틀리게 쓴다면, '지정된 Kubernetes API 버전은 Replica Set를 지원하지 않기 때문에 kind=ReplicaSet에 일치하지 않습니다' 라는 오류가 나오게 된다.

kind는 ReplicaSet이며 metadata 에 이름과 레이블을 추가한다. spec 섹션은 Replication Controller와 매우 유사하다. 이전과 같이 Pod 정의를 제공하는 template 섹션이 있다.

그러나 Replication ControllerReplicaSet 사이에는 한 가지 중요한 차이가 있다. Replica Set에는 selector 정의가 필요하다. selector 섹션은 ReplicaSet이 그 아래에 속하는 Pod를 식별하는 데 도움이 된다. 그런데 왜 그 아래에 해당하는 Pod을 지정해야 할까? Template에 Pod 정의 파일 자체의 내용을 제공한 경우 Replica Set은 Replica Set 생성의 일부로 생성되지 않은 Pod도 관리할 수 있다.


# Labels and Selector

Kubernetes에서 Pod와 객체에 레이블을 지정하는 이유가 뭘까? 간단한 시나리오를 살펴보자. front-end 웹 애플리케이션의 인스턴스를 세 Pod로 배포했다고 가정해 보자. 언제든지 세 개의 활성 Pod를 가질 수 있도록 Replication Controller 또는 ReplicaSet를 작성하려고 한다. 그것은 ReplicaSet의 사용 사례 중 하나이다.

이미 생성된 기존 Pod를 모니터링하는데 사용할 수 있다. 생성되지 않은 경우 ReplicaSet이 해당 Pod을 대신 생성한다. ReplicaSet의 역할은 Pod들을 모니터링한 후 고장난 Pod가 있으면 새 Pod를 배포하는 것이다. ReplicaSet는 실제로 Pod를 모니터링하는 프로세스이다.

# replicaset-definition.yml
selector:
  matchLabels:
    tier: front-end
    
    
# pod-definition.yml
metadata:
  name: myapp-pod
  labels:
    tier: front-end


이제 복제본 집합이 모니터링할 Pod을 어떻게 알 수 있을까? 클러스터에는 다른 애플리케이션을 실행하는 수백 개의 다른 Pod가 있을 수 있다. 여기서 Pod를 생성하면서 Pod에 라벨을 붙이는 것이 유용하다. 이제 이러한 레이블을 Replica Set에 대한 필터로 제공할 수 있다.
selector 섹션에서 matchLabels 필터를 사용하고 Pod를 만들 때 사용한 것과 동일한 레이블을 제공한다. 이렇게 하면 ReplicaSet이 모니터링할 Pod를 알 수 있다. 같은 개념의 label과 selector는 kubernetes 전역에서 사용된다.

ReplicaSet sepc 섹션에서는 templete, replicas, selector 세 개의 섹션이 있다.
예를 들어, 이전 슬라이드와 동일한 시나리오에서 이미 3개의 기존 Pod가 생성되었으며, 이를 위해 Pod을 모니터링하기 위해 Replica Set을 생성해야 한다. ReplicationController가 생성될 때 일치하는 레이블을 가진 세 개의 Pod가 이미 생성되었기 때문에 Pod의 새 인스턴스를 배포하지 않는다.

이 경우 ReplicaSet이 배포 시 새 Pod를 만들 것으로 예상되지 않으므로 ReplicaSet spec에 template 섹션을 제공하지 않아도 될까?
아니다, Pod 중 하나가 나중에 고장날 경우, Replica Set은 원하는 Pod 수를 유지하고 ReplicaSet은 새 Pod 만들어야 하기 때문에 템플릿 정의 섹션이 필요하다.

# Scale

ReplicaSet를 확장하는 방법을 살펴보자. 우리가 세 개의 복제본으로 시작했다고 가정해 보자. 앞으로는 6개로 확장하기로 결정했다.
ReplicaSet를 6개까지 확장하도록 업데이트하려면 어떻게 해야 할까?

# replicaset-definition.yml
replicas: 3 → replicas: 6

$ kubectl replace -f replicaset-definition.yml


첫 번째는 정의 파일의 복제본 수를 6개로 업데이트하는 것이다. 그런 다음 kubectl replace 명령을 실행하여 -f 매개변수를 사용하여 동일한 파일을 지정하고 ReplicaSet이 6개의 복제본으로 업데이트되도록 한다.


$ kubectl scale --replicas=6 -f replicaset-definition.yml
$ kubectl scale --replicas=6 replicaset myapp-replicaset


두 번째 방법은 스케일 명령을 실행하는 것이다. replicas 매개변수를 사용하여 새 복제본 수를 제공하고 입력과 동일한 파일을 지정한다.
정의 파일을 입력하거나 유형 이름 형식으로 ReplicaSet 이름을 제공할 수 있다. 그러나 파일 이름을 입력으로 사용하면 파일에서 복제본 수가 자동으로 업데이트되지 않는다. 즉, ReplicaSet 정의 파일의 복제본 수는 여전히 3개이다.









출처:
https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/learn/lecture/14298658#overview

'DevOps > 쿠버네티스(Kubernetes)' 카테고리의 다른 글

[CKA] Kubernetes Services  (0) 2022.09.24
[CKA] Kubernetes Deployment  (1) 2022.09.24
[CKA] Kubernetes Pod 와 YAML 파일  (0) 2022.09.03
[CKA] Kubernetes Pod  (0) 2022.09.03
[CKA] Kubernetes kubelet / Kube-Proxy  (0) 2022.09.03