3. 워크로드 운영 리소스(컨트롤러) : ReplicaSet, Deployment, StatuefultSet

MAYFIFTH·2025년 6월 4일

K8S

목록 보기
3/10

0️⃣워크로드

쿠버네티스 클러스터 내에서 실행되는 애플리케이션, 서비스 배포의 단위

  • 워크로드 관리 리소스를 통해 사용자 요구 사항(배포, 운영, 확장) 수행 가능
    • ReplicaSet, Deployment, StatefulSet 등
  • YAML 등의 파일 형식을 통해 애플리케이션의 수명주기를 선언적 방식으로 관리 가능

  • Deployment를 선언적 방식으로 작성한 예
apiVersion: apps/v1beta1
kind: Deployment
metadata:
	name: nginx-deployment
spec:
	replicas: 2
	template:
		metadata:
			labels:
				app: demo-app
		spec:
			containers:
			- name: hello-world
				image: hello-world:latest
				ports:
				- containerPort: 80

1️⃣ ReplicaSet

  • Downtime이 없는 안정적인 서비스를 위해 동시 구동되는 파드들의 집합을 관리
  • 레플리카 구성을 갖춘 파드들의 배포 규격에 정의된 수 만큼의 파드의 정상적인 구동을 보장
    • 대상 파드 중 하나가 오류로 인해 정지되면, 동일한 스펙의 새 파드를 즉시 다시 배포

💡즉, 레플리카 셋은 동일한 스펙과 규격을 가진 복제본 파드를 가지고, 파드 다운 시 바로 복제본으로 대체하는 리소스다.

  • 레플리카셋 예시
    • replicaset-example.yaml

      apiVersion: apps/v1
      kind: ReplicaSet
      metadata:
        name: nginx-replicaset
        labels:
          app: nginx
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
              - name: nginx
                image: nginx:latest
                ports:
                  - containerPort: 80
      
      kubectl apply -f replicaset-example.yaml # 배포
      
      kubectl get replicaset # 조회
      
      kubectl get pods -l app=nginx # matchLabels 조회
      
      kubectl delete pod [name] # 삭제하면 새로운 Pod가 생성되서 실행되는 것을 확인 가능

2️⃣ Deployment

  • 파드와 레플리카셋에 대한 선언적 업데이트 제공
  • 롤링 업데이트를 포함한 애플리케이션 버전 및 배포 관리에 주로 사용
    • 레플리카셋의 상위 객체로, 애플리케이션 및 서비스 단위 관리로 가장 많이 사용

  • 디플로이먼트 예시 deployment-example.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx:1.14.2
              ports:
                - containerPort: 80
    $ kubectl set image deployment/nginx-deployment nginx=nginx:1.16 # 1.16 버전으로 재배포
    $ kubectl rollout status deployment/nginx-deployment # 상태 확인
    $ kubectl get pods -l app=nginx
    $ kubectl describe pods nginx-deployment
  • 클러스터 내부 컨테이너 이미지는 1.14.2 로 첫 배포 되었고, 이를 set image 명령어로 1.16으로 변경
  • rollout status 명령어로 롤링 업데이트 상태를 확인한 후, describe 명령어로 파드 내부 이미지 버전을 확인해보면 1.16으로 변경된 것을 볼 수 있다.

3️⃣ StatefulSet

  • 애플리케이션의 상태를 저장하고 관리하는 역할을 수행하는 리소스
  • 파드 고유의 이름을 가지고 순서대로 생성되며, 재시작 시에도 동일한 네트워크 ID를 유지
  • 파드의 순서와 고유성 보장을 위해 각 파드에 영구 볼륨(PV)이 할당
    • 파드 삭제 시, 새로 생성된 파드에 해당 볼륨이 재 할당됨
  • 스테이트풀셋 예시
    • statefulset-example.yaml

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: web
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 2
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
              - name: nginx
                image: nginx:latest
                ports:
                  - containerPort: 80
                volumeMounts:
                  - name: www
                    mountPath: /usr/share/nginx/html
        volumeClaimTemplates:
          - metadata:
              name: www
            spec:
              accessModes: [ "ReadWriteOnce" ]
              resources:
                requests:
                  storage: 1Gi
      
    • 설명

  1. apiVersion, kind, metadata: 기본적인 리소스 정의와 이름을 설정
  2. selector: StatefulSet에서 관리할 Pod를 선택하는 조건을 정의
    • app: nginx라는 레이블을 가진 Pod들을 선택
  3. serviceName: StatefulSet에 의해 생성되는 서비스의 이름을 정의.
    • nginx라는 이름의 서비스가 생성
  4. replicas: 생성할 Pod의 수를 정의
    • 여기서는 2개의 Pod를 생성
  5. template: 실제로 생성될 Pod의 템플릿을 정의.
    • Podnginx:latest 이미지를 사용하고, containerPort: 80을 열며, volumeMounts를 통해 www 볼륨을 /usr/share/nginx/html에 마운트
  6. volumeClaimTemplates: 각 Pod에 대한 동적 PVC(PersistentVolumeClaim)를 생성
    • Pod는 1Gi의 스토리지를 요청하고, ReadWriteOnce 액세스 모드를 설정

      $ vi pv-example.yaml # PersistenceVolume 정의(추후 설명)
      $ kubectl apply -f pv-example.yaml 
      $ kubectl get pv 
      $ vi statefulset-example.yaml 
      $ kubectl apply -f statefulset-example.yaml
    • pv-example.yaml

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-web-0
      spec:
        capacity:
          storage: 1Gi
        accessModes:
          - ReadWriteOnce
        hostPath:
          path: "/tmp/data-web-0"
      ---
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-web-1
      spec:
        capacity:
          storage: 1Gi
        accessModes:
          - ReadWriteOnce
        hostPath:
          path: "/tmp/data-web-1"
    • kubectl delete pod web-1 실행 후에 get pvc를 해보면 그대로 유지 중인 것을 확인 가능


데몬셋(DaemonSet)

  • 모든 노드, 혹은 특정 레이블을 가진 노드에 하나씩 동일한 파드를 배포 지원
  • 클러스터에서 노드가 추가되면 해당 노드에도 데몬셋에 정의된 파드가 배포됨
    • 리소스 모니터링 도구, 로그 수집기, CNI 등 과 같은 도구에 주로 사용

  • 데몬셋 예시
    • 데몬셋의 특성을 확인하기 위해선 2개 이상의 노드가 필요

    • daemonset-example.yaml

      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: daemonset-example
        namespace: default
      spec:
        selector:
          matchLabels:
            name: daemonset-example
        template:
          metadata:
            labels:
              name: daemonset-example
          spec:
            containers:
              - name: hello
                image: busybox
                command:
                  - "/bin/sh"
                  - "-c"
                  - "while true; do echo DaemonSet running on $(hostname); sleep 10; done"
      
profile
HARVEY

0개의 댓글