이재홍의 언제나 최신 Kubernetes - Unit 5.2 MySQL 스테이트풀셋과 서비스의 구조 살펴보기

저작권 안내
  • 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
  • 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.

Spring Boot와 MySQL 실행하기

이재홍 http://www.pyrasis.com

MySQL 스테이트풀셋과 서비스의 구조 살펴보기

이제 YAML 파일을 자세히 살펴보겠습니다.

스테이트풀셋

mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  • .apiVersion: 현재 스테이트풀셋의 버전은 apps/v1입니다.
  • .kind: 스테이트풀셋을 생성하므로 StatefulSet을 지정합니다.
  • .metadata.name: 현재 스테이트풀셋의 이름입니다. 여기서는 mysql을 설정합니다.
  • .spec.serviceName: 연결하고자하는 헤드리스 서비스의 이름입니다. 여기서는 mysql을 설정합니다. 헤드리스 서비스는 뒤에서 설명하겠습니다.
  • .spec.replicas: 스테이트풀셋의 파드 개수입니다. 1로 설정하여 파드를 1개만 생성합니다.
  • .spec.selector: 스테이트풀셋으로 관리할 파드를 찾는 방법을 정의합니다. 여기서는 matchLabelsapp: mysql로 설정했으므로 키가 app, 값이 mysql로 정확히 일치하는 파드를 찾습니다.

여기서부터는 파드 설정입니다.

  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mysql
          image: mysql:5.7
          ports:
            - protocol: TCP
              containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: examplepassword
            - name: MYSQL_DATABASE
              value: example
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
  • .spec.template.metadata: labels에 키-값을 설정하여 스테이트풀셋이 찾을 수 있도록 합니다. 여기서는 app: mysql를 설정했습니다.
  • .spec.template.spec: 파드의 spec입니다. 파드에는 컨테이너가 여러 개 들어갈 수 있어서 containers로 되어있고, 그 아래에는 -를 사용하여 배열(Array)로 값을 설정합니다.
    • terminationGracePeriodSeconds: 10을 설정했는데, 종료 요청 후 10초간 기다리도록 합니다. 데이터베이스가 손상되지 않게 하기 위함입니다.
    • containers:
      • name에는 컨테이너의 이름을 설정합니다. 여기서는 mysql로 설정했지만 셀렉터와는 상관이 없습니다.
      • image에는 컨테이너를 실행할 Docker 이미지를 설정합니다. <이미지>:<태그> 형식이며 여기서는 mysql:5.7을 설정했습니다.
      • ports: 배열 형태로 containerPort를 설정합니다. containerPort는 컨테이너에서 개방할 포트 번호를 뜻합니다. 여기서는 MySQL 데이터베이스 포트인 3306을 설정했습니다.
      • env: 환경 변수입니다. 배열 형태로 설정하며 name, value 형식입니다. 여기서는 MYSQL_ROOT_PASSWORDexamplepassword를 설정했고, MYSQL_DATABASEexample을 설정하여 MySQL 데이터베이스가 처음 실행될 때 example 데이터베이스를 생성하도록 합니다.
      • volumeMounts: 볼륨 설정입니다. 스테이트풀셋은 상태를 저장하기 때문에 이 부분이 중요합니다. 배열 형태로 설정하며 name에는 볼륨의 이름인 data를 설정했고, mountPath에는 /var/lib/mysql를 설정하여 컨테이너의 /var/lib/mysql 경로에 data 볼륨이 연결되도록 합니다. data 볼륨은 뒤에서 설명하겠습니다.

그림 5-2 MySQL 스테이트풀셋

이제 퍼시스턴트 볼륨 클레임(Persistent Volume Claim, 영구 볼륨 요청) 부분입니다. 즉, 쿠버네티스 클러스터에 영구적으로 데이터를 저장할 수 있는 볼륨을 요청하여 스토리지(저장소)를 받겠다는 뜻입니다.

  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        storageClassName: standard
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
  • .spec.volumeClaimTemplates: 퍼시스턴트 볼륨 클레임 설정입니다.
    • metadata: 퍼시스턴트 볼륨 클레임의 이름입니다. 여기서는 data를 설정했습니다.
    • spec: 퍼시스턴트 볼륨 클레임의 spec입니다.
      • storageClassName: 스토리지 클래스(sc) 설정입니다. 여기서는 standard로 설정했습니다. 스토리지 클래스는 나중에 다른 것을 추가해서 사용할 수 있습니다.
      • accessModes: 접근 모드입니다. 여기서는 ReadWriteOnce로 설정했으며 ReadWriteOnce는 하나의 노드에서만 현재 볼륨이 읽기/쓰기로 마운트될 수 있습니다.
      • resources: 요청할 리소스 설정입니다. requestsstorage: 1Gi를 설정하여 스토리지(저장소) 1Gi 용량을 받겠다는 뜻입니다.

kubectl get pvc 명령을 입력하면 현재 생성된 퍼시스턴트 볼륨 클레임(pvc)을 확인할 수 있습니다.

$ kubectl get pvc
NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-mysql-0   Bound    pvc-34538161-d92c-48de-83cc-594107fe0868   1Gi        RWO            standard       10s

kubectl get pv 명령을 입력하면 퍼시스턴트 볼륨 클레임(pvc)을 통해 생성된 퍼시스턴트 볼륨(pv)를 확인할 수 있습니다. 여기가 실제 데이터가 저장되는 스토리지입니다.

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE
pvc-34538161-d92c-48de-83cc-594107fe0868   1Gi        RWO            Delete           Bound    default/data-mysql-0   standard                110s

그림 5-3 MySQL 퍼시스턴트 볼륨 클레임과 퍼시스턴트 볼륨

서비스

다음은 서비스입니다. 스테이트풀셋 서비스의 특징적인 점은 헤드리스 서비스를 사용한다는 점입니다. 헤드리스는 말그대로 머리가 없다는 뜻인데, 쿠버네티스에서는 IP 주소가 할당되지 않은 서비스를 뜻합니다. 그리고 헤드리스 서비스는 파드에 트래픽을 랜덤(또는 라운드로빈 등의 알고리즘)으로 균등하게 전달하지 않고, 파드의 이름을 직접 지정해서 전달합니다.

mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306
  • .apiVersion: 현재 서비스의 버전은 v1입니다.
  • .kind: 여기서는 서비스를 작성하므로 Service를 지정합니다.
  • .metadata.name: 현재 서비스의 이름입니다. 여기서는 mysql을 설정합니다.
  • .spec.clusterIP: ClusterIPNone으로 설정하여 헤드리스 서비스로 만듭니다.
  • .spec.selector: 서비스가 트래픽을 전달할 파드를 선택합니다. 여기서는 app: mysql을 설정했으므로 키가 app, 값이 mysql인 파드를 찾습니다.
  • .spec.ports: protocolTCP, port3306으로 설정합니다.

그림 5-4 MySQL 서비스

앞에서 mysql:5.7 컨테이너로 MySQL 데이터베이스에 접근할 때 -h 옵션에 호스트를 mysql로 지정했는데, 이렇게 하면 스테이트풀셋의 첫 번째 파드인 pod/mysql-0으로 트래픽을 전달합니다.

$ kubectl run -it --rm mysql-client --image=mysql:5.7 --restart=Never -- sh
If you don't see a command prompt, try pressing enter.
sh-4.2# mysql -h mysql -u root -p

저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

2022-10-22