Cloud/k8s-CKAD

[CKAD] Statefulset 과 Headless Service

jinkwon.kim 2024. 10. 9. 13:11
728x90
반응형

개요

Statefulset이 무엇이고 어디에 사용하는지와 Headless Service가 StatefulSet과 어떻게 연결되어 사용되는지 알아보겠습니다. 

StatefulSet이란?

개념

Kubernetes(K8s)에서 StatefulSet은 상태를 가지는 Application(예: Database, 분산 파일 시스템 등)을 관리하기 위해 사용되는 WorkLoad API 객체입니다.

특징

고유한 네트워크 식별자 (Stable Network Identity):

각 Pod는 고유한 Host 이름을 가지며, 이를 통해 Client가 특정한 Pod에 접근할 수 있습니다.

Ex) : web-0, web-1, web-2 등.

안정적인 스토리지 (Stable Persistent Storage):

각 Pod에 대해 고유한 PersistentVolumeClaim(PVC)이 생성되어, Pod가 rescheduling 되거나 재시작되더라도 Data가 유지됩니다.

Ex): web-0은 web-0-pvc와 연결된 스토리지를 항상 사용.

순차적 배포 및 업데이트 (Ordered Deployment and Scaling):

Pod는 순차적으로 생성, 업데이트, 삭제됩니다. 예를 들어, web-0이 준비된 후에 web-1이 생성됩니다.

이를 통해 Application의 일관성과 안정성을 유지합니다.

고정된 배포 및 업데이트 순서 (Ordered Rolling Updates):

업데이트 시에도 순차적으로 업데이트되어, 시스템의 가용성을 높입니다.\

StatefulSet이 필요한 이유

상태를 가진 애플리케이션 지원:

Database, mesasge queue, 분산 파일 시스템 등 상태를 유지해야 하는 application은 단순한 Deployment로는 관리가 어렵습니다. StatefulSet은 이러한 요구사항을 충족시켜줍니다.

데이터 일관성 보장:

각 instance가 고유한 storage를 가지므로, data의 일관성을 유지할 수 있습니다.

안정적인 네트워크 ID:

cluster 내에서 특정 Pod에 안정적으로 접근할 수 있어, Client와의 통신이 원활해집니다.

StatefulSet 생성 yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-statefulset
spec:
  serviceName: "my-service"
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx

StatefulSet과 Volume

StatefulSet에서는 사용되는 PersistentVolumeClaim을 template으로 정의합니다. StatefulSet의 각 Pod는 template을 기반으로 고유한 PVC를 생성하여 각 Pod가 독립적인 Storage를 갖도록 합니다.

그리고 Volume은 Dynamic Volume을 사용하는게 좋습니다. 이유는 PVC가 자동으로 생성되면 연결되 SC에 의해서 PV가 자동으로 생성되기 때문에 Statefull에서 volume을 따로 신경쓸 필요가 없기 떄문입니다.

 

추가적으로 중요한 것으로 Pod가 재시작되도 PVC를 삭제 되지 않습니다. 

그래서 PVC 되는 경우는 수동으로 PVC를 삭제하거나, PersistentVolumeReclaimPolicy가 Delete로 설정된 경우에 한합니다. 기본적으로, PVC는 StatefulSet이 삭제되더라도 자동으로 삭제되지 않으며, 사용자가 직접 관리해야 합니다.

statefulSet-Volume yaml 

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-statefulset
spec:
  serviceName: "my-service"
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
        volumeMounts:
        - name: my-volume
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: my-volume
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

Headless Service

개념

cluster 내에서 특정 application의 각 개별 Pod에 직접 접근할 수 있도록 하는 service 유형입니다.

Headless yaml 

일반 service 생성 yaml에서 아래 설정만 추가 하면됩니다. 

clusterIP: None

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  clusterIP: None
  selector:
    app: nginx
  ports:
  - port: 80
    name: web

 

일반 Service와 Headless Service의 차이점

일반 service는 하나의 가상 IP(Virtual IP)를 통해 여러 Pod에 Traffic을 분산시키는 반면

