게으름을 위한 부지런한 게으름뱅리' 블로그

[K8S] K8S에서 공용 Data 사용하기 (StatefulSet yaml 예시 ) 본문

IT/K8S

[K8S] K8S에서 공용 Data 사용하기 (StatefulSet yaml 예시 )

LazismLee 2024. 7. 1. 22:18
반응형

StatefulSet은 Kubernetes에서 stateful 애플리케이션을 배포하고 관리하기 위한 리소스입니다. 각각의 Pod에 고유한 식별자를 부여하고, 순차적으로 배포하며, 안정적인 네트워킹 및 스토리지 구성을 제공합니다. StatefulSet을 사용하는 장단점을 살펴보겠습니다.

장점

 

  • 고유한 식별자: 각 StatefulSet Pod에는 고유한 순차적 식별자가 자동으로 할당됩니다. 이는 데이터베이스나 메시지 큐와 같이 각 인스턴스가 고유한 이름이나 식별자를 가져야 하는 애플리케이션에 유용합니다.
  • 순차적 배포: StatefulSet은 Pod을 순차적으로 배포 및 업데이트할 수 있습니다. 이는 애플리케이션의 초기화, 데이터 복제 및 데이터베이스 스케일링 등에서 매우 유용합니다.
  • 안정적인 네트워킹: 각 Pod에 고유한 DNS 엔트리가 자동으로 생성되어, 서비스 디스커버리 및 내부 통신을 용이하게 합니다.
  • 관리된 스토리지: StatefulSet은 각 Pod에 고유한 PersistentVolumeClaim (PVC)을 자동으로 생성할 수 있습니다. 이를 통해 각 인스턴스가 독립적인 데이터 스토리지를 사용할 수 있으며, 데이터의 안전한 관리가 가능합니다.
  • 롤링 업데이트와 롤백: StatefulSet은 Pod을 업데이트하고 롤백하는 기능을 지원합니다. 이는 애플리케이션 업데이트 중에도 무중단 서비스를 제공할 수 있도록 합니다.

단점

 

  • 복잡성: StatefulSet 설정 및 관리는 Stateless 애플리케이션에 비해 복잡할 수 있습니다. 특히, 네트워크 설정이나 스토리지 구성에서 추가적인 고려가 필요할 수 있습니다.
  • 배포 시간: 각 Pod을 순차적으로 배포하는 점은 배포 시간이 길어질 수 있습니다. StatefulSet은 파드간에 순서를 유지하므로 이러한 순차적 배포는 일반적으로 더 많은 시간이 소요됩니다.
  • 스케일링의 제한: StatefulSet은 Pod을 일반적인 ReplicationController나 Deployment처럼 쉽게 수평으로 스케일링할 수 없습니다. 각 Pod은 고유한 상태를 가지므로 스케일링은 일반적으로 수직적으로 이루어집니다.
  • 삭제 시 관리 오버헤드: StatefulSet에서 Pod을 삭제할 때, 관련된 PersistentVolumeClaim (PVC)도 수동으로 삭제해야 할 수 있습니다. 이로 인해 관리 오버헤드가 발생할 수 있습니다.

StatefulSet은 stateful 애플리케이션을 Kubernetes 환경에서 안정적으로 관리하고 배포하는 데 매우 유용한 도구입니다. 그러나 복잡성과 배포 시간, 스케일링 제한 등 몇 가지 주의할 점이 있습니다. 애플리케이션의 특성과 요구 사항에 따라 StatefulSet을 적절히 선택하고, 적절한 구성을 고려하는 것이 중요합니다.

예시 1: 데이터베이스 클러스터 배포

1. StatefulSet 정의 (mysql-statefulset.yaml)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql  # StatefulSet의 이름
spec:
  serviceName: mysql  # StatefulSet에서 사용할 Headless Service의 이름
  replicas: 3  # Replica 수, 즉 Pod의 개수
  selector:
    matchLabels:
      app: mysql  # Pod를 선택할 Label Selector
  template:
    metadata:
      labels:
        app: mysql  # Pod의 Label
    spec:
      containers:
        - name: mysql  # 컨테이너 이름
          image: mysql:5.7  # 사용할 컨테이너 이미지
          env:
            - name: MYSQL_ROOT_PASSWORD  # MySQL 루트 패스워드 환경 변수 설정
              value: password
          ports:
            - containerPort: 3306  # 컨테이너가 Listen할 포트 설정
          volumeMounts:
            - name: mysql-persistent-storage  # 마운트할 볼륨 이름
              mountPath: /var/lib/mysql  # 컨테이너 내에서 볼륨을 마운트할 경로
  volumeClaimTemplates:
    - metadata:
        name: mysql-persistent-storage  # PVC 템플릿의 이름
      spec:
        accessModes: [ "ReadWriteOnce" ]  # PVC의 액세스 모드 설정
        resources:
          requests:
            storage: 10Gi  # 요청할 스토리지 용량

 

 

 

