Kubernetes Multi-Tier Architecture

김민형·2022년 10월 15일
0

GCP - Infra

목록 보기
7/14

GCP에서 GKE를 구성하여 앱을 배포해볼 것이다.
(개인적으로 클러스터 구축하기가 너무 편하다..)

아키텍처

간단하게 웹페이지 방문 횟수가 Count되어 뜨는 app을 배포할 것이고 DB는 redis를 사용할 것이다.
Flask 애플리케이션은 Redis를 사용하여 데이터를 저장한다.
Redis Master에 데이터를 쓰고 여러 Redis Slave에서 데이터를 읽는 구조.

Backend

redis-master.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-master
  namespace: backend
spec:
  selector:
    matchLabels:
      app: redis
      role: master
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: k8s.gcr.io/redis:e2e
        ports:
        - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis-master
  namespace: backend
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
  labels:
    app: redis
    role: master
    tier: backend
spec:
  type: LoadBalancer
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: master
    tier: backend

redis가 배포될 backend namespace가 따로 생성되고 Service를 통해 Internal LB가 생성될 것이다.
redis svc의 external-ip가 나오면 이 external-ip를 밑에 redis-slave.yaml 안에 입력해서 redis-slave들과의 connection을 만들어줘야 한다.

redis-slave.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-slave
  namespace: backend
spec:
  selector:
    matchLabels:
      app: redis
      role: slave
      tier: backend
  replicas: 3
  template:
    metadata:
      labels:
        app: redis
        role: slave
        tier: backend
    spec:
      containers:
      - name: slave
        image: gcr.io/google_samples/gb-redisslave:v1
        env:
        - name: GET_HOSTS_FROM
          value: "<redis EXTERNAL-IP>"
        ports:
        - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis-slave
  namespace: backend
  labels:
    app: redis
    role: slave
    tier: backend
spec:
  ports:
  - port: 6379
  selector:
    app: redis
    role: slave
    tier: backend

redis master 하나와 slave 3개 모두 배포된 것 확인

Frontend

app.py

from __future__ import unicode_literals
__author__ = "Anil Saravade"

import time
import redis
from flask import Flask
import os

app = Flask(__name__)
cache = redis.Redis(host=os.getenv('REDIS_SERVER'), port=6379)


def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)


@app.route('/')
def hit():
    count = get_hit_count()
    return 'Hello, you have %i visitors on this page' % int(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

requirements.txt

flask
redis

이제 이 앱을 yaml로 쿠버네티스에 배포하기 위해 Dockerization할 것이다.
여기선 GCP에서 지원하는 이미지 저장소인 Container Registry로 올릴 것이다.

Dockerfile


FROM python:2-alpine
MAINTAINER mhkim

WORKDIR /usr/src/app

COPY ./requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY ./app.py .

이미지 생성

docker build . -t <지정할 이미지 이름>:v1
docker tag <지정할 이미지 이름>:v1 gcr.io/<프로젝트 ID>/<지정할 이미지 이름>:v1
docker push gcr.io/<프로젝트 ID>/<지정할 이미지 이름>:v1

gcr.io 즉 Google Container Registry에 v1이라는 태그가 붙은 내 이미지가 생긴 것 확인.

front-app.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: frontend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-deployment
  namespace: frontend
  labels:
    app: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: <gcr 이미지 이름>
        ports:
        - containerPort: 5000
        env:
        - name: FLASK_APP
          value: "app.py"
        - name: REDIS_SERVER
          value: "<redis EXTERNAL-IP>"
        command: ["sh"]
        args: ["-c","flask run --host=0.0.0.0"]
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-public
  namespace: frontend
spec:
  type: LoadBalancer
  ports:
  - port: 80
    protocol: TCP
    targetPort: 5000
  selector:
      app: frontend

여기서 gcr 이미지 이름이란 내가 생성한 이미지를 아래처럼 그대로 복사해서 가져오면 된다.

콘솔에서 확인해보면 내부, 외부 LB 두개가 생성된 것을 확인할 수 있고 외부 LB의 IP로 접속해보면 배포한 app이 잘 뜨는 것을 확인할 수 있다.

새로고침을 몇 번 누르면 2 3 4 점점 visitor의 숫자가 늘어가는 것을 볼 수 있다.

[Kubernetes Multi-Tier Architecture 참고]
https://blog.searce.com/multi-tier-application-using-multiple-kubernetes-clusters-8df4c940576e

profile
Solutions Architect (rlaalsgud97@gmail.com)

0개의 댓글