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