[GKE] 방명록 애플리케이션 만들기

Jade·2021년 2월 28일
0

목표

  • GKE를 사용하여 다중 계층 웹 어플리케이션 빌드하기
  • 해당 애플리케이션은 방문자가 로그에 텍스트를 입력하고 최근에 기록된 몇 개 항목을 볼 수 있는 방명록이다.

학습 내용

  • 부하 분산기를 사용하여 외부 IP에서 방명록 웹 서비스 설정하기
  • 단일 마스터 및 여러 복제본으로 구성된 Redis 클러스터 실행하기
  • GKE 중요 개념 학습(선언적 구성, 디플로이먼트, 서비스)

사전 설정

  • Kubernetes Engine API 사용 설정
  • 테스트를 위한 프로젝트 선택
  • gcloud, kubectl 설치 (Cloud Shell, gcloud SDK의 경우 설치 불필요)

gcloud 명령줄 도구 설정

  • 프로젝트 ID와 Compute Engine 영역 옵션의 입력 시간을 절약하기 위해 기본값 세팅
gcloud config set project [project-id]
gcloud config set compute/zone [compute-zone]

GKE 클러스터 생성

  • 방명록 애플리케이션과 Redis 서비스를 실행할 GKE 클러스터 생성
    • 클러스터명: guestbook
    • 노드수: 4개
gcloud container clusters create guestbook --num-nodes=4

  • 프로젝트에서 실행중인 클러스터 나열하기
gcloud container clusters list
gcloud container clusters describe guestbook

Redis 리더 설정

방명록은 Redis를 사용하여 데이터를 저장한다.

애플리케이션은 Redis 리더 인스턴스에 데이터를 쓰고, 여러 Redis 팔로워 인스턴스에서 읽게 된다.

Redis 리더 디플로이먼트 생성

쿠버네티스의 디플로이먼트(Deployment)란, 컨테이너 애플리케이션을 배포하고 관리하는 역할을 담당한다. 디플로이먼트를 사용하면 레플리카셋의 리비전 관리뿐만 아니라 다양한 포드의 롤링 업데이트 정책을 사용할 수 있다는 장점이 있다.

  • 다음 명령어를 실행하여 샘플 매니페스트 클론
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/guestbook
git checkout abbb383

GCP github에서 샘플 매니페스트 파일 클론, abbb383로 브랜치 전환

  • 디플로이먼트 생성 전 guestbook/redis-leader-deployment.yaml 파일 내용 확인

    이 매니페스트 파일은 단일 복제본 Redis 리더 Pod를 실행하는 디플로이먼트를 지정한다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-leader
  labels:
    app: redis
    role: leader
    tier: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      containers:
      - name: leader
        image: "docker.io/redis:6.0.5"
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
  • .metadata.name 필드에 따라 redis-leader라는 이름으로 디플로이먼트가 생성된다.
  • .spec.replicas 필드에 따라 디플로이먼트는 1개의 레플리카 파드를 생성한다.
  • .spec.selector 필드에 따라 디플로이먼트가 관리할 파드를 찾는 방법을 정의한다. 이 사례에서는 파드 템플리엣 정의된 레이블(app: redis)를 선택한다.
  • template 필드에는 다음 하위 필드가 포함되어 있다.
    • .metadata.labels 필드를 사용해서 app: redis, role: leader, tier: backend 라는 레이블을 붙인다.
    • .metadata.spec 필드를 사용해서 도커 허브의 redis:6.0.5 버전 이미지를 실행하는 leader 라는 컨테이너 1개를 실행한다. 이 컨테이너 리소스 스펙은 cpu 100m, memory 100Mi이며, 6379번 포트를 사용한다.
  • 다음 명령어를 실행하여 Redis 리더 디플로이먼트
kubectl apply -f redis-leader-deployment.yaml

  • 다음 명령어를 실행하여 실행중인 Pod 확인
