Docker Compose에서 Kubernetes 클러스터 배포로의 이전: 핵심 개념 및 설정

도커 컴포즈에서 쿠버네티스 클러스터 배포로 전환할 때, 애플리케이션 관리는 근본적으로 달라집니다. 클러스터는 높은 가용성, 탄력성, 그리고 자동 확장을 제공하지만 새로운 추상화 개념을 도입합니다.

주요 개념 분석

클러스터 환경에서는 더 이상 직접 "컨테이너"를 관리하는 것이 아니라 "워크로드"(Workload)와 "서비스"(Service)를 다룹니다. 아래는 몇 가지 중요한 개념들입니다:

1. 상태 없는 워크로드 (Stateless Workload)

  • 쿠버네티스 객체: Deployment
  • 핵심 아이디어: 이 워크로드의 모든 인스턴스(파드)는 동일하고 서로 교체 가능합니다. 어떤 데이터도 영구적으로 저장되지 않습니다. 특정 인스턴스가 고장 나면 클러스터는 새로운 인스턴스를 즉시 생성하여 상태를 유지합니다.
  • 예시: 웹 서버(Nginx, Apache), API 백엔드, 마이크로서비스 게이트웨이.
  • 비유: 패스트푸드점의 계산원처럼 누구나 같은 서비스를 제공할 수 있습니다.

2. 상태 있는 워크로드 (StatefulSet)

  • 쿠버네티스 객체: StatefulSet
  • 핵심 아이디어: 각각의 파드는 안정적이고 유일한 식별자를 가지고 있으며 독립적인 지속 저장소에 연결됩니다.
  • 주요 특징:
  • 안정된 네트워크 ID: 파드가 재부팅되더라도 호스트명과 DNS 기록은 변하지 않습니다.
  • 안정된 지속 저장소: 각 파드는 자신만의 저장소(PVC)를 가지고 있어 재배치되어도 동일한 저장소에 다시 연결됩니다.
  • 예시: 데이터베이스(MySQL, PostgreSQL, Neo4j), 메시지 큐(Kafka, RabbitMQ), 분산 파일 시스템.
  • 비유: 은행의 금고처럼 각각 고유한 번호와 데이터를 가지고 있어 대체될 수 없습니다.

3. 저장소 (PersistentVolume - PV)

  • 핵심 아이디어: 이는 클러스터 내의 실제 저장소 자원입니다.
  • 출처: 구름 서비스의 디스크, NFS 또는 NAS 등이 될 수 있습니다.
  • 비유: 이미 나누어지고 라벨이 붙은 창고의 선반이라고 생각할 수 있습니다.

4. 저장 요청 (PersistentVolumeClaim - PVC)

  • 핵심 아이디어: 애플리케이션이 저장소를 요청하는 것입니다.
  • 작동 방식:
  • 정적 할당: 미리 PV를 만들고 이를 정확히 참조하는 PVC를 생성합니다.
  • 동적 할당: 단순히 PVC를 만들면 쿠버네티스가 자동으로 PV를 생성하고 연결합니다.
  • 비유: 창고의 물건을 가져오기 위한 수령서입니다.

5. 서비스 (Service)

  • 핵심 아이디어: 클러스터 내에서 파드의 IP 주소는 변경될 수 있지만, 서비스는 항상 일정한 엔트리 포인트를 제공합니다.
  • 기능:
  • 서비스 발견: 다른 애플리케이션들은 특정 서비스 이름을 통해 접근할 수 있습니다.
  • 로드 밸런싱: 여러 인스턴스가 있을 경우 자동으로 요청을 분산 처리합니다.
  • 포트 매핑: 특정 포트를 리스닝하고 이를 컨테이너의 포트와 연결합니다.

6. 라우팅 (Ingress)

  • 핵심 아이디어: 클러스터 외부로부터 HTTP/HTTPS 트래픽을 라우팅합니다.
  • 기능:
  • 도메인 기반 라우팅: 특정 도메인을 특정 서비스로 연결합니다.
  • SSL/TLS 종료: HTTPS 암호화를 중앙에서 처리합니다.
  • 비유: 사무실의 프론트 데스크처럼 외부 요청을 적절하게 분배합니다.

7. 비밀 정보 (Secret)

  • 쿠버네티스 객체: Secret
  • 핵심 아이디어: 민감한 데이터(비밀번호, API 키 등)를 안전하게 저장합니다.
  • 작동 방식: 비밀 정보를 먼저 저장하고, 해당 정보를 파드의 환경 변수나 파일로 연결합니다.
  • 비유: 잠금 장치가 있는 보험함처럼 중요한 정보를 안전하게 보관합니다.

