단일 인스턴스 유상태(Stateful) 애플리케이션 실행하기

단일 인스턴스 유상태(Stateful) 애플리케이션 실행하기

이 페이지는 PersistentVolume과 Deployment를 사용해 Kubernetes에서 단일 인스턴스 유상태(stateful) 애플리케이션을 실행하는 방법을 보여줘요. 애플리케이션은 MySQL이에요.

출처: 문서

본문

목표 (Objectives)

  • 환경의 디스크를 참조하는 PersistentVolume 만들기
  • MySQL Deployment 만들기
  • MySQL을 알려진 DNS 이름으로 클러스터의 다른 파드에 노출하기

시작하기 전에

  • Kubernetes 클러스터가 있어야 하고 kubectl 명령줄 도구가 클러스터와 통신하도록 구성되어 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 최소 두 개 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube를 이용해 만들거나, 아래 Kubernetes 플레이그라운드(iximiuz Labs, Killercoda, KodeKloud) 중 하나를 사용할 수 있어요. 버전을 확인하려면 kubectl version을 입력해요.
  • 기본 StorageClass가 있는 동적 PersistentVolume 프로비저너가 있거나, 여기 사용된 PersistentVolumeClaim을 충족하도록 PersistentVolume을 직접 정적으로 프로비저닝해야 해요.

MySQL 배포

Kubernetes Deployment를 만들고 PersistentVolumeClaim으로 기존 PersistentVolume에 연결해 유상태 애플리케이션을 실행할 수 있어요. 예를 들어 이 YAML 파일은 MySQL을 실행하고 PersistentVolumeClaim을 참조하는 Deployment를 설명해요. 이 파일은 /var/lib/mysql에 대한 볼륨 마운트를 정의하고, 20G 볼륨을 찾는 PersistentVolumeClaim을 만들어요. 이 클레임은 요구 사항을 충족하는 기존 볼륨이나 동적 프로비저너가 충족해요.

참고: 비밀번호가 구성 yaml에 정의되어 있는데, 이것은 안전하지 않아요. 보안 솔루션은 Kubernetes Secrets를 참고해요.

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:9
        name: mysql
        env:
          # Use secret in real usage
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  • YAML 파일의 PV와 PVC를 배포해요.
  • YAML 파일의 내용을 배포해요.
  • Deployment에 대한 정보를 표시해요.
  • Deployment가 만든 파드를 나열해요.
  • PersistentVolumeClaim을 검사해요.

MySQL 인스턴스 접근

앞선 YAML 파일은 클러스터의 다른 파드가 데이터베이스에 접근할 수 있게 하는 서비스를 만들어요. clusterIP: None 서비스 옵션은 서비스 DNS 이름이 파드의 IP 주소로 직접 해석되게 해요. 이것은 서비스 뒤에 파드가 하나만 있고 파드 수를 늘릴 의도가 없을 때 최적이에요.

MySQL 클라이언트를 실행해 서버에 연결해요.

kubectl run -it --rm --image=mysql:9 --restart=Never mysql-client -- mysql -h mysql -ppassword

이 명령은 MySQL 클라이언트를 실행하는 새 파드를 클러스터에 만들고, Service를 통해 서버에 연결해요. 연결되면 유상태 MySQL 데이터베이스가 실행 중이라는 것을 알 수 있어요.

Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.

mysql>

업데이트

이미지나 Deployment의 다른 부분은 평소대로 kubectl apply 명령으로 업데이트할 수 있어요. 다음은 유상태 앱에 특화된 몇 가지 주의 사항이에요.

  • 앱을 확장하지 마세요. 이 설정은 단일 인스턴스 앱 전용이에요. 기반 PersistentVolume은 한 파드에만 마운트될 수 있어요. 클러스터링된 유상태 앱은 StatefulSet 문서를 참고해요.
  • Deployment 구성 YAML 파일에서 strategy: type: Recreate를 사용해요. 이것은 Kubernetes가 롤링 업데이트를 사용하지 않도록 지시해요. 한 번에 하나 이상의 파드가 실행될 수 없으므로 롤링 업데이트는 동작하지 않아요. Recreate 전략은 업데이트된 구성으로 새 파드를 만들기 전에 첫 파드를 중지해요.

배포 삭제

이름으로 배포된 객체를 삭제해요.

kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume

PersistentVolume을 수동으로 프로비저닝했다면, 기반 리소스를 해제하는 것뿐 아니라 그것도 수동으로 삭제해야 해요. 동적 프로비저너를 사용했다면, PersistentVolumeClaim을 삭제한 것을 보면 PersistentVolume을 자동으로 삭제해요. 일부 동적 프로비저너(EBS와 PD용 같은)는 PersistentVolume을 삭제할 때 기반 리소스도 해제해요.

다음 단계

더 알아보기 (Learn more)