IT STUDY LOG

[컨테이너 오케스트레이션] 03. 쿠버네티스 구성 요소 본문

devops bootcamp 4/DevOps 인프라 관리

[컨테이너 오케스트레이션] 03. 쿠버네티스 구성 요소

roheerumi 2023. 5. 22. 17:32

# 학습 목표

  • 컨테이너 오케스트레이션이 무엇인지 이해할 수 있다.
  • 쿠버네티스의 간단한 작동 원리를 이해할 수 있다.
  • 쿠버네티스 리소스 명세를 작성할 수 있다.
    • 파드 명세를 작성할 수 있다.
    • 디플로이먼트 명세를 작성할 수 있다.
    • 서비스를 이용해 파드를 노출할 수 있다.
  • kubectl 명령어를 사용하여 리소스의 생성, 삭제, 조회를 할 수 있다.
  • kubectl 명령어를 사용하여 롤아웃 관련 작업을 진행할 수 있다.
    • 롤링 배포 현황을 확인할 수 있다.
    • 새로운 버전에 문제가 발생했을 때 롤백할 수 있다.

(이하 advanced)

  • liveness probe를 이용하여 파드의 health check를 할 수 있다.
  • 쿠버네티스가 Stateful한 애플리케이션을 다루는 방법을 이해할 수 있다.
  • 쿠버네티스에서 인그레스를 이용한 HTTP 기반 라우팅을 적용할 수 있다.
  • helm 패키지 매니저를 사용할 수 있다.

# 학습 내용

1.  볼륨과 스테이트풀셋

Stateless한 파드

- 파드 : 일시적이며, 언제나 삭제될 수 있으므로 파드 그 자체는 Stateless

- 디플로이먼트 : 파드의 교체와 배치를 담당. 디플로이먼트는 레플리카셋을 통해 파드를 scale out하며, 이때 만들어지는 파드들은 상호 대체 가능

 

파드가 사라져도, 데이터를 남기고 싶다면

- 데이터베이스 (MySQL, mongoDB, redis 등)과 같이 파드 그 자체에 상태(데이터)를 남겨야만 하는 Stateful 애플리케이션 또한 존재 가능

- 데이터베이스 애플리케이션이 담긴 파드가 사라질 때, 데이터가 함께 사라져서는 안 되므로, 쿠버네티스에도 영속적인(Persistence) 데이터(프로그램의 실행이 종료되어도 사라지지 않는 데이터)를 저장하기 위해 볼륨(Volume)을 연결 가능(여타 클라우드 서비스에서 볼륨을 따로 분리해 놓는 것과 마찬가지)

- 파드에 볼륨을 연결하면, 데이터를 영속적으로 저장하는 것이 가능

 

볼륨과 퍼시스턴스 볼륨(Persistence Volume)의 차이는?

(1) 볼륨

- 데이터를 포함하고 있는 "디렉터리"이며, 파드의 컨테이너에서 접근 가능

- 볼륨에는 여러 유형이 존재함

 > 임시 볼륨 : 파드의 수명동안 존재하며 파드가 존재하지 않으면 쿠버네티스가 삭제

 > 퍼시스턴트 볼륨 : 파드가 존재하지 않아도 삭제하지 않음

- 볼륨의 종류와 삭완없이 파드 내 컨테이너가 재시작되어도 데이터는 보존

- 디렉터리의 생성 방식, 이를 지원하는 매체와 내용은 사용된 특정 볼륨의 유형에 따라 결정됨

- 볼륨을 사용하려면, .spec.volumes 에서 파드에 제공할 볼륨을 지정하고 .spec.containers[*].volumeMounts 의 컨테이너에 해당 볼륨을 마운트할 위치를 선언

- 볼륨은 이미지의 특정 경로에 마운트됨

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      env:
      - name: MYSQL_ROOT_PASSWORD
        value: "rootpasswd"
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql # 특정 경로(subPath 지정)
    - name: php
      image: php:7.0-apache
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html # 특정 경로(subPath 지정)
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data

- 파드에 정의된 각 컨테이너에 대해 컨테이너가 사용할 각 볼륨을 어디에 마운트할지 명시

- 볼륨은 원칙적으로 다른 볼륨 안에 마운트될 수 없음 (단, 서브패스 사용에서 관련 메커니즘을 참고)

- 볼륨은 다른 볼륨에 있는 내용물을 가리키는 하드 링크를 포함 불가

