ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] Replica Set
    Kubernetes 2024. 4. 3. 23:18
    728x90

    Pod는 여러 개의 컨테이너를 추상화해 하나의 애플리케이션으로 동작하도록 만드는 훌륭한 컨테이너 묶음이다.

    그러나 YAML에 파드만 정의해 생성하게 되면 이 파드의 LifeCycle은?

    kubectl delete 명령어로 파드를 삭제하게 되면 그 파드의 컨테이너 또한 삭제된 뒤 쿠버네티스에서 영원히 사라지게 도니다.  이렇게 YAML 파일에 파드만 정의해 생성할 경우 해당 파드는 오직 쿠버네티스 사용자에 의해 관리된다. 이렇게 되면 단순히 파드의 기능을 테스트하는 것이 아닌 실제 외부 사용자의 요청을 처리해야 하는 MSA 구조의 파드라면 이러한 방식을 사용하기 어렵다. MSA에서는 여러 개의 동일 컨테이너를 생성한 뒤 외부 요청이 각 컨테이너에 적절히 분배될 수 있어야 한다.

    쿠버네티스에서는 파드가 기본 단위이기 때문에, 동일한 여러 개의 파드를 생성해 외부 요청을 각 파드에 분배하는 방식을 사용해야 한다. 가장 간단한 방법은 다른 이름을 가지는 여러 개의 파드를 직접 만드는 방식이다.

    apiVersion: v1
    kind: Pod
    metadata:
        name: my-nginx-pod-a
    spec:
        containers:
        - name: my-nginx-container
          args: ["-f", "/dev/null"] # 컨테이너가 종료되지 않도록 유지
    ---
    apiVersion: v1
    kind: Pod
    metadata:
        name: my-nginx-pod-b
    spec:
        containers:
        - name: my-nginx-container
          args: ["-f", "/dev/null"] # 컨테이너가 종료되지 않도록 유지

    그러나 여러 개의 파드를 직접 생성하는 방법은 비효율적인 작업이며, 파드가 생성된 노드에 장애가 발생하더라도 파드는 다른 노드에서 다시 생성되지 않는다. 이러한 한계를 해결하기 위해 Replica Set이 등장하게 되었다.

    Replica Set은 정해진 수의 동일한 파드가 항상 실행되도록 관리하며, 노드 장애 등의 이유로 파드를 사용할 수 없다면 다른 노드에서 파드를 다시 생성한다.

    # 레플리카셋 적용
    apiVersion: v1
    kind: ReplicaSet
    metadata:
        name: replicaset-nginx
    spec:
        replicas: 3
        selector:
         matchLabels:
           app: my-nginx-pods-label
        template:
          metadata:
            name: my-nginx-pod
            labels:
              app: my-nginx-pods-label
          spec:
          
            containers:
            - name: my-nginx-container
            image: nginx:latest
            ports:
            - containerPort: 80
              protocol: TCP
    
            - name: ubuntu-sidecar-container
            image: alicek106/rr-test:curl
            command: ["tail"]
            args: ["-f", "/dev/null"] # 컨테이너가 종료되지 않도록 유지

    레플리카셋의 파드 개수를 변경하기 위해 이미 생성된 레플리카셋을 삭제하고 다시 생성할 필요는 없다.

    쿠버네티스에서는 이미 생성된 리소스의 속성을 변경하는 기능을 제공하기 때문이다.

    삭제 시에는 kubectl delete rs 명령어를 사용하면 레플리카셋에 의해 생성된 파드 또한 삭제된다.

     

    레플리카셋의 동작 원리

    레플리카셋은 파드와 연결되어 있지 않으며 느슨한 연결을 유지한다. 이러한 느슨한 연결은 파드와 레플리카셋의 정의 중 라벨 셀렉터를 통해 이뤄진다.

    파드 생성 시 metadata 항목에서 리소스의 부가적인 정보를 설정할 수 있다고 했다. 그 부가 정보 중에는 리소스의 고유한 이름뿐 아니라 주석, 라벨 등도 포함된다. 특히 라벨은 파드 등의 쿠버네티스 리소스를 분류할 때 유용하게 사용할 수 있는 메타데이터이다.

    라벨은 쿠버네티스 리소스의 부가적인 정보를 표현할 수 있을 뿐 아니라 서로 다른 오브젝트가 서로를 찾아야 할 때 사용되기도 한다.

    레플리카셋과 파드의 레벨은 고유한 키-값 쌍이어야만 한다. 레플리카셋과 동일한 라벨을 가지는 파드를 직접 생성하는 것은 바람직하지 않다.

     

    레플리카셋이 생성해 놓은 파드의 레벨을 삭제한다면 어떻게 될까?

    kubectl edit : 리소스의 속성을 변경할 수 있도록 텍스트 편집기를 실행하며, 변경 사항을 적용하려면 파일을 저장한 뒤 빠져나온다.

    kubectl edit 명령어는 파드뿐만 아니라 모든 종류의 쿠버네티스 오브젝트에 사용할 수 있으며, YAML에서 설정하지 않았던 상세한 리소스의 설정까지 확인할 수 있다. 예로, 레플리카셋으로부터 생성된 파드는 레플리카셋의 이름을 ownerReferences 항목에 저장하고 있다.

    레플리카셋의 목적은 파드를 생성하는 것이 아닌, 일정 개수의 파드를 유지하는 것이다.

    replicas에 설정된 숫자만큼 동일한 파드를 유지해 바람직한 상태로 만드는 것임을 잊지 말아야 한다.

    레플리카셋은 matchExpression 기반의 라벨 셀렉터를 사용할 수 있다.

    ...
    selector:
    	matchExpressions:
          - key: app
      		values:
              - my-nginx-pods-label
              - your-nginx-pods-label
            operator: In
        template:
     ...

    위 예시는 키가 app인 라벨을 가지고 있는 파드들 중에서 values 항목에 정의된 값들이 존재하는 파드들을 대상으로 레플리카셋 내 관리를 하겠다는 의미이다. 즉, app: my-nginx-pods-label이라는 라벨을 가지는 파드뿐 아니라 app: your-nginx-pods-label이라는 라벨을 가지는 파드 또한 레플리카셋의 관리하에 놓인다.

    728x90
Designed by Tistory.