본문 바로가기

카테고리 없음

[K8S] StatefulSet과 Deployment의 차이점

Goal

쿠버네티스 컨트롤러의 종류 중 StatefulSet과 Deployment의 차이점을 알아보고, 어떤 상황에서 어떤 컨트롤러를 사용하는 것이 적합한지 이해합니다.

 

안녕하세요, 오늘은 StatefulSet과 Deployment의 차이점에 대해 알아보도록 하겠습니다. 
Kubernetes에서 StatefulSet과 Deployment는 컨테이너화된 애플리케이션의 배포와 관리를 담당하는 리소스 컨트롤러입니다. 그러나 둘 사이에는 몇 가지 중요한 차이점이 있습니다. 비슷하게 파드를 유지하고 관리하는 역할을 하는 것처럼 보이는 두개의 컨트롤러가 왜 별도로 제공되는지 이해하기 위해, StatefulSet과 Deployment의 차이점에 대해 자세히 살펴보겠습니다.

 

Deployment?

Kubernetes Deployment 컨트롤러는 컨테이너화된 애플리케이션의 배포와 업데이트를 관리하는 리소스 컨트롤러입니다. 즉, 애플리케이션의 릴리즈와 롤링 업데이트를 쉽게 수행할 수 있도록 도와줍니다. Deployment를 사용하면 애플리케이션의 무중단 업데이트, 롤백, 그리고 복잡한 배포 전략 등을 쉽게 구현할 수 있습니다.

Deployment 컨트롤러는 쿠버네티스 클러스터 내에서 애플리케이션의 상태를 지속적으로 모니터링하고 필요한 변경사항을 적용합니다. 이를 통해 애플리케이션의 배포와 업데이트 프로세스를 자동화하고, 개발자들은 애플리케이션의 로직에 집중할 수 있도록 도와줍니다.

# Deployment 예시
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app-container
          image: my-app-image:v1
          ports:
            - containerPort: 80

 

StatefulSet?

StatefulSet은 Deployment와 유사하게 동작하지만, 고유한 이름과 안정적인 네트워크 식별자를 갖는 파드를 관리하는 데 특화되어 있습니다. 주로 데이터베이스와 같이 각 파드의 상태가 중요하고 고유한 식별자가 필요한 애플리케이션에 사용됩니다.

StatefulSet은 애플리케이션의 상태와 안정성이 중요한 경우에 유용하며, 특히 데이터베이스나 메시징 시스템과 같이 데이터 지속성과 식별자가 중요한 애플리케이션에 적합합니다.

# StatefulSet 예시코드

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-stateful-app
spec:
  replicas: 3
  serviceName: my-stateful-service
  selector:
    matchLabels:
      app: my-stateful-app
  template:
    metadata:
      labels:
        app: my-stateful-app
    spec:
      containers:
        - name: my-stateful-app-container
          image: my-stateful-app-image:v1
          ports:
            - containerPort: 80
          volumeMounts:
            - name: data
              mountPath: /data
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        storageClassName: "standard"
        resources:
          requests:
            storage: 1Gi

 

주요 차이점

유일한 식별자 사용 유무 (Unique Identifier)

- Deployment

Deployment는 파드를 생성할 때 마다 무작위로 생성된 유일한 식별자를 할당합니다. 이로 인해 파드의 이름은 무작위 문자열과 숫자의 조합으로 이루어집니다.
- StatefulSet

StatefulSet은 파드를 생성할 때 순서대로 번호를 할당하여 유일한 이름을 만듭니다. 예를 들어, 첫 번째 파드는 `web-0`, 두 번째 파드는 `web-1`, 이런 식으로 순차적으로 이름이 지정됩니다.

볼륨과 데이터 영속성   

- Deployment

Deployment는 롤링 업데이트를 위해 일시적인 파드를 생성하고 삭제합니다. 이로 인해 Deployment는 기본적으로 쿠버네티스의 `emptyDir`과 같은 일시적인 볼륨을 사용합니다. Deployment에서도 고정적인 볼륨을 연결할 수 있지만, Statefulset과  같이 선언 시에 PVC(Persistent Volume Claim)를 함께 선언할 수 없어 별도로 생성해야 하며, Pod Replica 개수가 2개 이상인 경우 각각의 Pod를 다른 볼륨에 연결할 수 있는 방법이 없습니다. 모든 Pod가 같은 PVC에 연결이 되는 의도치않은 상황이 발생할 수 있습니다.