(2) 퍼시스턴스 볼륨(PV)

-1) 관리자가 프로비저닝하거나 2) 스토리지 클래스를 사용하여 동적으로 프로비저닝한 클러스터의 스토리지

-  노드가 클러스터 리소스인 것처럼 PV는 클러스터 리소스

- PV는 Volumes와 같은 볼륨 플러그인이지만, PV를 사용하는 개별 파드와는 별개의 라이프사이클을 가짐

- 이 API 오브젝트는 NFS, iSCSI 또는 클라우드 공급자별 스토리지 시스템 등 스토리지 구현에 대한 세부 정보를 담음

더보기

Amazon EC2 인스턴스 스토어

 

Amazon EC2 인스턴스 스토어 - Amazon Elastic Compute Cloud

Amazon EC2 인스턴스 스토어 인스턴스 스토어는 인스턴스에 블록 수준의 임시 스토리지를 제공합니다. 스토리지는 호스트 컴퓨터에 물리적으로 연결된 디스크에 위치합니다. 인스턴스 스토어는

docs.aws.amazon.com

- Amazon EC2 인스턴스 유형은 직접 연결된 블록 디바이스 스토리지 형태의 스토리지

- 인스턴스 스토어를 임시 스토리지로 인스턴스 스토어 볼륨에 저장된 데이터는 인스턴스 중지, 종료 또는 하드웨어 장애 시 유지되지 않음

 

Amazon EBS 볼륨

 

Amazon Elastic Block Store(Amazon EBS) - Amazon Elastic Compute Cloud

Amazon Elastic Block Store(Amazon EBS) Amazon Elastic Block Store(Amazon EBS)는 EC2 인스턴스에 사용할 수 있는 블록 수준 스토리지 볼륨을 제공합니다. EBS 볼륨은 형식이 지정되지 않은 원시 블록 디바이스처럼 동

docs.aws.amazon.com

- 데이터를 장기적으로 유지하거나 암호화하려는 경우 사용

- 특징

 > EBS 볼륨은 인스턴스 중지 및 종료 시에도 데이터를 보존

 > EBS 스냅샷으로 EBS 볼륨을 백업 가능 : 의도하지 않은 변경이나 데이터 손실을 방지하려면 AWS Backup을 사용하여 스냅샷 생성을 자동화하는 것을 권장

 > 한 인스턴스에서 EBS 볼륨을 제거하고 다른 인스턴스에 다시 연결 가능

 > EBS 볼륨은 전체 볼륨 암호화를 지원

참고: Amazon EBS에서는 인스턴스의 루트 볼륨에 대한 DeleteOnTermination 속성이 기본적으로 true로 설정 되며, 이 속성을 변경하지 않으면 인스턴스가 종료될 때 인스턴스의 루트 볼륨이 삭제됨. DeleteOnTermination 속성을 false로 변경하려면 Amazon EC2 인스턴스를 종료할 때 Amazon EBS 볼륨이 삭제되지 않도록 하려면 어떻게 해야 하나요?를 참조

 

Stateful한 애플리케이션을 관리하려면

- but, 파드 명세에 PV를 정의해서 직접 연결하는 것은 좋은 방법이 아님

 

왜 파드와 PV를 직접 연결하지 않기를 권장할까?

관리 수준

- PV를 직접 정의하여 연결하는 경우, PV와 관련된 모든 설정과 관리 책임은 클러스터 관리자(쿠버네티스 클러스터를 설치, 구성 및 관리하는 역할)에게 있음

- PVC를 사용하는 경우, 개발자(쿠버네티스를 사용하여 애플리케이션을 개발, 배포 및 관리하는 역할을 담당) 또는 사용자가 PVC를 생성하고 관리하며, 클러스터 관리자는 PVC의 요청에 따라 적절한 PV를 할당 및 연결

재사용성

- PV를 직접 정의하여 파드에 연결하는 경우, PV는 단일 파드에만 연결될 수 있으며 파드가 삭제되면 PV도 함께 삭제됨

- PVC를 사용하는 경우, PVC는 여러 파드에서 공유할 수 있으며, 파드가 삭제되더라도 PVC는 유지되어 PV와 PVC를 분리하고 PV를 재사용할 수 있는 유연성을 제공

동적 프로비저닝

