인프런 워밍업 클럽 4기 DevOps - 2주차 (3)

sanghyun·2025년 6월 15일
0
post-thumbnail

모든 강의 이미지 출처는 [인프런] 쿠버네티스 어나더 클래스(지상편) - Spring 1,2 입니다.

Section 10. Application 기능으로 이해하기 - PV/PVC, Deployment, Service, HPA

PV/PVC

PV (Persistence Volume)

  • local 타입의 Volume은 특정 노드의 경로를 저장소로 사용하는 방법으로, 어느 Node에 Pod를 생성할 것 인지 지정하기 위한 nodeAffinity 설정이 필수적이다.
    • 만일 Pod가 재생성되어 다른 Node에 배치되면 기존 데이터를 접근할 수 없기 때문이다.
  • Pod 내부 path를 Node의 local path로 마운트 하게 되면, Pod가 죽어서 path에 있던 파일이 삭제되더라도 Node에는 남아있어 데이터를 유지할 수 있다.
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1 # 저장소로 사용할 Node의 로컬 경로 지정 
  nodeAffinity: # PV가 위치한 노드를 지정하는 Node Affinity (Pod에도 동일한 조건 지정 필요) 
    required:
      nodeSelectorTerms: 
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - example-node
  • local + nodeAffinity 조합 외에도 volume.hostPath + nodeSelector 조합으로도 적용할 수 있다.
    • 다만, hostPath, local 방식은 데이터를 쓰는 것보다 조회하는 용도에 더 적합하다. (ReadOnly)
    • 테스트 환경에서만 임시 저장 용도를 사용하고 실제 환경에서는 다른 저장소를 활용하는 것이 권장된다.

PVC (Persistence Volume Claim)

  • Pod와 PV를 연결하는 인터페이스 역할의 Object이다.
  • Pod는 PVC를 통해 원하는 리소스를 가진 PV를 할당받을 수 있으며, PV가 변경되더라도 Pod에서는 직접적인 변경을 가하지 않고 저장소를 사용할 수 있다.

[미션] local PV 동작 확인

▶ Pod와 Node에 각각 file 생성 및 확인

# 파일 생성 
[root@k8s-master ~] curl http://192.168.56.30:31231/create-file-pod
[root@k8s-master ~] curl http://192.168.56.30:31231/create-file-pv

▶ Pod 삭제 후 file 재확인

# Pod 삭제 후 파일 조회  
[root@k8s-master ~] curl http://192.168.56.30:31231/list-file-pod
[root@k8s-master ~] curl http://192.168.56.30:31231/list-file-pv

  • Pod 재생성 시, Pod에 생성되었던 파일은 삭제되었으나 Node에 생성되었던 파일은 남아있는 것을 확인할 수 있다.

▶ Deployment 설정에 PVC 대신 hostPath 사용하도록 변경 후 동작 확인

    spec:
      volumes:
        - name: files
          hostPath:
            path: /root/k8s-local-volume/1231

▶ 결과

  • hostPath 사용 시에도 local PV 방식과 동일하게 동작함을 확인할 수 있음.

Deployment

  • Deployment는 파드를 원하는 상태로 유지하며 배포를 업데이트 하는 쿠버네티스 Object다.
  • Deployment를 선언하면, ReplicaSet을 생성하고 template에 선언된 상태의 Pod를 replicas 수 만큼 생성한다.
  • 주요 필드는 다음과 같다.
    • replicas : ReplicaSet에서 생성할 Pod의 개수
    • template : ReplicaSet에서 생성할 Pod의 선언적 상태
    • strategy : 신규 Pod로 업데이트 시 사용할 배포 전략 (Recreate, RollingUpdate)
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
	strategy:
		type: RollingUpdate

Recreate 배포 방식

  • 기존 Pod를 모두 죽이고 새로운 Pod를 생성하는 배포 방식이다.
  • 기존 Pod를 관리하는 ReplicaSet의 replicas를 0으로 변경하여 기존 파드가 삭제되는 과정에서 다운 타임이 발생한다.
  • 배포 과정에서 자원 사용량이 증가하지 않는다.

RollingUpdate 배포 방식

  • 기존 Pod에서 새로운 Pod로 점직적으로 전환하는 배포 방식이다.
  • 기존 Pod를 관리하는 ReplicaSet의 replicas를 점차 감소시키고 신규 Pod를 관리하는 ReplicaSet의 replicas를 점차 증가시킨다.
  • 따라서, 배포 과정에서 다운 타임은 발생하지 않으나, 두 가지 버전의 Pod가 동시에 존재하게 된다.
  • 배포 과정에서 자원 사용량이 약 150% 증가한다. → maxUnavailable, maxSurge 설정값에 따라 달라질 수 있다.
    • maxUnavailable : 배포 과정 중 사용할 수 없는 최대 파드의 수 또는 비율 (기본값 : 25%)
    • maxSurge : 배포 과정 중 생성할 수 있는 최대 파드의 수 또는 비율 (기본값 : 25%)

