Redis 및 PHP로 방명록 만들기

이 가이드는 GKE를 사용하여 간단한 다중 계층 웹 애플리케이션을 빌드하는 방법을 보여 줍니다. 가이드 애플리케이션은 방문자가 로그에 텍스트를 입력하고 마지막으로 로깅된 몇 개의 항목을 볼 수 있는 방명록입니다.

이 가이드는 부하 분산기를 사용하여 외부 IP에서 방명록 웹 서비스를 설정하는 방법과 단일 마스터 및 다중 작업자로 구성된 Redis 클러스터를 실행하는 방법을 보여 줍니다.

이 예에서는 여러 가지 GKE의 중요 개념을 상세히 설명합니다.

  • YAML 매니페스트 파일을 사용하는 선언적 구성
  • 복제된 포드 집합의 구성을 결정하는 Kubernetes 리소스인 배포
  • 포드 집합의 내부 및 외부 부하 분산기를 만들기 위한 서비스

목표

GKE에서 방명록 애플리케이션을 배포하고 실행하려면 다음을 수행해야 합니다.

  1. Redis 마스터 설정
  2. Redis 작업자 설정
  3. 방명록 웹 프런트엔드 설정
  4. 방명록 웹사이트 방문
  5. 방명록 웹 프런트엔드 확장

시작하기 전에

다음 단계에 따라 Kubernetes Engine API를 사용 설정합니다.
  1. Google Cloud Platform Console에서 Kubernetes Engine 페이지로 이동합니다.
  2. 프로젝트를 만들거나 선택합니다.
  3. API 및 관련 서비스가 사용 설정될 때까지 기다립니다. 몇 분 정도 걸릴 수 있습니다.
  4. 프로젝트에 결제가 사용 설정되어 있는지 확인하세요.

    결제 사용 설정 방법 알아보기

이 가이드에 사용된 다음 명령줄 도구를 설치합니다.

  • gcloud는 Kubernetes Engine 클러스터를 만들고 삭제하는 데 사용됩니다. gcloudGoogle Cloud SDK에 포함되어 있습니다.
  • kubectl은 Kubernetes Engine에서 사용되는 클러스터 조정 시스템인 Kubernetes를 관리하기 위해 사용됩니다. gcloud를 사용하여 kubectl을 설치할 수 있습니다.
    gcloud components install kubectl

gcloud 명령줄 도구의 기본값 설정

gcloud 명령줄 도구에서 프로젝트 IDCompute Engine 영역 옵션을 입력하는 시간을 절약하기 위해 기본값을 설정할 수 있습니다.
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

구성 파일 다운로드

이 가이드에서 사용되는 구성 파일을 다운로드하려면 Kubernetes GitHub 저장소를 방문하세요.

GKE 클러스터 만들기

첫 번째 단계는 방명록 애플리케이션과 Redis 서비스를 실행할 GKE 클러스터를 만드는 것입니다.

노드가 3개인 guestbook이라는 컨테이너 클러스터를 만듭니다.

gcloud container clusters create guestbook --num-nodes=3

다음 명령어를 사용하여 프로젝트의 클러스터를 나열하거나 단일 클러스터의 세부정보를 가져올 수 있습니다.

gcloud container clusters list
gcloud container clusters describe guestbook

1단계: Redis 마스터 설정

방명록 애플리케이션은 Redis를 사용하여 데이터를 저장합니다. 방명록 애플리케이션은 Redis 마스터 인스턴스에 데이터를 쓰고 여러 Redis 작업자(슬레이브) 인스턴스에서 데이터를 읽습니다. 첫 번째 단계는 Redis 마스터를 배포하는 것입니다.

redis-master-deployment라는 매니페스트 파일을 사용하여 Redis 마스터를 배포합니다. 이 매니페스트 파일은 단일 복제본 Redis 마스터 포드를 실행하는 배포 컨트롤러를 지정합니다.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis-master
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: k8s.gcr.io/redis:e2e  # or just image: redis
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379

Redis 마스터를 배포하려면 다음 명령어를 실행하세요.