2. MySQL 데이터베이스 서비스 정의 (mysql-service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: mysql  # 서비스의 이름
spec:
  ports:
    - port: 3306  # 서비스가 Listen할 포트
      targetPort: 3306  # 연결할 타겟 포트
  selector:
    app: mysql  # 서비스가 연결할 Pod 선택을 위한 Label Selector

예시 2: 메시징 시스템 클러스터 배포

메시징 시스템을 StatefulSet을 사용하여 배포하는 방법을 보여줍니다.

 

1. StatefulSet 정의 (rabbitmq-statefulset.yaml)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rabbitmq  # StatefulSet의 이름
spec:
  serviceName: rabbitmq  # Headless Service의 이름
  replicas: 3  # Replica 수, 즉 Pod의 개수
  selector:
    matchLabels:
      app: rabbitmq  # Pod를 선택할 Label Selector
  template:
    metadata:
      labels:
        app: rabbitmq  # Pod의 Label
    spec:
      containers:
        - name: rabbitmq  # 컨테이너 이름
          image: rabbitmq:3.8-management  # 사용할 컨테이너 이미지
          ports:
            - containerPort: 5672  # 컨테이너가 Listen할 포트 설정
            - containerPort: 15672  # RabbitMQ 관리 포트 설정
          volumeMounts:
            - name: rabbitmq-data  # 마운트할 볼륨 이름
              mountPath: /var/lib/rabbitmq  # 컨테이너 내에서 볼륨을 마운트할 경로
  volumeClaimTemplates:
    - metadata:
        name: rabbitmq-data  # PVC 템플릿의 이름
      spec:
        accessModes: [ "ReadWriteOnce" ]  # PVC의 액세스 모드 설정
        resources:
          requests:
            storage: 5Gi  # 요청할 스토리지 용량

 

2. RabbitMQ 서비스 정의 (rabbitmq-service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: rabbitmq  # 서비스의 이름
spec:
  ports:
    - port: 5672  # 서비스가 Listen할 포트
      targetPort: 5672  # 연결할 타겟 포트
    - port: 15672  # RabbitMQ 관리 포트
      targetPort: 15672  # 연결할 타겟 포트
  selector:
    app: rabbitmq  # 서비스가 연결할 Pod 선택을 위한 Label Selector

 

예시 3: 분산 파일 시스템 클러스터 배포

이 예시에서는 분산 파일 시스템을 StatefulSet을 사용하여 배포하는 방법을 보여줍니다.

1. StatefulSet 정의 (glusterfs-statefulset.yaml)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: glusterfs  # StatefulSet의 이름
spec:
  serviceName: glusterfs  # Headless Service의 이름
  replicas: 3  # Replica 수, 즉 Pod의 개수
  selector:
    matchLabels:
      app: glusterfs  # Pod를 선택할 Label Selector
  template:
    metadata:
      labels:
        app: glusterfs  # Pod의 Label
    spec:
      containers:
        - name: glusterfs  # 컨테이너 이름
          image: gluster/gluster-centos:latest  # 사용할 컨테이너 이미지
          command:
            - "/bin/bash"
            - "-c"
            - "while true; do sleep 3600; done"  # 컨테이너가 실행할 명령 설정
          volumeMounts:
            - name: glusterfs-data  # 마운트할 볼륨 이름
              mountPath: /data  # 컨테이너 내에서 볼륨을 마운트할 경로
  volumeClaimTemplates:
    - metadata:
        name: glusterfs-data  # PVC 템플릿의 이름
      spec:
        accessModes: [ "ReadWriteOnce" ]  # PVC의 액세스 모드 설정
        resources:
          requests:
            storage: 20Gi  # 요청할 스토리지 용량

 

2. GlusterFS 서비스 정의 (glusterfs-service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: glusterfs  # 서비스의 이름
spec:
  ports:
    - port: 24007  # 서비스가 Listen할 포트
      targetPort: 24007  # 연결할 타겟 포트
    - port: 24008  # 서비스가 Listen할 포트
      targetPort: 24008  # 연결할 타겟 포트
    - port: 49152  # 서비스가 Listen할 포트
      targetPort: 49152  # 연결할 타겟 포트
  selector:
    app: glusterfs  # 서비스가 연결할 Pod 선택을 위한 Label Selector

 

이 예시들은 각각 다른 stateful 애플리케이션을 StatefulSet을 사용하여 Kubernetes에서 배포하는 방법을 보여줍니다. 각 Pod은 고유한 식별자를 가지며, 고유한 PersistentVolumeClaim (PVC)을 통해 데이터를 관리할 수 있습니다.

반응형
Comments