- PV를 직접 정의하는 경우, 미리 정의된 PV를 사용해야 하므로 PV가 충분하지 않은 경우 추가적인 PV를 생성하고 연결해야 함

- PVC를 사용하는 경우, 클러스터는 PVC 요청에 따라 필요한 PV를 동적으로 프로비저닝하여 할당하고 연결하므로 사용자가 직접 PV를 생성 및 관리하지 않아도 되는 편의성을 제공

유연성

- PV를 직접 정의하여 연결하는 방식은 클러스터 관리자에게 더 많은 제어권과 유연성을 제공

- PVC를 사용하는 경우, 개발자 또는 사용자는 PVC로 제한된 설정만을 조정 가능

 

PVC(Persistent Volume Claim)

- 볼륨과 파드 간의 의존도를 줄이기 위해, 퍼시스턴스 볼륨 클레임(Persistence Volume Claim, 이하 PVC)을 이용하여 PV와 연결

- PVC는 파드가 볼륨의 세부 사항을 몰라도 볼륨을 사용할 수 있게 도와줌

  • PV는 실제로 데이터가 저장되는 공간
  • PVC는 PV를 선택, 연결해 주는 요청 그 자체

 

PVC와 파드

- 퍼시스턴트볼륨클레임 (PVC)은 사용자의 스토리지에 대한 요청으로 파드와 비슷

- 파드는 노드 리소스를 사용하고 / PVC는 PV 리소스를 사용

- 파드는 특정 수준의 리소스(CPU 및 메모리)를 요청할 수 있으며 / 클레임은 특정 크기 및 접근 모드를 요청할 수 있음(예: ReadWriteOnce, ReadOnlyMany 또는 ReadWriteMany로 마운트 할 수 있음. AccessModes 참고).

- 퍼시스턴트볼륨 클레임을 사용하면 사용자가 추상화된 스토리지 리소스를 사용할 수 있으나, 다른 문제들 때문에 성능과 같은 다양한 속성을 가진 퍼시스턴트 볼륨이 필요한 경우가 일반적

- 클러스터 관리자는 사용자에게 해당 볼륨의 구현 방법에 대한 세부 정보를 제공하지 않고 크기와 접근 모드와는 다른 방식으로 다양한 퍼시스턴트볼륨을 제공할 수 있어야 함

 

PVC의 작동 원리

- 애플리케이션이 스토리지 리소스에 대한 요청을 정의하는 추상화된 개체로, 스토리지를 요청하는 애플리케이션과 실제 스토리지를 연결하는 역할 수행

  1. PVC 생성: 개발자 또는 사용자는 PVC를 생성하고 필요한 스토리지 요구사항을 지정. PVC는 쿠버네티스 API를 통해 클러스터에 생성됨.
  2. 매칭과 바인딩: 클러스터의 스토리지 프로비저닝 기능이 활성화되어 있는 경우, PVC는 스토리지 프로비저닝 컨트롤러에 의해 처리됨. 컨트롤러는 PVC의 요구에 맞는 PV(Persistent Volume, 클러스터 내의 실제 스토리지 볼륨)를 찾거나 동적으로 생성.
  3. PV 할당: PV가 매칭되면 PVC와 PV가 바인딩. 이후 PVC는 PV를 참조하게 되고, PV는 해당 PVC와 연결된 애플리케이션에 대한 스토리지를 제공 가능.
  4. 마운트: 애플리케이션 파드가 PVC를 사용하도록 지정하면, 파드는 PVC를 마운트하여 스토리지에 접근 가능. 이를 통해 애플리케이션은 스토리지를 사용하여 데이터 읽기/쓰기 가능.
  5. 스토리지 사용: 애플리케이션은 PVC를 통해 스토리지에 대한 작업을 수행하며, 읽기, 쓰기, 삭제 등의 스토리지 작업은 파드 내부에서 PVC를 통해 진행됨.

- PVC를 사용함으로써 애플리케이션은 스토리지에 대한 추상화된 인터페이스를 가지며, 스토리지의 프로비저닝 및 관리는 클러스터 관리자 또는 스토리지 프로비저닝 컨트롤러가 담당

- 이를 통해 애플리케이션과 스토리지의 결합이 유연하게 이루어지고, 스토리지의 재사용 및 동적 프로비저닝이 가능

 

Stateful한 애플리케이션이 수평 확장한다면