[미션] RollingUpdate

maxUnavailable: 25%, maxSurge: 25%

▶ Deployment 설정

  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%

▶ 결과

[미션] RollingUpdate

maxUnavailable: 0%, maxSurge: 100%

▶ Deployment 설정

  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0%
      maxSurge: 100%
  strategy:
   	type: Recreate     

▶ 결과

[미션] Recreate

▶ Deployment 설정

  strategy:
   	type: Recreate     

▶ 결과

  • Recreate 방식 사용 시, 배포 과정에서 Running 상태인 Pod가 없어서 호출이 실패하는 것을 확인할 수 있다. (다운 타임!)

[미션] Rollback

▶ 이전 revision으로 롤백

[root@k8s-master ~] kubectl rollout undo -n anotherclass-123 deployment/api-tester-1231

▶ 결과 (이전 이미지 버전으로 롤백)


Service

Service의 역할

  • Service Publishing : 외부에서 Pod로 트래픽을 연결
  • Service Discovery : 내부 DNS를 이용해 Service 이름으로 API 호출
  • Service Registry : 서비스가 관리하는 Pod들의 IP를 관리하는 역할
  • Load Balancing : 서비스가 관리하는 Pod들 중 하나로 트래픽을 분배해주는 역할

Service의 주요 필드

  • selector : Service가 관리할 Pod들을 지정하기 위한 Label Selector
  • type : Service의 유형 (ClusterIP, NodePort, LoadBalancer)
  • ports
    • protocol : Pod와 통신하기 위한 프로토콜 종류 (TCP 외 다른 프로토콜도 지원)
    • targetPort : Pod와 통신하기 위한 Port 번호
    • port : Service에 접근하기 위한 Port 번호
    • nodePort : NodePort 타입인 Service에서 사용하는 필드로, 각 Node에서 오픈하는 Port 번호

ClusterIP

  • Service의 기본 타입으로, 클러스터 외부에서는 서비스에 접근할 수 없고 클러스터 내부에서만 접근이 가능하다.
  • 서비스에 여러 개의 파드를 연결했다면, 요청을 해당 파드들 중 하나로 분산시킨다.

NodePort

  • 모든 노드에 동일한 Port를 오픈하여, 외부로 부터 해당 Port로 요청이 들어오면 Service가 Pod에 요청을 분산시킨다.
  • 따라서 노드 IP와 Port를 통해 서비스에 접근할 수 있다.

LoadBalancer

  • 외부에서 접근하기 위한 용도의 타입으로, 외부에 노출할 IP가 지정되어야 한다.
  • 이 때, 외부 IP 지원 플러그인이 필요하다.

[미션] Pod 내부에서 Service 명으로 API 호출

▶ Pod 내부에서 Servie 명으로 API 호출

[root@k8s-master ~] kubectl exec -it api-tester-1231-6f4c85fb95-4c4nd -n anotherclass-123 -- curl http://api-tester-1231:80/version  

▶ 결과

▶ Deployment, Service 설정 변경 후 Pod 내부에서 Servie 명으로 API 호출

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
spec:
  template:
    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master
      containers:
        - name: api-tester-1231
          ports:                // 삭제
          - name: http          // 삭제
            containerPort: 8080 // 삭제
---
apiVersion: v1
kind: Service
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
spec:
  ports:
    - port: 80
      targetPort: http -> 8080 // 변경
      nodePort: 31231
  type: NodePort

▶ 결과


HPA (Horizontal Pod Autoscaling)

  • HPA는 부하 증감에 따라 Pod를 개수를 조정하여 자동으로 스케일링하기 위한 Object이다.
  • 변경될 Pod 수를 계산하는 공식은 다음과 같다.
변경될 Pod 수 = 현재 Pod 수 * (평균 CPU/HPA CPU)
  • 예시로, 현재 2개의 Pod가 있고 그 중 한 Pod의 CPU가 150, 나머지 한 Pod가 1일 때 평균 CPU는 75.5 (=(150+1)/2) 로 HPA에 기재된 CPU인 60보다 커지게 된다.
  • HPA에 의해 해당 공식으로 계산된 Pod 수로 스케일링된다.
변경될 Pod 수 = 2 * ((150+1)/2/60) = 3 (2.51 **올림 처리**)
  • 메모리는 부하에 따른 증감 대상이 아니기 때문에, HPA에서 제공하는 옵션이나 실제로 사용되지는 않는다.
profile
안하는 건 있어도, 못하는 건 없다

0개의 댓글