EKS 클러스터에 간단한 Flask 어플리케이션 배포하기
서버 로그 수집에 Fluent Bit 를 도입할 수 있을지 탐색할 계획입니다. 현재 소속된 팀의 서버 개발자 분들은 Amazon EKS 로 Kubernetes 클러스터를 운영하고 있습니다. 그래서 일단 Kubernetes 에 대해 어느정도 이해가 필요할 것 같아서 직접 써보며 익혀보려고 합니다.
EKS 클러스터 생성
Getting Started with eksctl 문서를 참고하여 Homebrew 로 eksctl 을 설치합니다. 그러면 kubectl 과 aws-iam-authenticator 도 설치된다고 합니다. AWS CLI 는 예전에 설치했었습니다.
brew tap weaveworks/tap
brew install weaveworks/tap/eksctl
eksctl 명령어로 EKS 클러스터와 Managed Node Group 을 생성합니다. 마침 re:invent 때 Amazon EKS on AWS Fargate 가 GA 로 발표 되었기에 관심이 갔는데, 아직 서울 리전은 지원하지 않습니다. 그러니 Cluster with Linux-only workloads 탭의 명령어를 적당히 바꿔서 사용합니다.
eksctl create cluster \
--name kubernetes-study \
--version 1.14 \
--region ap-northeast-2 \
--nodegroup-name flask \
--node-type t3.medium \
--nodes 2 \
--nodes-min 2 \
--nodes-max 2 \
--managed
Flask 어플리케이션 준비
A Minimal Application 문서를 참고하여 정말 간단한 어플리케이션을 app.py
로 준비합니다.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
Flask 로 app.py
를 실행하기 위한 Dockerfile 을 준비한 뒤 build 하여 Image 를 준비합니다.
FROM python:3.7.5-slim
RUN pip install flask==1.1.1
WORKDIR /app
ADD . /app
ENV FLASK_APP app.py
ENTRYPOINT ["flask", "run", "--host=0.0.0.0"]
docker build . -t kubernetes-study
Docker Image 를 관리할 ECR Repository 를 생성합니다.
- Repository name : kubernetes-study
- Tag immutability : Disabled
- Scan on push : Disabled
Step 1: Authenticate Docker to your Default Registry 문서를 참고하여 aws ecr get-login
명령어를 실행한 뒤, 획득한 docker login
명령어를 실행하여 인증합니다. 그 다음 Pushing an Image 문서를 참고하여 push 할 Image ID 를 확인한 뒤에 적절한 tag 를 달고 ECR Repository 에 push 합니다.
docker tag <image_id> <aws_account_id>.dkr.ecr.ap-northeast-2.amazonaws.com/kubernetes-study
docker push <aws_account_id>.dkr.ecr.ap-northeast-2.amazonaws.com/kubernetes-study
Kubernetes Objects 생성
Learning Kubernetes on EKS by Doing 연재글의 Part 2 와 Part 3 글을 참고하여 Deployment 와 Service 를 정의하는 YAML 파일을 작성합니다. Service 를 만들 때 Classic Load Balancer 를 사용합니다. 작성한 뒤 kubectl 명령어를 실행해서 적용합니다. (<aws_account_id> 부분을 AWS Account ID 로 교체)
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app
labels:
name: flask-app
spec:
replicas: 2
selector:
matchLabels:
name: flask-app
template:
metadata:
name: flask-app
labels:
name: flask-app
spec:
containers:
- name: flask-app
image: <aws_account_id>.dkr.ecr.ap-northeast-2.amazonaws.com/kubernetes-study:latest
ports:
- containerPort: 5000
resources:
requests:
memory: 256Mi
limits:
memory: 512Mi
kubectl apply -f deployment.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
flask-app-cb674b795-nbf87 1/1 Running 0 38s
flask-app-cb674b795-sxnw4 1/1 Running 0 38s
apiVersion: v1
kind: Service
metadata:
name: flask-app
spec:
type: LoadBalancer
selector:
name: flask-app
ports:
- protocol: TCP
port: 5000
targetPort: 5000
kubectl apply -f service.yaml
kubectl get services
명령어를 실행하면 NAME 이 flask-app
이고 TYPE 이 LoadBalancer
인 Object 가 생성된 것을 확인할 수 있습니다. 그 Object 의 EXTERNAL-IP 값을 복사한 뒤에 앞에 http:// 을 붙이고 뒤에 :5000 port 를 지정해서 브라우저로 접속해보면, Flask 코드에 적은대로 Hello, World!
가 응답으로 내려오는 것을 확인할 수 있습니다.