- StatefulSet

StatefulSet은 파드가 고유한 식별자를 갖고 있으므로 각 파드에 PV(Persistent Volume)을 연결할 수 있습니다. 이로 인해 파드는 생성 및 삭제되어도 데이터 유실이 발생하지 않습니다. 일반적으로 StatefulSet에는 `PersistentVolumeClaim`을 함께 선언하여 지속적인 데이터 스토리지를 파드와 연결하여 사용합니다. 파드가 종료된 후 재실행되더라도 고정적으로 파드와 정해진 볼륨이 연결됩니다.

스케일링 및 업데이트

- Deployment

Deployment는 파드의 수평적 스케일링과 롤링 업데이트를 지원합니다. 여러 개의 파드를 빠르게 생성하고, 업데이트할 수 있으며, 애플리케이션의 무중단 배포를 쉽게 수행할 수 있습니다.
- StatefulSet

StatefulSet은 파드의 순차적인 스케일링과 안정적인 롤링 업데이트를 지원합니다. 파드를 하나씩 순차적으로 생성하고 삭제하며, 각 파드의 상태가 안정화된 후에 다음 파드를 생성합니다. 이로 인해 StatefulSet은 일련의 파드를 안정적으로 조작하여 데이터 유실을 방지합니다. 특히 이런 기능은 클러스터 기반의 데이터베이스를 구성할 때 도움이 됩니다. 클러스터에서 데이터베이스 파드가 제거되고 추가되는 동작이 순차적으로 발생하기 때문에 데이터베이스를 안정적으로 운영할 수 있습니다.

Pod Identity

 - Deployment

Deployment의 파드는 노드 호스트가 변경될 수 있으며, 파드를 재시작하면 새로운 IP 주소를 할당받습니다. 이로 인해 클러스터 내부 또는 외부에서 파드에 접근하기가 어렵습니다.
- StatefulSet

StatefulSet의 파드는 고유한 이름을 갖고 있으며, 노드 호스트가 변경되어도 동일한 이름을 유지합니다. 이로 인해 파드의 고정적인 이름과 IP 주소를 통해 <pod-name>.<service-name>.<namespace>.svc.cluster.local 형식으로 각각의 파드에 접근하기에 용이합니다.

예를 들어, StatefulSet으로 3개의 파드를 생성하는 경우를 생각해보겠습니다. 각 파드에는 순차적으로 고유한 이름이 부여됩니다.

파드 1: web-0
파드 2: web-1
파드 3: web-2

그러나 Deployment로 생성한 파드 이름은 아래와 같이 무작위 해시값이 붙고, 재시작 시에 해당 값이 변경됩니다.

파드 1: my-deployment-56b86bcf86-7m6mz
파드 2: my-deployment-56b86bcf86-n45ss
파드 3: my-deployment-56b86bcf86-xbwbh

이처럼 StatefulSet의 경우 파드가 고유한 이름과 DNS 이름을 유지하기 때문에 파드 2(web-1)는 새로운 노드로 이동하더라도 이름과 DNS 이름은 변하지 않습니다. 따라서 이전의 web-1 이름과 IP 주소가 새로운 노드에서도 동일하게 유지됩니다.
이러한 특성은 데이터베이스와 같이 데이터의 일관성과 지속성이 중요한 애플리케이션에서 매우 유용합니다.

 

결론

이렇게 StatefulSet과 Deployment는 서로 다른 사용 사례와 동작 방식을 갖고 있습니다.

StatefulSet의 기능들은 주로 데이터베이스와 같이 데이터의 안정성과 지속성이 중요한 애플리케이션에 적합하며, 

Deployment는 단순한 웹 서버와 같이 빠른 배포와 스케일링이 필요한 애플리케이션에 더 적합합니다.

 

Deployment와 Statefulset의 동작 차이점에 대해 자세히 알고, 쿠버네티스에 실행시키려는 앱의 특성에 맞는 컨트롤러를 고르셔서 사용하시는데에 제 글이 도움이 되었기를 바랍니다.

 

감사합니다.