쿠버네티스 환경에서 워드프레스 앱 실행해보기

hyeongjun Jo·2023년 2월 16일
1

DevOps

목록 보기
1/12
post-thumbnail

오늘은 쿠버네티스 환경 위에서 워드프레스 앱을 배포해보는 실습을 하겠습니다.
워드프레스 앱은 프론트엔드 웹 페이지와 데이터베이스로 구성된 멀티티어(multi-tier) 앱입니다. 데이터베이스는 mysql을 사용합니다.
워드프레스를 배포하는 것 뿐만아니라 모니터링을 하면서 무중단으로 파드의 숫자를 늘리고 줄여 보겠습니다.

목표

  • 사전 준비
    • 시크릿
    • 볼륨
  • 워드프레스 앱 배포
    • mysql 배포
    • 워드프레스 앱 배포
  • HPA를 이용해 파드 개수 자동 조절
    • 모니터링

아키텍처 구성도

쿠버네티스 환경

간단한 실습을 할 것이기 때문에 기존에 사용하던 AWS 환경이 아닌 Docker Desktop을 이용한 local 쿠버네티스 환경을 사용하였습니다.

버튼 하나로 손쉽게 쿠버네티스 환경을 구축할 수 있습니다.

내부를 들여다 보면 kubeadm을 이용하는 것을 알 수 있습니다. 자세한 내용은 아래를 참고바랍니다.
https://www.docker.com/blog/how-kubernetes-works-under-the-hood-with-docker-desktop/

기존의 .kube/config는 aws의 context를 가리키고 있기 때문에 current-context 필드를 수정해줍니다.

쿠버네티스 클러스터 환경준비가 끝났습니다.

데이터베이스

MySQL을 사용할 것이기 때문에 MySQL 유저 비밀번호를 쿠버네티스 시크릿으로 먼저 등록합니다.

이렇게 쿠버네티스 시크릿으로 비밀번호를 등록해두면 보안성은 지키면서 쿠버네티스 환경에서 자유롭게 수정/재배포 할 수 있습니다.

Type에서 Opaque는 기본적인 key-value 형식의 secret을 의미합니다.
Secret의 다양한 Type은 아래를 참고바랍니다.
https://kubernetes.io/docs/concepts/configuration/secret/

로컬 DB를 이용할 것이기 때문에 데이터베이스로 사용할 볼륨을 정의해야합니다.

local-volume.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-volume
  labels:
    type: local
spec:
  capacity:
    storage: 2Gi # 용량
  accessModes:
  - ReadWriteOnce # 접근모드 - 노드 하나에만 볼륨을 마운트
  hostPath:
    path: /tmp/test-lv # 경로
  persistentVolumeReclaimPolicy: Recycle # 볼륨 초기화 정책

볼륨이 활성화된 것을 알 수 있습니다.

이제 mysql 파드를 실행해봅시다.

mysql.yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
  - port: 3306
  selector:
    app: wordpress
    tier: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mariadb:10.7
        name: mysql
        env:
        - name: MYSQL_DATABASE
          value: wordpress
        - name: MYSQL_ROOT_PASSWORD # secret 사용
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password.txt
        ports:
        - containerPort: 3306
          name: mysql
        resources:
          requests:
          	cpu: 25m
          limits:
          	cpu: 50m
        volumeMounts:
        - name: mysql-local-storage
          mountPath: /var/lib/mysql
      volumes:
	  - name: mysql-local-storage
        persistentVolumeClaim:
          claimName: mysql-lv-claim
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-lv-claim
  labels:
    app: wordpress
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

PVC를 설정하여 앞서 만들어논 PV를 mysql Pod에서 사용하게 하였습니다.

이렇게 만들어논 PVC는 deployment의 manifest 알 수 있듯이 mysql 컨테이너의 디렉터리와 Mount하여 volume으로 사용할 수 있습니다.

replicas는 하나로 기본값이 1이라 작성하지 않아도 되지만 명시적으로 적어놓았습니다.

env필드를 보면 WORDPRESS_PASSWORD를 이전에 설정해놓았던 secret을 사용하는 것을 알 수 있습니다.

WordPress

이제 WordPress 앱을 실행 시켜봅시다.

wordpress.yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30180
  selector:
    app: wordpress
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:5.9.1-php8.1-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_NAME
          value: wordpress
        - name: WORDPRESS_DB_USER
          value: root
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password.txt
        resources:
          requests:
          	cpu: 25m
          limits:
          	cpu: 50m
        ports:
        - containerPort: 80
          name: wordpress

서비스는 NodePort 타입을 이용하였으며 포트번호는 30180으로 설정하였습니다.
만약 포트번호를 설정하지 않는다면 쿠버네티스에서 임의로 30000~32767 범위의 포트번호가 할당됩니다.

localhost:30180으로 접속하여 확인해봅시다.

🚨 TroubleShooting
DB와의 연결이 실패하는 경우가 발생하였는데 이유는 m1 맥북칩을 사용하는 나의 실습환경이 기존의 mysql:5.6 태그의 이미지를 받아오지 못해서였다.
그래서 mysql:8을 사용하였으나 php가 해당 UTF시리즈를 인식하지 못하는 버그가 발생하였다.
따라서 image를 mysql 에서 mariadb를 이용하여 버그를 고칠 수 있었다.

성공적으로 wordpress앱을 실행시켰습니다.

모니터링

앱을 실행시켰으니 이제 모니터링을 해봅시다.
쿠버네티스 대시보드에 접속합니다.

디플로이먼트와 파드의 상태를 볼 수 있고

손쉽게 파드의 로그를 찍어볼 수 있습니다.
이번엔 프로메테우스에 접속해봅시다.

성공적으로 접속이 되는 것을 알 수 있습니다.
모니터링할 준비를 마쳤으니 HPA를 이용해 파드의 개수를 늘리고 줄여봅시다.

오토스케일링

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: wordpress-hpa
  namespace: default
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: wordpress
  targetCPUUtilizationPercentage: 90

HPA mainfest 파일을 작성하고 실행합니다.
CPU는 90%가 넘어가면 scale up 하도록 설정하였습니다.

$ while true;do curl localhost:30180;done 명령으로 wordpress 앱의 접속량을 늘려 과부하를 줘볼까요?

hpa가 90% 이상의 cpu 사용량을 확인하고 replica를 늘리는 모습이 보입니다.
쿠버네티스 대시보드를 이용해 로그를 확인해봅시다.

반복해서 접속하려는 GET 요청이 찍히는 것을 알 수 있습니다.

프로메테우스로 확인해보면 CPU 사용률이 계속 상승하는 것을 알 수 있습니다.

hpa가 늘렸다 줄인 pod들도 시간에 따라 확인 가능합니다.

워드프레스에 직접 접속해보니 응답속도가 느려졌지만 연결이 끊기지는 않습니다.
이제 ^C로 과부하에 걸린 워드프레스앱을 해방시켜줍시다!

오늘은 쿠버네티스 환경에서 직접 mysql과 워드프레스 앱을 구동시키고 배포하여보았습니다. 실행과정에서 적지 않은 오류를 범했지만 성공적으로 실습을 마쳤습니다.


참고: https://kubernetes.io/ko/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/

profile
DevOps Engineer

0개의 댓글