kubectl create -f redis-master-deployment.yaml

Redis 마스터 포드가 kubectl get pods를 실행 중인지 확인합니다.

kubectl get pods
출력:
NAME                           READY     STATUS    RESTARTS   AGE
redis-master-343230949-qfvrq   1/1       Running   0          43s

이전 명령어의 출력에서 포드 이름을 복사하고 다음 명령어를 실행하여 Redis 마스터 포드의 로그를 살펴보세요.

kubectl logs -f [POD_NAME]

redis-master 서비스 만들기

방명록 애플리케이션은 데이터를 쓰기 위해 Redis 마스터와 통신해야 합니다. Redis 마스터 포드로 트래픽을 프록시하려면 서비스를 만들어야 합니다.

서비스는 논리적 포드 집합과 이 집합에 액세스하는 정책을 정의하는 Kubernetes 추상화를 의미합니다. 트래픽을 하나 이상의 포드로 프록시하는 것은 사실상 이름이 지정된 부하 분산기입니다. 서비스를 설정하면 포드 라벨에 따라 프록시할 포드를 서비스에 알립니다.

Redis 마스터의 서비스 리소스를 설명하는 redis-master-service.yaml 매니페스트 파일을 살펴보세요.

apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    app: redis
    role: master
    tier: backend
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: master
    tier: backend

이 매니페스트 파일은 라벨 선택기 집합이 포함된 redis-master라는 서비스를 만듭니다. 이러한 라벨은 이전 단계에서 배포된 라벨 집합과 일치합니다. 따라서 이 서비스는 1단계에서 만든 Redis 마스터 포드로 네트워크 트래픽을 라우팅합니다.

매니페스트의 ports 섹션은 단일 포트 매핑을 선언합니다. 이 경우, 서비스는 port: 6379의 트래픽을 지정된 selector 라벨과 일치하는 컨테이너의 targetPort: 6379로 라우팅합니다. 배포에서 사용되는 containerPort는 트래픽을 배포로 라우팅할 targetPort와 일치해야 합니다.

다음을 실행하여 Redis 마스터의 서비스를 시작합니다.

kubectl create -f redis-master-service.yaml

서비스가 만들어졌는지 확인합니다.

kubectl get service
출력:
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    42s
redis-master   10.51.242.233   <none>        6379/TCP   12s

2단계: Redis 작업자 설정

Redis 마스터가 단일 포드라도 여러 개의 Redis 작업자 복제본을 추가하는 방법으로 가용성을 높이고 트래픽 수요를 충족할 수 있습니다.

Redis 작업자 포드의 배포를 설명하는 redis-slave-deployment.yaml 매니페스트 파일을 살펴보세요.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis-slave
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: redis
        role: slave
        tier: backend
    spec:
      containers:
      - name: slave
        image: gcr.io/google_samples/gb-redisslave:v1
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access an environment variable to find the master
          # service's host, comment out the 'value: dns' line above, and
          # uncomment the line below:
          # value: env
        ports:
        - containerPort: 6379

배포는 매니페스트 파일에서 선언된 구성을 달성해야 합니다. 예를 들어 이 매니페스트 파일은 Redis 작업자에 대한 2개의 복제본을 정의합니다. 실행 중인 복제본이 없다면 배포는 컨테이너 클러스터에서 2개의 복제본을 시작합니다. 실행 중인 복제본이 셋 이상이면 지정된 구성을 충족하기 위해 일부 복제본을 종료합니다.

이 경우, 배포 객체는 2개의 복제본을 지정합니다. Redis 작업자 배포를 만들려면 다음을 실행하세요.

kubectl create -f redis-slave-deployment.yaml

포드 목록을 쿼리하여 2개의 Redis 작업자 복제본이 실행되고 있는지 확인합니다.

kubectl get pods
출력:
NAME                           READY     STATUS    RESTARTS   AGE
redis-master-343230949-qfvrq   1/1       Running   0          17m
redis-slave-132015689-dp23k    1/1       Running   0          2s
redis-slave-132015689-xq9v0    1/1       Running   0          2s

