이번 실습에서는 MySQL 데이터베이스를 사용하여 Google Kubernetes Engine(GKE)에서 단일 복제본 WordPress 배포를 설정하는 방법을 설명합니다.
MySQL을 설치하는 대신 MySQL의 관리형 버전을 제공하는 Cloud SQL을 사용합니다.
WordPress는 PersistentVolumes(PV) 및 PersistentVolumeClaims(PVC)를 사용하여 데이터를 저장합니다.
PV는 PVC에서 작성된 요청을 수행하기 위해 관리자가 프로비저닝하거나 Kubernetes에 의해 동적으로 프로비저닝되는 클러스터의 스토리지 볼륨을 나타냅니다. PVC는 특정 스토리지 클래스의 스토리지에 대한 사용자의 요청으로 PV에서 수행할 수 있습니다. PV 및 PVC는 pod 수명 주기와 별개이며 pod의 다시 시작, 재예약, 삭제를 통해 데이터를 보존합니다. WordPress는 Google Persistent Disk를 PV 지원용 스토리지로 사용합니다.
일반적으로 컨테이너의 루트 파일 시스템은 영구 데이터를 저장하는 데 적합하지 않습니다. GKE에서 실행하는 컨테이너는 일반적으로 일회용 항목이며, 클러스터 관리자는 노드 오류 또는 기타 원인으로 인해 사용할 수 없게 된 모든 컨테이너를 삭제, 축출 또는 다시 예약해야 합니다. 노드가 실패하면 컨테이너의 루트 파일 시스템에 저장된 모든 데이터가 손실됩니다.
Persistent Disk에서 지원되는 PV를 사용하면 WordPress 플랫폼 데이터를 컨테이너 외부에 저장할 수 있습니다. 이렇게 하면 컨테이너가 삭제되더라도 데이터가 유지됩니다. 기본 스토리지 클래스를 사용하면 pod가 다른 노드로 다시 예약되는 경우 Persistent Disk(및 데이터)가 pod와 함께 이동하지 않습니다.
- GKE 클러스터 만들기
- Persistent Disk에서 지원되는 PV 및 PVC 만들기
- MySQL용 Cloud SQL 인스턴스 만들기
- WordPress 배포
- 삭제
실습은 Cloud Shell을 이용하여 진행하겠습니다.
gcloud services enable container.googleapis.com sqladmin.googleapis.com
# Cloud Shell에서 GKE 및 Cloud SQL Admin API를 사용 설정합니다.
gcloud config set compute/zone asia-northeast2-a
# Cloud Shell에서 gcloud 명령줄 도구의 기본 영역을 설정합니다.
export PROJECT_ID=central-accord-331407
# PROJECT_ID 환경 변수를 Google Cloud 프로젝트 ID로 설정합니다.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
# GitHub 저장소에서 앱 매니페스트 파일을 다운로드합니다.
cd kubernetes-engine-samples/wordpress-persistent-disks
# wordpress-persistent-disks 파일이 있는 디렉토리로 이동합니다.
WORKING_DIR=$(pwd)
# WORKING_DIR 환경 변수를 설정합니다.
이 실습에서는 YAML 형식의 매니페스트 파일을 사용하여 k8s 객체를 만듭니다.
WordPress 앱 컨테이너를 호스팅하기 위한 GKE 클러스터를 만듭니다.
CLUSTER_NAME=persistent-disk-tutorial
gcloud container clusters create $CLUSTER_NAME \
--num-nodes=3 --enable-autoupgrade --no-enable-basic-auth \
--no-issue-client-certificate --enable-ip-alias --metadata \
disable-legacy-endpoints=true
# Cloud Shell에서 노드가 3개인 persistent-disk-tutorial 이라는
클러스터를 만듭니다.
참고: 이 이전 단계에서 설명한 대로 영역을 올바르게 설정했는지 확인합니다.
영역이 설정되지 않았으면 gcloud가 리전 클러스터를 만듭니다. 리전 클러스터는 프로젝트의 기본 리전 내에서 영역별 3개 노드로 구성된 노드 풀을 만듭니다. 이렇게 하면 단일 영역 클러스터보다 많은 노드가 포함된 클러스터가 발생하고 할당량 문제가 발생할 수 있습니다.
WordPress에 필요한 스토리지로 PVC를 만듭니다. GKE에는 Persistent Disk에서 지원되는 PV를 동적으로 프로비저닝할 수 있는 기본 StorageClass 리소스가 설치되어 있습니다. wordpress-volumeclaim.yaml 파일을 사용하여 배포에 필요한 PVC를 만듭니다.
이 매니페스트 파일은 200GB의 스토리지를 요청하는 PVC를 설명합니다. 파일에서 StorageClass 리소스가 정의되지 않았으므로 이 PVC는 기본 StorageClass 리소스를 사용하여 Persistent Disk에서 지원되는 PV를 프로비저닝합니다.
kubectl apply -f $WORKING_DIR/wordpress-volumeclaim.yaml
# Cloud Shell에서 매니페스트 파일을 배포합니다.
kubectl get persistentvolumeclaim
# Persistent Disk에서 지원되는 PV를 프로비저닝하고 PVC에 결합되는데
최대 10초가 걸릴수 있습니다. 위 명령어로 상태를 확인할 수 있습니다.
INSTANCE_NAME=mysql-wordpress-instance
gcloud sql instances create $INSTANCE_NAME
# Cloud Shell에서 mysql-wordpress-instance 라는 인스턴스를 만듭니다.
export INSTANCE_CONNECTION_NAME=$(gcloud sql instances describe $INSTANCE_NAME \
--format='value(connectionName)')
# 인스턴스 연결 이름을 환경 변수로 추가합니다.
gcloud sql databases create wordpress --instance $INSTANCE_NAME
# WordPress에 대해 데이터를 저장할 데이터베이스를 만듭니다.
CLOUD_SQL_PASSWORD=$(openssl rand -base64 18)
gcloud sql users create wordpress --host=% --instance $INSTANCE_NAME \
--password $CLOUD_SQL_PASSWORD
# WordPress에서 인스턴스를 인증할 wordpress 라는 데이터베이스 사용자와
비밀번호를 만듭니다.
# Cloud Shell 세션을 닫으면 비밀번호가 손실됩니다. 비밀번호는 후반부에
필요하므로 기록해둡니다.
WordPress 블로그의 데이터베이스 설정이 완료되었습니다.
WordPress를 배포하려면 먼저 서비스 계정을 만들어야 합니다. 서비스 계정 사용자 인증 정보를 저장할 Kubernetes 보안 비밀과 데이터베이스 사용자 인증 정보를 저장할 다른 보안 비밀을 만듭니다.
SA_NAME=cloudsql-proxy
gcloud iam service-accounts create $SA_NAME --display-name $SA_NAME
# Cloud SQL 프록시를 통해 WordPress 앱에서 MYSQL 인스턴스에 액세스할 수 있게
하려면 서비스 계정을 만들어야 합니다.
SA_EMAIL=$(gcloud iam service-accounts list \
--filter=displayName:$SA_NAME \
--format='value(email)')
# 서비스 계정 이메일 주소를 환경 변수로 추가합니다.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--role roles/cloudsql.client \
--member serviceAccount:$SA_EMAIL
# 서비스 계정에 cloudsql.client 역할을 추가합니다.
gcloud iam service-accounts keys create $WORKING_DIR/key.json \
--iam-account $SA_EMAIL
# 서비스 계정의 키를 만듭니다.
# 이 명령어는 key.json 파일의 사본을 다운로드합니다.
kubectl create secret generic cloudsql-db-credentials \
--from-literal username=wordpress \
--from-literal password=$CLOUD_SQL_PASSWORD
# MYSQL 사용자 인증 정보용 K8s Secret을 만듭니다.
kubectl create secret generic cloudsql-instance-credentials \
--from-file $WORKING_DIR/key.json
# 서비스 계정 사용자 인증 정보용 k8s Secret을 만듭니다.
다음 단계는 GKE 클러스터에 WordPress 컨테이너를 배포하는 것입니다.
wordpress_cloudsql.yaml 매니페스트 파일은 WordPress 인스턴스가 있는 컨테이너를 실행하는 단일 pod를 만드는 배포를 설명합니다. 이 컨테이너는 생성된 cloudsql-db-credentials 보안 비밀이 포함된 WORDPRESS_DB_PASSWORD 환경 변수를 읽습니다.
또한 이 매니페스트 파일은 사이드카 컨테이너에서 실행되는 Cloud SQL 프록시를 통해 MySQL과 통신하도록 WordPress 컨테이너를 구성합니다. 호스트 주소 값은 WORDPRESS_DB_HOST 환경 변수에 설정됩니다.
cat $WORKING_DIR/wordpress_cloudsql.yaml.template | envsubst > \
$WORKING_DIR/wordpress_cloudsql.yaml
# INSTANCE_CONNECTION_NAME 환경 변수를 바꿔서 파일을 준비합니다.
kubectl create -f $WORKING_DIR/wordpress_cloudsql.yaml
# wordpress_cloudsqll.yaml 매니페스트 파일을 배포합니다.
kubectl get pod -l app=wordpress --watch
# 배포를 확인하여 상태가 running으로 변경되는지 체크합니다.
현재 외부 IP 주소가 없으므로 클러스터 외부에서 액세스할 수 없습니다. 외부 부하 분산기로 k8s 서비스를 만들고 구성하여 WordPress 앱을 인터넷에 노출시킬 수 있습니다.
kubectl create -f $WORKING_DIR/wordpress-service.yaml
# type : LoadBalancer 의 서비스를 만듭니다. 몇 분정도 소요됩니다.
kubectl get svc -l app=wordpress --watch
# 배포를 확인하고 서비스에 외부 IP 주소가 할당될 때 까지 기다립니다.
EXTERNAL-IP로 접속해보겠습니다.
프로젝트를 삭제하거나 개별 리소스를 삭제해줍니다.
kubectl delete service wordpress
# 서비스를 삭제합니다.
# wordpress 서비스에 프로비저닝된 부하 분산기가 삭제될 때 까지 기다립니다.
백그라운드에서 부하 분산기가 비동기식으로 삭제됩니다.
watch gcloud compute forwarding-rules list
# 삭제 프로세스를 확인합니다.
Listed 0 items.
# 위 출력이 표시되면 부하 분산기가 삭제된 것입니다.
kubectl delete deployment wordpress
# 배포를 삭제합니다.
kubectl delete pvc wordpress-volumeclaim
# Wordpress용 PVC를 삭제합니다.
이 명령어는 PV 및 Persistent Disk도 자동으로 삭제합니다.
gcloud container clusters delete $CLUSTER_NAME
# GKE 클러스터를 삭제합니다.
gcloud sql instances delete $INSTANCE_NAME
# Cloud SQL 인스턴스를 삭제합니다.
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--role roles/cloudsql.client \
--member serviceAccount:$SA_EMAIL
# 서비스 계정에서 역할을 삭제합니다.
gcloud iam service-accounts delete $SA_EMAIL
# 서비스 계정을 삭제합니다.
참고 https://cloud.google.com/kubernetes-engine/docs/tutorials/persistent-disk?hl=ko