IT STUDY LOG
[컨테이너 오케스트레이션] 03. 쿠버네티스 구성 요소 본문
# 학습 목표
- 컨테이너 오케스트레이션이 무엇인지 이해할 수 있다.
- 쿠버네티스의 간단한 작동 원리를 이해할 수 있다.
- 쿠버네티스 리소스 명세를 작성할 수 있다.
- 파드 명세를 작성할 수 있다.
- 디플로이먼트 명세를 작성할 수 있다.
- 서비스를 이용해 파드를 노출할 수 있다.
- 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 인스턴스 유형은 직접 연결된 블록 디바이스 스토리지 형태의 스토리지
- 인스턴스 스토어를 임시 스토리지로 인스턴스 스토어 볼륨에 저장된 데이터는 인스턴스 중지, 종료 또는 하드웨어 장애 시 유지되지 않음
- 데이터를 장기적으로 유지하거나 암호화하려는 경우 사용
- 특징
> 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로 제한된 설정만을 조정 가능
- 볼륨과 파드 간의 의존도를 줄이기 위해, 퍼시스턴스 볼륨 클레임(Persistence Volume Claim, 이하 PVC)을 이용하여 PV와 연결
- PVC는 파드가 볼륨의 세부 사항을 몰라도 볼륨을 사용할 수 있게 도와줌
- PV는 실제로 데이터가 저장되는 공간
- PVC는 PV를 선택, 연결해 주는 요청 그 자체
PVC와 파드
- 퍼시스턴트볼륨클레임 (PVC)은 사용자의 스토리지에 대한 요청으로 파드와 비슷
- 파드는 노드 리소스를 사용하고 / PVC는 PV 리소스를 사용
- 파드는 특정 수준의 리소스(CPU 및 메모리)를 요청할 수 있으며 / 클레임은 특정 크기 및 접근 모드를 요청할 수 있음(예: ReadWriteOnce, ReadOnlyMany 또는 ReadWriteMany로 마운트 할 수 있음. AccessModes 참고).
- 퍼시스턴트볼륨 클레임을 사용하면 사용자가 추상화된 스토리지 리소스를 사용할 수 있으나, 다른 문제들 때문에 성능과 같은 다양한 속성을 가진 퍼시스턴트 볼륨이 필요한 경우가 일반적
- 클러스터 관리자는 사용자에게 해당 볼륨의 구현 방법에 대한 세부 정보를 제공하지 않고 크기와 접근 모드와는 다른 방식으로 다양한 퍼시스턴트볼륨을 제공할 수 있어야 함
PVC의 작동 원리
- 애플리케이션이 스토리지 리소스에 대한 요청을 정의하는 추상화된 개체로, 스토리지를 요청하는 애플리케이션과 실제 스토리지를 연결하는 역할 수행
- PVC 생성: 개발자 또는 사용자는 PVC를 생성하고 필요한 스토리지 요구사항을 지정. PVC는 쿠버네티스 API를 통해 클러스터에 생성됨.
- 매칭과 바인딩: 클러스터의 스토리지 프로비저닝 기능이 활성화되어 있는 경우, PVC는 스토리지 프로비저닝 컨트롤러에 의해 처리됨. 컨트롤러는 PVC의 요구에 맞는 PV(Persistent Volume, 클러스터 내의 실제 스토리지 볼륨)를 찾거나 동적으로 생성.
- PV 할당: PV가 매칭되면 PVC와 PV가 바인딩. 이후 PVC는 PV를 참조하게 되고, PV는 해당 PVC와 연결된 애플리케이션에 대한 스토리지를 제공 가능.
- 마운트: 애플리케이션 파드가 PVC를 사용하도록 지정하면, 파드는 PVC를 마운트하여 스토리지에 접근 가능. 이를 통해 애플리케이션은 스토리지를 사용하여 데이터 읽기/쓰기 가능.
- 스토리지 사용: 애플리케이션은 PVC를 통해 스토리지에 대한 작업을 수행하며, 읽기, 쓰기, 삭제 등의 스토리지 작업은 파드 내부에서 PVC를 통해 진행됨.
- PVC를 사용함으로써 애플리케이션은 스토리지에 대한 추상화된 인터페이스를 가지며, 스토리지의 프로비저닝 및 관리는 클러스터 관리자 또는 스토리지 프로비저닝 컨트롤러가 담당
- 이를 통해 애플리케이션과 스토리지의 결합이 유연하게 이루어지고, 스토리지의 재사용 및 동적 프로비저닝이 가능
Stateful한 애플리케이션이 수평 확장한다면
- 파드를 정의할 때 PVC를 통해 볼륨에 연결 가능하나 그냥 이러한 파드를 디플로이먼트로 배포해도, PVC를 통해 연결되는 볼륨은 하나이므로 결국 같은 스토리지를 사용하는 형태
- 파드마다 별도의 데이터를 저장할 수 있게 만들려면, 수평확장되는 파드에 서로 다른 PV가 연결되어야 함
- 스토리지클래스는 관리자가 제공하는 스토리지의 "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/
https://github.com/kubernetes/examples/blob/master/staging/persistent-volume-provisioning/README.md
https://kubernetes.io/ko/docs/concepts/storage/volumes/
https://kubernetes.io/ko/docs/concepts/storage/persistent-volumes/
https://repost.aws/ko/knowledge-center/instance-store-vs-ebs
https://github.com/kubernetes/design-proposals-archive/blob/main/storage/persistent-storage.md
https://kubernetes.io/ko/docs/concepts/workloads/controllers/statefulset/
https://kubernetes.io/ko/docs/tutorials/stateful-application/basic-stateful-set/
'devops bootcamp 4 > DevOps 인프라 관리' 카테고리의 다른 글
[서비스 모니터링] 01. 모니터링의 목표와 측정 항목 (0) | 2023.06.02 |
---|---|
[컨테이너 오케스트레이션] 04. 쿠버네티스 네트워크 (0) | 2023.05.22 |
[컨테이너 오케스트레이션] 02. 쿠버네티스 워크로드 (0) | 2023.05.18 |
[컨테이너 오케스트레이션] 01. 쿠버네티스 주요 개념 (0) | 2023.05.17 |
[Infrastructure as Code] 02. Terraform (0) | 2023.05.12 |