redis-slave 서비스 만들기

방명록 애플리케이션은 데이터를 읽기 위해 Redis 작업자와 통신해야 합니다. Redis 작업자 검색을 가능하게 만들려면 서비스를 설정해야 합니다. 서비스는 포드 집합에 투명한 부하 분산을 제공합니다.

redis-slave-service.yaml은 Redis 작업자의 서비스 구성을 정의합니다.

apiVersion: v1
kind: Service
metadata:
  name: redis-slave
  labels:
    app: redis
    role: slave
    tier: backend
spec:
  ports:
  - port: 6379
  selector:
    app: redis
    role: slave
    tier: backend

이 파일은 포트 6379에서 실행되는 redis-slave라는 서비스를 정의합니다. 서비스의 selector 필드는 이전 단계에서 만든 Redis 작업자 포드와 일치합니다.

다음을 실행하여 redis-slave 서비스를 만듭니다.

kubectl create -f redis-slave-service.yaml

서비스가 만들어졌는지 확인합니다.

kubectl get service
출력:
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    1m
redis-master   10.51.242.233   <none>        6379/TCP   49s
redis-slave    10.51.247.238   <none>        6379/TCP   3s

3단계: 방명록 웹 프런트엔드 설정

방명록의 Redis 저장소를 만들어 실행 중이라면 이제 방명록 웹 서버를 시작합니다. Redis 작업자와 마찬가지로 이것도 배포가 관리하는 복제된 애플리케이션입니다.

이 가이드는 단순한 PHP 프런트엔드를 사용합니다. 요청이 읽기인지 쓰기인지에 따라 Redis 작업자 서비스나 마스터 서비스와 통신하도록 구성되어 있습니다. 단순한 JSON 인터페이스를 노출하고 jQuery-Ajax 기반 UX를 제공합니다.

방명록 웹 서버에 대한 배포를 설명하는 frontend-deployment.yaml 매니페스트 파일을 살펴보세요.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google-samples/gb-frontend:v4
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below:
          # value: env
        ports:
        - containerPort: 80

방명록 웹 프런트엔드 배포를 만들려면 다음을 실행합니다.

kubectl create -f frontend-deployment.yaml

웹 프런트엔드를 식별하는 라벨 목록을 쿼리하여 3개의 복제본이 실행 중인지 확인합니다.

kubectl get pods -l app=guestbook -l tier=frontend
출력:
NAME                      READY     STATUS    RESTARTS   AGE
frontend-88237173-5p257   1/1       Running   0          40s
frontend-88237173-84036   1/1       Running   0          40s
frontend-88237173-j3rvr   1/1       Running   0          40s

위의 매니페스트 파일은 환경 변수 GET_HOSTS_FROM=dns를 지정합니다. 방명록 웹 프런트엔드 애플리케이션에 이 구성이 제공되면 호스트 이름 redis-slaveredis-master를 사용하고 DNS 확인을 수행하여 이전 단계에서 만든 각 서비스의 IP 주소를 찾습니다. 이 개념을 DNS 서비스 검색이라고 합니다.

외부 IP 주소에 프런트엔드 노출

이전 단계에서 만든 redis-slaveredis-master 서비스는 서비스의 기본 유형이 ClusterIP이므로 컨테이너 클러스터 안에서만 액세스할 수 있습니다. ClusterIP는 서비스가 가리키고 있는 포드 집합을 위한 단일 IP 주소를 제공합니다. 이 IP 주소는 클러스터 안에서만 액세스할 수 있습니다.

하지만 방명록 웹 프런트엔드 서비스는 외부에서 볼 수 있어야 합니다. 즉, 클라이언트가 컨테이너 클러스터 외부에서 서비스를 요청할 수 있어야 합니다. 그렇게 하려면 서비스 구성에서 type: LoadBalancer를 지정해야 합니다. 이 구성을 지정하는 frontend-service.yaml 매니페스트 파일은 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # if your cluster supports it, uncomment the following to automatically create
  # an external load-balanced IP for the frontend service.
  # type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: guestbook
    tier: frontend