- 파드를 정의할 때 PVC를 통해 볼륨에 연결 가능하나 그냥 이러한 파드를 디플로이먼트로 배포해도, PVC를 통해 연결되는 볼륨은 하나이므로 결국 같은 스토리지를 사용하는 형태

- 파드마다 별도의 데이터를 저장할 수 있게 만들려면, 수평확장되는 파드에 서로 다른 PV가 연결되어야 함

 

스토리지 클래스(StorageClass) 리소스

- 스토리지클래스는 관리자가 제공하는 스토리지의 "classes"를 설명할 수 있는 방법을 제공

- 파드가 PV를 동적으로 요청해서 그때그때 볼륨이 생성되도록, 사용자가 요청할 때 자동으로 PV를 프로비저닝할 수 있도록 지원

# 스토리지클래스 예시
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs # 필수. PV 프로비저닝에 사용되는 볼륨 플러그인을 결정하는 프로비저너
parameters:
  type: gp2 # 스토리지 클래스에는 스토리지 클래스에 속하는 볼륨을 설명하는 파라미터로 provisioner 에 따라 사용 가능
reclaimPolicy: Retain # 스토리지클래스에 의해 동적으로 생성된 퍼시스턴트볼륨은 클래스 정책(Delete-기본값, Retain)
allowVolumeExpansion: true
mountOptions:
  - debug
volumeBindingMode: Immediate


- 각 스토리지클래스에는 해당 스토리지클래스에 속하는 퍼시스턴트볼륨을 동적으로 프로비저닝 할 때 사용되는 provisioner, parameters 와 reclaimPolicy 필드가 포함

- 스토리지클래스 오브젝트의 이름은 중요하고 사용자가 특정 클래스를 요청할 수 있는 방법

- 관리자는 스토리지클래스 오브젝트를 처음 생성할 때 클래스의 이름과 기타 파라미터를 설정하며, 일단 생성된 오브젝트는 업데이트 불가

- 관리자는 특정 클래스에 바인딩을 요청하지 않는 PVC에 대해서만 기본 스토리지클래스를 지정할 수 있음

 

스테이트풀셋

- 스테이트풀셋은 애플리케이션의 스테이트풀을 관리하는데 사용하는 워크로드 API 오브젝트

- 파드 집합의 디플로이먼트와 스케일링을 관리하며, 파드들의 순서 및 고유성을 보장

- 스토리지 볼륨을 사용해서 워크로드에 지속성을 제공하려는 경우, 솔루션의 일부로 스테이트풀셋을 사용 가능

- 스테이트풀셋의 개별 파드는 장애에 취약하나, 퍼시스턴트 파드 식별자를 이용해 기존 볼륨을 실패한 볼륨을 대체하는 새 파드에 더 쉽게 적용 가능

- 스테이트풀셋은 애플리케이션 구성(파드)을 복제하더라도, 스토리지 클래스를 이용해 파드가 필요로 하는 볼륨을 자동으로 프로비저닝하여 연결

- 즉 첫 번째 파드를 primary(master), 두 번째 파드를 secondary 복제본처럼 구성하는 것 또한 가능

 

디플로이먼트와 스테이트풀셋의 공통점과 차이점

- 공통점 : 둘 다 동일한 컨테이너 스펙을 기반으로 둔 파드들을 관리

- 차이점 : 스테이트풀셋은 파드의 순서고유성을 보장. 스테이트풀셋이 생성한 파드는 상호 대체할 수 없는 파드

 

스테이트풀셋을 사용할 때의 주의사항

- 파드에 지정된 스토리지는 관리자에 의해 퍼시스턴트 볼륨 프로비저너를 기반으로 하는 storage class를 요청해서 프로비전하거나 사전에 프로비전이 되어야 함

- 스테이트풀셋은 현재 파드의 네트워크 신원을 책임지고 있는 헤드리스 서비스 가 필요하며 사용자가 이 서비스를 생성할 책임

 

헤드리스 서비스

- 현재 파드의 네트워크 신원을 책임

- 로드밸런싱과 단일 서비스 IP가 필요하지 않을 경우, "헤드리스" 서비스라는 것을 만들 수 있음

- 명시적으로 클러스터 IP (.spec.clusterIP)에 "None"을 지정

# 헤드리스 서비스 지정 : 네트워크 도메인 컨트롤
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