kubectl get pods

  • 다음 명령어를 실행하여 Redis 리더 파드의 로그 확인
kubectl logs deployment/redis-leader

Redis 리더 서비스 생성

쿠버네티스의 서비스(Service)란, 동일한 서비스를 제공하는 파드 그룹에 지속적인 단일 접점이 필요할 때 생성하는 리소스다. 각 서비스는 서비스가 존재하는 동안 절대 바뀌지 않는 IP주소와 포트가 있으며, 클라이언트는 해당 IP와 포트로 접속한 다음 해당 서비스를 지원하는 파드 중 하나로 연결된다.

방명록 애플리케이션은 데이터를 쓰기 위해 Redis 리더와의 통신이 필요하다. 본 테스트에서는 서비스를 생성하여 트래픽을 리더 Pod로 프록시 처리 할 것이다.

  • Redis 리더의 서비스 리소스를 설명하는 guestbook/redis-leader-service.yaml 파일 내용 확인
apiVersion: v1
kind: Service
metadata:
  name: redis-leader
  labels:
    app: redis
    role: leader
    tier: backend
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: leader
    tier: backend
  • .metadata.name 필드에 따라 redis-leader라는 이름의 서비스가 생성된다.
  • .spec.ports 필드는 단일 포트 매핑을 선언한다. 이 사례에서는 selector의 레이블과 일치하는 컨테이너 대상 포트인 6379번으로 트래픽을 라우팅한다.
  • 다음 명령어를 실행하여 Redis 서비스 생성
kubectl apply -f redis-leader-service.yaml

  • 다음 명령어를 실행하여 서비스 생성 여부 확인
kubectl get service

Redis 팔로워 설정

Redis 리더가 단일 Pod라도 복제본인 팔로워를 여러 개 추가하면 가용성을 높이고 트래픽 수요를 충족할 수 있다.

  • Redis 팔로워 Pod의 디플로이먼트를 설명하는 guestbook/redis-follower-deployment.yaml 내용 확인
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-follower
  labels:
    app: redis
    role: follower
    tier: backend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      containers:
      - name: follower
        image: gcr.io/google_samples/gb-redis-follower:v2
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
  • 다음 명령어를 실행하여 Redis 팔로워 디플로이먼트 생성
kubectl apply -f redis-follower-deployment.yaml

  • 다음 명령어를 실행하여 현재 프로젝트에서 실행중인 Pod 확인
kubectl get pods

  • .spec.replicas 필드 설정에 따라 2개의 팔로워 파드가 생성되었다.

Redis 팔로워 서비스 생성

방명록 애플리케이션은 데이터를 읽기 위해 Redis 팔로워와 통신해야 한다. Redis 팔로워를 검색할 수 있도록 하려면 추가적으로 다른 서비스를 생성해야 한다.

  • guestbook/redis-follower-service.yaml 파일을 확인하여 Redis 팔로워의 서비스 구성 내용 확인
apiVersion: v1
kind: Service
metadata:
  name: redis-follower
  labels:
    app: redis
    role: follower
    tier: backend
spec:
  ports:
    # the port that this service should serve on
  - port: 6379
  selector:
    app: redis
    role: follower
    tier: backend
  • 6370 포트에서 실행되는 서비스 redis-follower를 정의하는 내용.
  • .spec.selector 필드는 이전 단계에서 만든 Redis 팔로워 Pod와 일치한다는 것을 알 수 있다.
  • 다음 명령어를 실행하여 redis-follower 서비스 생성
kubectl apply -f redis-follower-service.yaml

  • 다음 명령어를 실행하여 현재 프로젝트에서 실행중인 서비스 확인
kubectl get service

방명록 웹 프론트엔드 설정

