예시: WordPress와 MySQL을 퍼시스턴트 볼륨에 배포하기
이 튜토리얼은 WordPress 사이트와 MySQL 데이터베이스를 Minikube를 이용하여 어떻게 배포하는지 보여준다. 애플리케이션 둘 다 퍼시스턴트 볼륨과 퍼시스턴트볼륨클레임을 데이터를 저장하기 위해 사용한다.
퍼시스턴트볼륨(PV)는 관리자가 수동으로 프로비저닝한 클러스터나 쿠버네티스 스토리지클래스를 이용해 동적으로 프로비저닝된 저장소의 일부이다. 퍼시스턴트볼륨클레임(PVC)은 PV로 충족할 수 있는 사용자에 의한 스토리지 요청이다. 퍼시스턴트볼륨은 파드 라이프사이클과 독립적이며 재시작, 재스케줄링이나 파드를 삭제할 때에도 데이터를 보존한다.
경고:
이 배포는 프로덕션 사용 예로는 적절하지 않은데 이는 단일 인스턴스의 WordPress와 MySQL을 이용했기 때문이다. 프로덕션이라면 WordPress Helm Chart로 배포하기를 고려해보자.참고:
이 튜토리얼에 제공된 파일들은 GA 디플로이먼트 API를 사용하며 쿠버네티스 버전 1.9 이상을 이용한다. 이 튜토리얼을 쿠버네티스 하위 버전에서 적용한다면 API 버전을 적절히 갱신하거나 이 튜토리얼의 이전 버전을 참고하자.목적
- 퍼시스턴트볼륨클레임과 퍼시스턴트볼륨 생성
- 다음을 포함하는
kustomization.yaml
생성- 시크릿 생성자
- MySQL 리소스 구성
- WordPress 리소스 구성
kubectl apply -k ./
로 생성한 kustomization 을 적용- 정리
시작하기 전에
쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.
버전 확인을 위해서, 다음 커맨드를 실행kubectl version
.
이 예시는 kubectl
1.14 이상 버전에서 동작한다.다음 설정 파일을 다운로드한다.
퍼시스턴트볼륨클레임과 퍼시스턴트볼륨 생성
MySQL과 Wordpress는 각각 데이터를 저장할 퍼시스턴트볼륨이 필요하다. 퍼시스턴트볼륨클레임은 배포 단계에 생성된다.
많은 클러스터 환경에서 설치된 기본 스토리지클래스(StorageClass)가 있다. 퍼시스턴트볼륨클레임에 스토리지클래스를 지정하지 않으면 클러스터의 기본 스토리지클래스를 사용한다.
퍼시스턴트볼륨클레임이 생성되면 퍼시스턴트볼륨이 스토리지클래스 설정을 기초로 동적으로 프로비저닝된다.
경고:
로컬 클러스터에서 기본 스토리지클래스는hostPath
프로비저너를 사용한다. hostPath
는 개발과 테스트 목적에만 적합하다. hostPath
볼륨인 경우 데이터는 스케쥴링된 파드의 노드에 /tmp
살아있고 노드 간에 이동하지 않는다. 파드가 죽어서 클러스터 내에 다른 노드로 스케줄링되거나 해당 노드가 재부팅되면 그 데이터는 잃어버린다.참고:
hostPath
프로비저너를 사용해야 하는 클러스터를 기동하는 경우라면 --enable-hostpath-provisioner
플래그를 controller-manager
컴포넌트에 꼭 설정해야 한다.참고:
만약 구글 쿠버네티스 엔진으로 운영하는 쿠버네티스 클러스터를 가지고 있다면 가이드를 따르도록 한다.kustomization.yaml 생성하기
시크릿 생성자 추가
시크릿은 암호나 키 같은 민감한 데이터들을 저장하는 오브젝트이다. 1.14 버전부터 kubectl
은 kustomization 파일을 이용해서 쿠버네티스 오브젝트를 관리한다. kustomization.yaml
의 제너레이터로 시크릿을 생성할 수 있다.
다음 명령어로 kustomization.yaml
내에 시크릿 제네레이터를 추가한다. YOUR_PASSWORD
는 사용하기 원하는 암호로 변경해야 한다.
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: mysql-pass
literals:
- password=YOUR_PASSWORD
EOF
MySQL과 WordPress에 필요한 리소스 구성 추가하기
다음 매니페스트는 MySQL 디플로이먼트 단일 인스턴스를 기술한다. MySQL 컨케이너는 퍼시스턴트볼륨을 /var/lib/mysql에 마운트한다. MYSQL_ROOT_PASSWORD
환경 변수는 시크릿에서 가져와 데이터베이스 암호로 설정한다.
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: 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
다음의 매니페스트는 단일-인스턴스 WordPress 디플로이먼트를 기술한다. WordPress 컨테이너는
웹사이트 데이터 파일을 위해 /var/www/html
에 퍼시스턴트볼륨을 마운트한다. WORDPRESS_DB_HOST
환경 변수에는
위에서 정의한 MySQL 서비스의 이름이 설정되며, WordPress는 서비스를 통해 데이터베이스에 접근한다.
WORDPRESS_DB_PASSWORD
환경 변수에는 kustomize가 생성한 데이터베이스 패스워드가 설정된다.
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
MySQL 디플로이먼트 구성 파일을 다운로드한다.
curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml
WordPress 구성 파일을 다운로드한다.
curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml
두 파일을
kustomization.yaml
에 추가하자.
cat <<EOF >>./kustomization.yaml
resources:
- mysql-deployment.yaml
- wordpress-deployment.yaml
EOF
적용하고 확인하기
kustomization.yaml
은 WordPress 사이트와 MySQL 데이터베이스를 배포하는 모든 리소스를 포함한다.
다음과 같이 디렉터리를 적용할 수 있다.
kubectl apply -k ./
이제 모든 오브젝트가 존재하는지 확인할 수 있다.
시크릿이 존재하는지 다음 명령어를 실행하여 확인한다.
kubectl get secrets
응답은 아래와 비슷해야 한다.
NAME TYPE DATA AGE mysql-pass-c57bb4t7mf Opaque 1 9s
퍼시스턴트볼륨이 동적으로 프로비저닝되었는지 확인한다.
kubectl get pvc
참고:
PV를 프로비저닝하고 정착(bound)시키는데 수 분이 걸릴 수 있다.
응답은 아래와 비슷해야 한다.
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mysql-pv-claim Bound pvc-8cbd7b2e-4044-11e9-b2bb-42010a800002 20Gi RWO standard 77s wp-pv-claim Bound pvc-8cd0df54-4044-11e9-b2bb-42010a800002 20Gi RWO standard 77s
다음 명령어를 실행하여 파드가 실행 중인지 확인한다.
kubectl get pods
참고:
파드의 상태가 `RUNNING`가 되기까지 수 분이 걸릴 수 있다.
응답은 아래와 비슷해야 한다.
NAME READY STATUS RESTARTS AGE wordpress-mysql-1894417608-x5dzt 1/1 Running 0 40s
다음 명령어를 실행하여 서비스가 실행 중인지 확인해보자.
kubectl get services wordpress
응답은 아래와 비슷해야 한다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE wordpress LoadBalancer 10.0.0.89 <pending> 80:32406/TCP 4m
참고:
Minikube에서는 서비스를 `NodePort`으로만 노출할 수 있다. EXTERNAL-IP는 항상 Pending 상태이다.
다음 명령어를 실행하여 WordPress 서비스의 IP 주소를 얻어온다.
minikube service wordpress --url
응답은 아래와 비슷해야 한다.
http://1.2.3.4:32406
IP 주소를 복사해서 웹 브라우저에서 사이트를 열어 보자.
아래 스크린샷과 유사한 WordPress 설정 페이지를 볼 수 있어야 한다.
경고:
이 페이지의 WordPress 설치를 내버려 두지 말자. 다른 사용자가 이 페이지를 발견하고 귀하의 인스턴스에 웹 사이트를 설정하고 악의적인 컨텐츠를 게시하는데 사용할 수 있다.WordPress를 사용자명과 암호를 넣어 생성하거나 인스턴스를 삭제하자.
정리하기
다음 명령을 실행하여 시크릿, 디플로이먼트, 서비스와 퍼시스턴트볼륨클레임을 삭제하자.
kubectl delete -k ./
다음 내용
- 인트로스펙션과 디버깅을 알아보자.
- 잡를 알아보자.
- 포트 포워딩를 알아보자.
- 어떻게 컨테이너에서 셸을 사용하는지를 알아보자.