본문 바로가기

server/k8s

[k8s] fastapi + helm (minikube에 올려보기)

 

helm 공부하기 위해 간단하게 fastapi를 minikube에 올리는 예제를 해보았다.

이번 포스팅에서는 (1)로컬에서 docker를 실행해보고, (2) minikube에서 실행시켜 보고, (3) 마지막으로 helm으로 실행시켜 보았다.

내용이 꽤 길다.

 

해당 포스팅의 모든 소스는 github에 올려두었다.

https://github.com/uiandwe/fastapi_k8s


1. 로컬에서 docker를 실행

k8s에 올리기 위해 위해 docker부터 만들어야 한다.

 

fastapi 서버 부분이다. 간단하게 호출히 리턴하도록만 만들었다.

app/main.py

from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

 

서버 구동에 필요한 패키지들

app/requirements.txt

fastapi
uvicorn

 

도커 부분이다. python 이미지에 fastapi 파일를 복사하고 서버를 실행한다. 포트는 8000번이다.

Dockerfile

FROM python:3.7

COPY ./app /app
WORKDIR /app

RUN pip install -r requirements.txt

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

 

 

도커 빌드 및 docker를 실행해보자. 잘 동작한다.

> docker build -t fastapi:v.1 .
> docer run -p 8000:8000  fastapi:v.1

2. minikube

다음으로 minikube에서 실행해보도록 하자. (minikube의 설치는..각자 알아서..)

 

minikube 시작

minikube start

 

 

k8s에서 사용할수 있도록 기본적인 spec yaml을 작성해보자. deployment와 service부분만 작성했다.

아래 코드를 보면 2개의 서버를 띄우도록 했다. (replicas 2), 2개를 라우팅해야하므로, 로드밸런스로 service를 설정했다.

fastapi.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fast-api-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: fast-api
  template:
    metadata:
      labels:
        app: fast-api
    spec:
      containers:
      - name: fast-api
        image: fastapi:v1
        resources:
          limits:
            memory: "256Mi"
            cpu: "500m"
        ports:
        - containerPort: 8000
---

apiVersion: v1
kind: Service
metadata:
  name: fast-api-service
spec:
  selector:
    app: fast-api
  ports:
  - port: 8000
    targetPort: 8000
  type: LoadBalancer

 

바로 실행시켜 보자.

> kubectl apply -f fastapi.yaml
deployment.apps/fast-api-deployment created
service/fast-api-service created

 

k9s에서 아래와 같이 정상작동을 확인했다.

pod가 두개 생성되나. 앞써 replicas: 2로 설정했기 때문이다.

두개의 pod와 통신해야 하므로 LoadBalancer를 통해서 외부와 통신하게 된다. LoadBalancer는 service에 설정되어 있다.

 

 

 


혹시나 실행시 아래와 같이 imagePull 에러가 난다면, minikube에서 local docker를 인식못해서 이미지가 어디있지를 몰라서 실행에 에러가 난것이다.

 

해결법은 minikube와 현재 나의 docker host와 연결하면 된다.

minikube docker-env를 실행해보면 docker 셋팅을 볼수 있다. 해당 셋팅을 minikube에 셋팅해 주면 된다.

$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://127.0.0.1:59779"
export DOCKER_CERT_PATH="/Users/emart/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"

# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)

$ eval $(minikube -p minikube docker-env)

 

혹시나 docker image 명령어로 원하는 이미지가 없다면 docker 빌드를 해야 한다. 셋팅만 되었을뿐 아직 minikube에는 image가 등록되지 않았을 수 있다.

(추가로 docker image시 기존에 안보이던 image들도 보일수 있다. minikube안에서만 사용하던 이미지들이 통합되서 보이기 때문이다)


 

 

minikube에서 service를 확인해보면 로드밸런스가 설정되어 잇지만, external이 아직 pending 으로 되어 있는걸 볼수 있다.

$ kubectl get service

 

아직 pending으로 나오는것은 minikube에서 로드 밸런서를 지원하는 클라우드 공급자의 경우에는 서비스에 접근할 수 있도록 외부 IP 주소가 프로비저닝 해야 한다. (아직 연결 전이라는 뜻)

minikube에서 LoadBalancer타입은 minikube service 명령어를 통해서 해당 서비스를 접근할 수 있게 한다.

 

$ minikube service fast-api-service


 

다른 pod에서 해당 fastapi로 통신하려 한다면 다음과 같이 하면 된다.

먼저 curl를 테스트할 새로운 pod를 생성한다.

kubectl run mycurlpod --image=curlimages/curl -i --tty -- sh

 

> curl http://192.168.49.2:31675

 

 

service name 으로 통신한다면 다음과 같다.

> curl http://fast-api-service:8000

curl pod 삭제

> kubectl delete pod mycurlpod

 


 

 

fastapi 리소스 삭제

설정 파일로 지우기

> kubectl delete -f ./fastapi.yaml

 

커맨드로 각각 지우고 싶다면 다음과 같다. (로드밸런스와 디플로이먼트를 지워준다)

kubectl delete service fast-api-service
kubectl delete deployment fast-api-deployment

 

 

 

3. helm 으로 minikube 배포하기

 

helm create 명령을 사용해서 기본적인 헬름 템플릿을 만들어준다. fastapi_chart라는 이름으로 만들었다

> helm create fastapi_chart

 

그중 value.yaml을 다음과 같이 수정했다.

1) image를 로컬에 생성한 이미지 이름과 tag로 수정했다. 이미지:버전 => fastapi:v.1

2)리소스 부분의 cpu와 메모리를 적당히 수정했다.

replicaCount: 1

image:
  repository: fastapi
  pullPolicy: IfNotPresent
  tag: v.1

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

serviceAccount:
  create: true
  annotations: {}
  name: fastapi-service

podAnnotations: {}

podSecurityContext: {}

securityContext: {}

service:
  type: LoadBalancer
  port: 8000


ingress:
  enabled: false
  className: ""
  annotations: {}
  hosts:
    - host: fastapi-helm.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []

resources: 
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

 

 

해당 헬름을 먼저 insert을 통해 minikube에 적용한다.

helm install fastapi-chart  fastapi_chart  --values fastapi_chart/values.yaml

 

pod가 정상적으로 올라온것을 볼수 있다.

 

k9s로 확인해보면 ready가 false로 표기되고 있다.(혹시 port를 잘못 썼는지 확인해보자..- 나의 경우 9110으로 되어 있었다..)

 

 

외부 확인하기 위해 서비스를 프로비저닝 한다.

> minikube service fastapi-chart

 

헬름으로 리소스 삭제

>helm uninstall fastapi-chart

 

 

 

 

 

 

참고

https://kubernetes.io/ko/docs/tutorials/hello-minikube/

 

Hello Minikube

이 튜토리얼에서는 Minikube와 Katacoda를 이용하여 쿠버네티스에서 샘플 애플리케이션을 어떻게 실행하는지 살펴본다. Katacode는 무료로 브라우저에서 쿠버네티스 환경을 제공한다. 참고: 로컬에서

kubernetes.io

https://helm.sh/docs/chart_template_guide/getting_started/

 

Getting Started

A quick guide on Chart templates.

helm.sh

 

'server > k8s' 카테고리의 다른 글

[k8s] argocd (minikube에 올려보기)  (0) 2024.03.08