본문 바로가기

Server Infra/Kubernetes

K8s Study DOIK - MySQL Operator for Kubernetes #2

728x90

세팅끝

일단 셈플로 넣은 Database와 Table부터 만들어서 넣자!(터널링으로 접근하여 Datagrip로 밀어 넣었다)

-- auto-generated definition
create schema testdb collate utf8mb4_0900_ai_ci;

-- auto-generated definition
create table users
(
    id              int auto_increment primary key,
    email           varchar(100) null,
    hashed_password varchar(100) null,
    is_active       tinyint(1)   null,
    constraint ix_users_email unique (email)
);

create index ix_users_id on users (id);

자 이제 이전 포스팅에서 만든 docker를 활용하여 deploy와 svc를 배포할 차례이다.

 

우선 전용으로 사용할 namespace를 만들어 주었다

k create ns demo-fast

이유는 프로메테우스 지표 때문인데 이전 포스팅에서 설치한 프로메테우스에 자세한 지표를 추가하기 위하여 나는 istio의 지표를 활용하려 한다.

curl -L https://istio.io/downloadIstio | sh -
cd istio-1.14.1/
export PATH=$PWD/bin:$PATH

istioctl profile list #사용할 profile을 미리 확인한다. 나는 demo를 선택했다.

istioctl install --set profile=demo -y
#설치가 완료되면 사전에 만든 namespace에 label을 달아준다.

k label namespaces demo-fast istio-injection=enabled

위의 작업이 마무리 되면 아래의 resource를 생성해 줄것이다.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: fastapi-sample
  name: fastapi-sample
  namespace: demo-fast
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fastapi-sample
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: fastapi-sample
    spec:
      containers:
      - image: mateon01/sample-fastapi:1.0.3
        name: sample-fastapi
        ports:
        - containerPort: 8080
        resources: {}
        env:
          - name: db_url_val
            value: mysql+pymysql://root:*****@mycluster.mysql-cluster.svc:3306/testdb
          - name: db_reader_url_val
            value: mysql+pymysql://root:*****@mycluster.mysql-cluster.svc:6447/testdb
        livenessProbe:
          httpGet:
            path: /get
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
  name: fastapi-sample-service
  namespace: demo-fast
spec:
  selector:
    app: fastapi-sample
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

배포를 하면

API 호출도 잘 되고 DB에 입력도 잘 된다. 만족스럽게 어플리케이션까지 배포했다면 자동으로 스캐일링 되게끔 keda와 autoscaler를 설정해 보자!

https://keda.sh/docs/2.5/scalers/mysql/

 

KEDA | MySQL

Scale applications based on MySQL query result.

keda.sh

위의 링크를 참조해서 작성했는데 각 kind별 spec에 대한 설명이 조금 아쉬웠다.

kubectl explain [kind name] --recursive

위의 명령어로 스팩들을 확인하여 작성하도록 하자!

일단 프로메테우스의 메트릭은 만족스럽게 나온다. 해당 지표로 KEDA ScaledObject를 만들었다.

apiVersion: keda.sh/v1alpha1 
kind: ScaledObject 
metadata: 
  name: fastapi-scale 
spec: 
  scaleTargetRef: 
    kind: Deployment 
    name: fastapi-sample 
  minReplicaCount: 1 
  maxReplicaCount: 40 
  cooldownPeriod: 30 
  pollingInterval: 1 
  triggers: 
  - type: prometheus 
    metadata: 
      serverAddress: http://prometheus.istio-system.svc:9090
      metricName: fastapi_connections_active_keda 
      query: | 
          sum(avg_over_time(istio_requests_total{app="fastapi-sample"}[1m]))
      threshold: "50"

 

keda설정과 지표 수집부터 모든 준비가 끝났다. 이제 부하테스트를 해보겠다

 

user의 수가 200까지는 잘 버티기에 400까지 올려보았더니 중간중간 timeout이 나서 DB select query가 실패하는것을 확인했다.

오 깨졌나?! 싶었는데

각 인스턴스별로 모니터링하고 있었다.

그냥 커넥션 수가 문제였다 ㅠㅠㅠ

분명 Pool을 만들었는데...? 빠르게 Connection수를 늘려주자

SHOW VARIABLES LIKE "max_connections";

SET GLOBAL max_connections = 100000;

이제 다시 때려보자!

드디어 기다리던 Internal Server Error가 나왔다.(하지만 어느 소스에서 에러가 났는지는 모른다..)

생각해보니까 로그도 모니터링을 같이 해야하네...?!

그리고 DB의 성능도 문제다. QPS가 200정도 뿐이 안된다.

 

좀더 복잡한 테이블로 쿼리해야하나...? 우선 이 데이터베이스 생각보다 잘 죽지 않는다. 저 에러도 Latency 문제로 정말 select가 실패했거나 내가 만든 Python API가 구려서 일 수도 있다. Go와 같은 언어로 하면 좀더 빠를것 같지만 러닝커브가 필요하니 이건 패스...

 

일단, 예상대로 되지않아 많이 슬프다 ㅠ 생각보다 mysql operator 이놈이 잘 만들어졌다.

728x90