쿠버네티스 백엔드 서버 배포

pipi·2023년 8월 21일
0

인프라

목록 보기
10/12

라즈베리파이 64bit에서 k3s를 사용한 환경이며, 공유기를 통해 ip를 할당받은 상황이다.

  1. nest js, mongoDB를 사용했으며, 각각 docker 이미지를 생성한다.
  2. 쿠버네티스(k3s)에서 해당 이미지를 pod로 만들어 띄운다(deployment, service 활용)
  3. ingress(로드밸런서 사용)을 통해, 공유기 ip를 할당받고, 외부에서 백엔드 서버로 접근한다.

Docker 이미지 생성

Dockerfile 생성

FROM node:16-alpine
WORKDIR /usr/src/app

COPY . .
RUN npm install
RUN npm run build

CMD ["npm", "start"]

.dockerignore 생성

.git
Dockerfile
node_modules
dist

빌드 + 원격 업로드

라즈베리파이는 arm64인데, 도커를 빌드한 컴퓨터는 amd64이기에, 해당 이미지를 라파이에서 빌드하면 에러가 뜬다. 그렇기에 도커를 빌드할때 플랫폼을 arm64로 해줘야한다. 안그러면 에러뜬다 ㅎㅎ

docker build . --platform linux/arm64/v8 -t nestjs_image_arm64
docker tag nestjs_image pipisebastian/nestjs_image_arm64
docker push pipisebastian/nestjs_image_arm64

빌드된 이미지가 로컬에서 잘 되는지 확인가능하다.(생략 가능하지만.. 해보는걸 추천합니다..)
docker run -e MONGODB_URL=mongodb://127.0.0.1:27017 -e JWT_SECRET_KEY="key" pipisebastian/nestjs_image_test
+) nestjs로 만든 서버는 환경변수로 mongodb 주소와, jwt key를 넣어줘야 제대로 동작한다.


DB

백엔드 서버와 연결할 mongoDB를 띄운다. 테스트를 위해 볼륨 타입은 hostPath를 사용한다.
hostPath는 각 노드의 로컬 파일시스템을 사용하기에, 각 노드마다 볼륨이 존재한다. 추후 다른방법을 공부해볼 예정이다.

db.yaml 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
        - name: mongodb
          image: mongo:4.4.8
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: mongodb-volume
              mountPath: /data/db
      volumes:
        - name: mongodb-volume
          hostPath:
            path: /data/db
---
apiVersion: v1
kind: Service
metadata:
  name: mongodb-service
spec:
  ports:
    - port: 27017
      targetPort: 27017
  selector:
    app: mongodb

MongoDB 컨테이너는 기본적으로 데이터를 /data/db 경로에 저장하기에, 해당 데이터를 가져왔고,
저장되는 로컬 디렉토리도 /data/db 경로 에 지정해줬다.(디렉토리 만들었음)

kubectl apply -f db.yaml
kuebectl get svc

curl [몽고db service ip:27017] 했을때 잘 나오면 된다.


BackEnd

back.yaml 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nest-app
  labels:
    app: nest-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nest-app
  template:
    metadata:
      labels:
        app: nest-app
    spec:
      containers:
        - name: nest-app
          image: pipisebastian/nestjs_image_arm64
          env:
            - name: MONGODB_URL
              value: "mongodb://10.43.128.49:27017"
            - name: JWT_SECRET_KEY
              value: "key"
          ports:
            - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: nest-app
  labels:
    app: nest-app
spec:
  selector:
    app: nest-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000

kubectl apply -f back.yaml
kubectl logs -f [백엔드 pod 이름] 으로 로그를 확인해보자. 잘된다!

백엔드 서비스 ip로 접근해서, 잘되는지 확인해봅시다
curl [백엔드 pod 이름]/docs <- 이건 각자 만든 api로 테스트해보면 됩니다!


ingress 파일 수정

ingress로 외부접근을 확인해보자. 현재는 모두 내부, cluster Ip다.
라즈베리파이에서 ingress구축을 정리한 링크다. 해당 링크를 참고해, ingress controller등 환경이 구축된 상황이라 가정하겠다!

ingress.yaml 생성

우리가 총 2개의 애플리케이션을 만들기에, 각각의 백엔드 서버가 필요하다.
그래서 /app1/login, /app2/login 와 같이 라우팅경로로 접근할 예정이기에, 다음과 같이 ingress 파일을 작성해준다.
그러나 현재 백엔드서버는 1개만 띄워놓은 상태라, 임시로 다른 서비스를 넣었다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nest-app
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2

spec:
  ingressClassName: nginx
  rules:
   - http:
      paths:
      - path: /app(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: nest-app
            port:
              number: 80

      - path: /blue
        pathType: Prefix
        backend:
          service:
            name: nginx-deploy-blue
            port:
              number: 80

kubectl apply -f ingress.yaml


결과 확인

curl 192.168.123.130/app/docs
curl 192.168.123.130/app/users
curl 192.168.123.130/blue

외부접근도 잘된다.

1개의 댓글

comment-user-thumbnail
2023년 8월 22일

오옹 멋있어요~~!! 굿굿

답글 달기

관련 채용 정보