# 스테이트풀셋 지정 : 이름이 web인 스테이트풀셋은 3개의 nginx 컨테이너의 레플리카가 고유의 파드에서 구동될 것이라 지시하는 Spec 가짐
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # .spec.template.metadata.labels 와 일치해야 한다
  serviceName: "nginx"
  replicas: 3 # 기본값은 1
  minReadySeconds: 10 # 기본값은 0
  template:
    metadata:
      labels:
        app: nginx # .spec.selector.matchLabels 와 일치해야 한다
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: registry.k8s.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

- 쿠버네티스의 구현에 묶이지 않고, 헤드리스 서비스를 사용하여 다른 서비스 디스커버리 메커니즘과 인터페이스 가능

- 헤드리스 서비스의 경우, 클러스터 IP가 할당되지 않고, kube-proxy가 이러한 서비스를 처리하지 않으며, 플랫폼에 의해 로드 밸런싱 or 프록시 하지 않음

 


# References

챗 GPT

https://kubernetes.io/ko/docs/concepts/storage/dynamic-provisioning/

 

동적 볼륨 프로비저닝

동적 볼륨 프로비저닝을 통해 온-디맨드 방식으로 스토리지 볼륨을 생성할 수 있다. 동적 프로비저닝이 없으면 클러스터 관리자는 클라우드 또는 스토리지 공급자에게 수동으로 요청해서 새 스

kubernetes.io

https://github.com/kubernetes/examples/blob/master/staging/persistent-volume-provisioning/README.md

 

GitHub - kubernetes/examples: Kubernetes application example tutorials

Kubernetes application example tutorials. Contribute to kubernetes/examples development by creating an account on GitHub.

github.com

https://kubernetes.io/ko/docs/concepts/storage/volumes/

 

볼륨

컨테이너 내의 디스크에 있는 파일은 임시적이며, 컨테이너에서 실행될 때 애플리케이션에 적지 않은 몇 가지 문제가 발생한다. 한 가지 문제는 컨테이너가 크래시될 때 파일이 손실된다는 것

kubernetes.io

https://kubernetes.io/ko/docs/concepts/storage/persistent-volumes/

 

퍼시스턴트 볼륨

이 페이지에서는 쿠버네티스의 퍼시스턴트 볼륨 에 대해 설명한다. 볼륨에 대해 익숙해지는 것을 추천한다. 소개 스토리지 관리는 컴퓨트 인스턴스 관리와는 별개의 문제다. 퍼시스턴트볼륨 서

kubernetes.io

https://repost.aws/ko/knowledge-center/instance-store-vs-ebs

 

인스턴스 스토어와 EBS의 차이점은 무엇인가요?

Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스와 연결된 데이터를 저장하고 싶습니다. 인스턴스 스토어를 사용해야 하는지 아니면 연결된 Amazon Elastic Block Store(Amazon EBS) 볼륨을 사용해야 하는지 잘 모

repost.aws

https://github.com/kubernetes/design-proposals-archive/blob/main/storage/persistent-storage.md

 

GitHub - kubernetes/design-proposals-archive: Archive of Kubernetes Design Proposals

Archive of Kubernetes Design Proposals. Contribute to kubernetes/design-proposals-archive development by creating an account on GitHub.

github.com

https://kubernetes.io/ko/docs/concepts/workloads/controllers/statefulset/

 

스테이트풀셋

스테이트풀셋은 애플리케이션의 스테이트풀을 관리하는데 사용하는 워크로드 API 오브젝트이다. 파드 집합의 디플로이먼트와 스케일링을 관리하며, 파드들의 순서 및 고유성을 보장한다 . 디플

kubernetes.io

https://kubernetes.io/ko/docs/tutorials/stateful-application/basic-stateful-set/

 

스테이트풀셋 기본

이 튜토리얼은 스테이트풀셋(StatefulSet)을 이용하여 애플리케이션을 관리하는 방법을 소개한다. 어떻게 스테이트풀셋의 파드를 생성하고, 삭제하며, 스케일링하고, 업데이트하는지 시연한다. 시

kubernetes.io

https://kubernetes.io/ko/docs/concepts/services-networking/service/#%ED%97%A4%EB%93%9C%EB%A6%AC%EC%8A%A4-headless-%EC%84%9C%EB%B9%84%EC%8A%A4

 

서비스

파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법 쿠버네티스를 사용하면 익숙하지 않은 서비스 디스커버리 메커니즘을 사용하기 위해 애플리케이션을 수정할

kubernetes.io

 

Comments