frontend 서비스가 만들어지면 GKE는 부하 분산기와 외부 IP 주소를 만듭니다. 이러한 리소스는 청구 대상입니다. ports 섹션의 포트 선언은 port: 80targetPort가 지정되지 않았다고 지정합니다. targetPort 속성을 생략하면 기본적으로 port 필드의 값이 사용됩니다. 이 경우, 이 서비스는 포트 80의 외부 트래픽을 frontend 배포의 컨테이너 포트 80으로 라우팅합니다.

서비스를 생성하려면 우선 frontend-service.yaml 파일에서 다음 줄의 주석을 해제합니다.

type: LoadBalancer

그러고 나서 다음을 실행하여 서비스를 만듭니다.

kubectl create -f frontend-service.yaml

4단계: 방명록 웹사이트 방문

방명록 서비스에 액세스하려면 다음 명령어를 실행하여 방금 설정한 서비스의 외부 IP 주소를 찾아야 합니다.

kubectl get service frontend
출력:
NAME       CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
frontend   10.51.242.136   109.197.92.229     80:32372/TCP   1m

EXTERNAL-IP 열에서 IP 주소를 복사하고 브라우저에서 페이지를 로드합니다.

GKE에서 실행되는 방명록

수고하셨습니다. 몇 가지 방명록 항목을 추가해 보세요.

5단계: 웹 프런트엔드 확장

방명록 앱이 실행된 지 어느 정도 지나 갑자기 유명해졌다고 가정해 보세요. 프런트엔드에 웹 서버를 추가하는 것이 좋겠다고 결정합니다. 서버가 배포 컨트롤러를 사용하는 서비스로 정의되어 있으므로 이 작업은 쉽게 할 수 있습니다.

다음을 실행하여 frontend 포드 수를 5개로 확장합니다.

kubectl scale deployment frontend --replicas=5

이제 5개의 복제본이 실행되어야 한다고 지정하도록 배포의 구성이 업데이트됩니다. 배포는 이에 맞춰 실행 중인 포드 수를 조정합니다. 확인하려면 다음 명령어를 실행하세요.

kubectl get pods
출력:
NAME                           READY     STATUS    RESTARTS   AGE
frontend-88237173-3s3sc        1/1       Running   0          1s
frontend-88237173-twgvn        1/1       Running   0          1s
frontend-88237173-5p257        1/1       Running   0          23m
frontend-88237173-84036        1/1       Running   0          23m
frontend-88237173-j3rvr        1/1       Running   0          23m
redis-master-343230949-qfvrq   1/1       Running   0          54m
redis-slave-132015689-dp23k    1/1       Running   0          37m
redis-slave-132015689-xq9v0    1/1       Running   0          37m

다시 잘 알려지지 않은 사이트가 되면 같은 방법으로 웹 서버 포드의 수를 줄일 수 있습니다.

삭제

이 가이드에서 사용한 리소스 비용이 Google Cloud Platform 계정에 청구되지 않도록 하는 방법은 다음과 같습니다.

6단계: 삭제

이 가이드를 완료한 후에는 다음 단계에 따라 자신의 계정에 원치 않는 비용이 발생하지 않도록 다음 리소스를 삭제합니다.

  1. 서비스 삭제: 이 단계는 frontend 서비스를 위해 만든 Cloud 부하 분산기의 할당을 취소합니다.

    kubectl delete service frontend

  2. frontend 서비스를 위해 프로비저닝된 부하 분산기가 삭제될 때까지 대기: kubectl delete를 실행하면 부하 분산기가 백그라운드에서 비동기식으로 삭제됩니다. 다음 명령어 출력을 확인하여 부하 분산기가 삭제될 때까지 기다립니다.

    gcloud compute forwarding-rules list

  3. 컨테이너 클러스터 삭제: 이 단계에서는 컴퓨팅 인스턴스, 디스크, 네트워크 리소스와 같이 컨테이너 클러스터를 구성하는 리소스를 삭제합니다.

    gcloud container clusters delete guestbook

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine 가이드