Headless Service는 이러한 중간 계층 없이 각 Pod에 고유한 개별적인 DNS A Record를 제공합니다.

이는 StatefulSet과 같은 상태를 가지는 application에서 특히 유용합니다.

차이점 요약

특징 일반 Service Headless Service
Cluster IP 있음 없음 (clusterIP: None)
Load Balancing cluster 내부에서 자동으로 수행 Load Balancing  없음, 직접 접근 가능
DNS A Record 단일 Cluster IP에 매핑 각 팟에 대한 개별 DNS A 레코드 생성
사용 사례 Stateless 애플리케이션 (예: 웹 서버) Stateful 애플리케이션 (예: 데이터베이스)

kubectl get service 결과 

kubernetes : 기본 service

nginx : headless service

 

Kubernetes DNS 네임스페이스 구조

<서비스 이름>.<네임스페이스>.svc.<클러스터 도메인>

 

serivce의 이름이 nginx 라고 가정시 아래와 같은 DNS명 사용이 가능 합니다. 

완전한 도메인 이름(Fully Qualified Domain Name, FQDN)

nginx.default.svc.cluster.local

Namespace 내에서의 단축 domain name

서비스 이름만 사용: nginx

서비스 이름과 네임스페이스 조합: nginx.default

DNS 레코드 동작 방식

일반 Service인 nginx의 DNS 레코드는 다음과 같이 동작합니다:

단일 가상 IP(Cluster IP) 할당

nginx service는 cluster 내에서 단일 Cluster IP를 할당받습니다. 예를 들어, 10.96.0.1과 같은 IP가 할당될 수 있습니다.

DNS 이름 해석

client가 nginx.default.svc.cluster.local 또는 nginx(같은 namespace 내)으로 접근하면, Kubernetes DNS는 이 요청을 nginx service의 Cluster IP로 해석합니다.

로드 밸런싱

nginx service는 내부적으로 로드 밸런서를 통해 backend Pod로 traffic을 분산시킵니다. client는 단일 Cluster IP 또는 DNS 이름을 통해 서비스에 접근하지만, 실제 traffic은 여러 Pod으로 분산됩니다.

일반 Service vs Headless Service의 DNS 레코드 비교

아래는 일반 Service와 Headless Service의 DNS 레코드 구성을 비교한 표입니다:

특징 일반 Service Headless Service
Cluster IP 할당됨 (예: 10.96.0.1) 할당되지 않음 (clusterIP: None)
DNS 레코드 단일 A Record (Cluster IP) 각 팟에 대한 개별 A Record
DNS 이름 해석 nginx.default.svc.cluster.local → Cluster IP nginx-0.nginx.default.svc.cluster.local → Pod1 IP
nginx-1.nginx.default.svc.cluster.local → Pod2 IP
트래픽 분산 방식 내부 Load Balancer 통해 Pod으로 분산 Client가 직접 특정 Pod에 접근
사용 사례 Stateless 애플리케이션 (예: 웹 서버) Stateful 애플리케이션 (예: 데이터베이스)

정리

  • StatefulSet은 고유한 Pod 이름과 안정적인 네트워크 ID 그리고 고유한 PVC를 생성하여 영구적인 storage를 제공하여 상태를 유지하는 application을 효과적으로 관리합니다.
  • Headless Service는 StatefulSet과 함께 사용되어 각 Pod에 개별적인 DNS Record를 생성하고, client가 특정 Pod에 직접 접근할 수 있게 합니다.
    Format :  <statefulset-name>-<ordinal>.<service-name>.<namespace>.svc.cluster.local
    Ex : web-0.web.default.svc.cluster.local

 

 

 

 

728x90
반응형

'Cloud > k8s-CKAD' 카테고리의 다른 글

[CKAD] Admission Controller  (1) 2024.10.16
[CKAD] Network Policy  (0) 2024.10.03
[CKAD] service  (0) 2024.09.16
[CKAD] Jobs과 Cron Job  (2) 2024.09.14
[CKAD] Pod의 배포 및 업데이트  (0) 2024.09.02