Docker Compose vs Kubernetes 이전 비교

아래는 제공된 docker-compose.yml 파일을 쿠버네티스 YAML 구성 파일로 변환한 예입니다.

Docker Compose 파일

version: '3.8'

services:
  neo4j:
    image: neo4j:5.20.0
    container_name: neo4j_db
    ports:
      - "7474:7474"
      - "7687:7687"
    environment:
      - NEO4J_AUTH=neo4j/indemind@@ 
    volumes:
      - /home/indemind/zy_/neo4j/docker_data:/data
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7474"]
      interval: 10s
      timeout: 10s
      retries: 5

Kubernetes로의 이전

총괄:

  1. PV (PersistenVolume): NAS 저장소를 정의합니다.
  2. PVC (PersistenVolumeClaim): 위 PV를 사용하도록 요청합니다.
  3. Secret: Neo4j 비밀번호를 안전하게 저장합니다.
  4. StatefulSet: Neo4j를 관리합니다.
  5. Service: Neo4j의 포트를 노출합니다.
1. PV (PersistenVolume)

새로운 NAS 디렉토리를 만들어야 합니다. 아래는 k8s-persistent-volume.yml 파일입니다.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: neo4j-storage
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  csi:
    driver: nas.csi.volcengine.com
    volumeHandle: neo4j-data
    volumeAttributes:
      server: "cnbja0e0eda9ce19fe.vpc-1a1zcgj9sn8cg8nveplg3708b.nas.ivolces.com"
      path: "/enas-cnbja0e0eda9ce19fe/neo4j-data"
      fsType: "Extreme"
  mountOptions:
    - nolock,proto=tcp,noresvport
    - vers=3
2. PVC (PersistenVolumeClaim)

다음은 k8s-persistent-volume-claim.yml 파일입니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: neo4j-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  volumeName: neo4j-storage
  storageClassName: ""
3. Secret

Neo4j 비밀번호를 저장하기 위해 k8s-secret.yml 파일을 만듭니다.

apiVersion: v1
kind: Secret
metadata:
  name: neo4j-secret-key
type: Opaque
stringData:
  NEO4J_PASSWORD: "indemind@@"
4. StatefulSet

Neo4j를 관리하기 위해 k8s-statefulset.yml 파일을 작성합니다.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: neo4j-db
spec:
  serviceName: "neo4j-service"
  replicas: 1
  selector:
    matchLabels:
      app: neo4j
  template:
    metadata:
      labels:
        app: neo4j
    spec:
      enableServiceLinks: false
      volumes:
      - name: neo4j-volume
        persistentVolumeClaim:
          claimName: neo4j-claim
      containers:
      - name: neo4j-container
        image: docker.io/neo4j:5.22.0
        ports:
        - containerPort: 7474
          name: http
        - containerPort: 7687
          name: bolt
        env:
        - name: NEO4J_AUTH
          valueFrom:
            secretKeyRef:
              name: neo4j-secret-key
              key: NEO4J_PASSWORD
        resources:
          limits:
            cpu: "2"
            memory: 4Gi
          requests:
            cpu: "1"
            memory: 2Gi
        readinessProbe:
          httpGet:
            path: /
            port: 7474
          initialDelaySeconds: 20
          periodSeconds: 10
          timeoutSeconds: 10
          failureThreshold: 5
        livenessProbe:
          httpGet:
            path: /
            port: 7474
          initialDelaySeconds: 60
          periodSeconds: 10
          timeoutSeconds: 10
          failureThreshold: 5
        volumeMounts:
        - name: neo4j-volume
          mountPath: /data
5. Service

내부 통신을 위해 k8s-service.yml 파일을 작성합니다.

apiVersion: v1
kind: Service
metadata:
  name: neo4j-service
spec:
  type: ClusterIP
  selector:
    app: neo4j
  ports:
  - port: 7474
    targetPort: 7474
    name: http
  - port: 7687
    targetPort: 7687
    name: bolt
6. Ingress

외부 접근을 위해 k8s-ingress.yml 파일을 작성합니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: neo4j-ingress
spec:
  rules:
  - host: "neo4j.your-domain.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: neo4j-service
            port:
              number: 7474

태그: kubernetes docker-compose statefulset

7월 22일 07:24에 게시됨