이전 내용에 따라 현재 방명록의 Redis 스토리지가 실행되고 있으므로, 방명록 웹 서버를 생성할 차례이다. Redis 팔로워와 마찬가지로 프론트엔드는 디플로이먼트를 사용하여 생성된다.
방명록 앱은 PHP를 사용하며, 요청이 읽기인지 쓰기인지에 따라 리더 또는 팔로워 서비스와 통신하도록 구성된다.

  • 웹 서버의 디플로이먼트를 설명하는 guestbook/frontend-deployment.yaml 파일 내용 확인
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
        app: guestbook
        tier: frontend
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v5
        env:
        - name: GET_HOSTS_FROM
          value: "dns"
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 80
  • 환경 변수 GET_HOSTS_FROM=dns를 지정함으로써, 프론트엔드 애플리케이션은 redis-follower 및 redis-leader를 사용하여 DNS 조회를 수행하게 된다.
  • 다음 명령어를 실행하여 방명록 웹 프론트엔드 디플로이먼트 생성
kubectl apply -f frontend-deployment.yaml

  • 다음 명령어를 실행하여 웹 프론트엔드를 식별하는 레이블 목록을 쿼리하여 3개의 복제본이 실행중인지 확인
kubectl get pods -l app=guestbook -l tier=frontend

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

서비스의 기본 유형이 Cluster IP이므로, 이전 단계에서 만든 두 개의 서비스는 현재 GKE 클러스터 내에서만 액세스 할 수 있다.

하지만 방명록 웹 프론트엔드는 클라이언트가 GKE 클러스터 외부에서 서비스를 요청할 수 있어야 하기 때문에 LoadBalancer, NodePort를 지정해야 한다. 이 예시에서는 LoadBalancer를 사용한다.

  • guestbook/frontend-service.yaml 파일 내용 확인
apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  type: LoadBalancer
  ports:
    # the port that this service should serve on
  - port: 80
  selector:
    app: guestbook
    tier: frontend
  • .metadata.name 필드에 따라 frontend라는 서비스가 생성되면서 GKE는 로드밸런서와 외부 IP 주소를 만든다.
  • .spec.ports 필드에는 80 포트를 지정하며, targetPort는 생략한다. targetPort를 생략하는 경우 기본적으로 port 필드 값이 사용되므로, 이 사례에서도 80 포트로 들어오는 외부 트래픽을 컨테이너 포트 80으로 라우팅 한다.
  • 다음 명령어를 실행하여 서비스 생성
kubectl apply -f frontend-service.yaml

방명록 웹사이트 방문

  • 다음 명령어를 실행하여 설정한 서비스의 외부 찾기
kubectl get servicefrontend

  • 출력된 외부 IP를 복사하여 브라우저에서 페이지 로드

  • 테스트 메시지 입력 후 Submit 버튼을 누르면 프론트엔드에 메시지가 표시되는 것을 확인할 수 있다.

    • 이 메시지는 이전에 만든 서비스를 통해 데이터가 Redis에 성공적으로 추가되었음을 나타낸다.

웹 프론트엔드 서비스 확장

만약 방명록 서비스가 유명해졌다는 가정하에 프론트엔드 웹 서버를 추가하고 싶다면, 손쉽게 서비스를 확장할 수 있다.

  • 다음 명령어를 실행하여 frontend Pod의 수를 5개로 확장
kubectl scale deployment frontend --replicas=5

  • 다음 명령어를 실행하여 현재 실행되고 있는 Pod 목록 확인
kubectl get pods

5개의 Pod가 실행 중인 것을 알 수 있다

리소스 삭제

이 테스트에 사용된 리소스 비용이 청구되지 않도록 하려면 개별 리소스를 삭제해야 한다.

서비스 삭제

kubectl delete service frontend

frontend 서비스에 프로비저닝된 로드밸런서가 삭제되었는지 확인

gcloud compute forwarding-rules list

GKE 클러스터 삭제

gcloud container clusters delete guestbook

참고문서

GKE 가이드: Redis 및 PHP로 방명록 만들기

profile
우당탕탕 좌충우돌 인프라 여행기

0개의 댓글