[프로젝트 수행] k8s & CI/CD 환경 구축

Nam_JU·2022년 11월 16일
0

WebRTC-Project

목록 보기
6/18
post-thumbnail

k8s 환경세팅

  • 서버 컴퓨터에 ubuntu/ master1, worker3을 구성
  • CNI 설정 완료
  • Nexus, Promethus, Grafana 구성 완료 - 아직 K8S와 연동되어있지는 않음


Front Server, Signarling Server Deploy yaml 작성


  • k8s 환경이 구축된 서버에서 테스트 해보기 위해 Deloy.yaml코드가 필요하다. 임시 테스트된 코드를 도커 이미지로 만들어서 Deploy yaml을 만들어 테스트 해보기로함

Signarling Server Deploy yaml

apiVersion: apps/v1
kind: Deployment 
metadata:
  name: python-deployment 
  labels:
    app: pythonserver 
spec:
  replicas: 3 
  selector:
    matchLabels:
      app: pythonserver
  template:
    metadata:
      labels:
        app: pythonserver 
    spec:
      containers:
      - name: pythonserver-container 
        image: roheejae/back:1.0
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: pythonserver-svc
  labels:
    app: pythonserver
spec:
  selector:
    app: pythonserver
  ports:
  - port: 8080
    targetPort: 8080
externalIPs:
  - 192.168.56.102

Front Server Deploy yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: reactweb
  name: reactweb
spec:
  replicas: 3
  selector:
    matchLabels:
      app: reactweb
  template:
    metadata:
      labels:
        app: reactweb
    spec:
      containers:
      - name: reactweb-container 
        image: roheejae/front:1.0
        ports:
        - containerPort: 3000
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: reactfront-svc
spec:
  type: NodePort
  selector:
    app: reactweb
  ports:
  - port: 3000
    targetPort: 3000
	externalIPs:
	- 192.168.56.111

에러 이슈

  • 위의 deploy를 보면 replica를 3씩 지정했는데 이부분에서 문제가 터졌다.
  • webRTC는 소켓 통신이 계속 맺어져야 시그너링이 된다
    그러나 replica를 3으로 지정해주면서 서버에서의 socket connection 이슈 ⇒ 다수의 Deployment 에 커넥션을 요청 ⇒ 각 Pod 들이 커넥션에 대한 공부를 공유하지 못함 ⇒ 지속적인 Connection 요청으로 인한 에러가 나타났다

  • 에러내용
10.100.235.128 - - [18/Nov/2022 03:21:52] "POST /socket.io/?EIO=4&transport=polling&t=OI8mSaU&sid=nHmcNNzbNG0P3jQ-AACX HTTP/1.1" 200 -
10.100.235.128 - - [18/Nov/2022 03:21:52] "GET /socket.io/?EIO=4&transport=polling&t=OI8mSaK&sid=nHmcNNzbNG0P3jQ-AACX HTTP/1.1" 200 -
10.100.235.128 - - [18/Nov/2022 03:21:53] "GET /socket.io/?EIO=4&transport=polling&t=OI8mSsp&sid=KBDD4nRI75JlljdPAACb HTTP/1.1" 400 -
10.100.235.128 - - [18/Nov/2022 03:21:55] "GET /socket.io/?EIO=4&transport=polling&t=OI8mTD- HTTP/1.1" 200 -
disconnect handler error
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/engineio/server.py", line 622, in _trigger_event
    return self.handlers[event](*args)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 794, in _handle_eio_disconnect
    self._handle_disconnect(eio_sid, n)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 698, in _handle_disconnect
    self._trigger_event('disconnect', namespace, sid)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 745, in _trigger_event
    return self.handlers[namespace][event](*args)
  File "/usr/local/lib/python3.8/site-packages/flask_socketio/__init__.py", line 282, in _handler
    return self._handle_event(handler, message, namespace, sid,
  File "/usr/local/lib/python3.8/site-packages/flask_socketio/__init__.py", line 766, in _handle_event
    ret = handler(*args)
  File "/app/server/app.py", line 73, in on_disconnect
    room_id = rooms_sid[sid]
KeyError: 'noE4Yb9jTGBEKMxVAACA'
disconnect handler error
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/engineio/server.py", line 622, in _trigger_event
    return self.handlers[event](*args)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 794, in _handle_eio_disconnect
    self._handle_disconnect(eio_sid, n)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 698, in _handle_disconnect
    self._trigger_event('disconnect', namespace, sid)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 745, in _trigger_event
    return self.handlers[namespace][event](*args)
  File "/usr/local/lib/python3.8/site-packages/flask_socketio/__init__.py", line 282, in _handler
    return self._handle_event(handler, message, namespace, sid,
  File "/usr/local/lib/python3.8/site-packages/flask_socketio/__init__.py", line 766, in _handle_event
    ret = handler(*args)
  File "/app/server/app.py", line 73, in on_disconnect
    room_id = rooms_sid[sid]
KeyError: '6xydUPfXDHMtNMZOAACC'
10.100.235.128 - - [18/Nov/2022 03:21:56] "POST /socket.io/?EIO=4&transport=polling&t=OI8mTYN&sid=9q7xk1aD-RYQK_HVAACd HTTP/1.1" 400 -
10.100.235.128 - - [18/Nov/2022 03:21:57] "GET /socket.io/?EIO=4&transport=polling&t=OI8mTie HTTP/1.1" 200 -
10.100.235.128 - - [18/Nov/2022 03:21:57] "POST /socket.io/?EIO=4&transport=polling&t=OI8mTrp&sid=9Act-c-SiH9kSZs5AACe HTTP/1.1" 400 -
10.100.235.128 - - [18/Nov/2022 03:21:57] "GET /socket.io/?EIO=4&transport=polling&t=OI8mTrp.0&sid=9Act-c-SiH9kSZs5AACe HTTP/1.1" 400 -
10.100.235.128 - - [18/Nov/2022 03:21:59] "GET /socket.io/?EIO=4&transport=polling&t=OI8mUMd HTTP/1.1" 200 -
10.100.235.128 - - [18/Nov/2022 03:21:59] "POST /socket.io/?EIO=4&transport=polling&t=OI8mUMn&sid=g5CbjhkwHv7IHbM6AACb HTTP/1.1" 200 -
disconnect handler error
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/engineio/server.py", line 622, in _trigger_event
    return self.handlers[event](*args)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 794, in _handle_eio_disconnect
    self._handle_disconnect(eio_sid, n)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 698, in _handle_disconnect
    self._trigger_event('disconnect', namespace, sid)
  File "/usr/local/lib/python3.8/site-packages/socketio/server.py", line 745, in _trigger_event
    return self.handlers[namespace][event](*args)
  File "/usr/local/lib/python3.8/site-packages/flask_socketio/__init__.py", line 282, in _handler
    return self._handle_event(handler, message, namespace, sid,
  File "/usr/local/lib/python3.8/site-packages/flask_socketio/__init__.py", line 766, in _handle_event
    ret = handler(*args)
  File "/app/server/app.py", line 73, in on_disconnect
    room_id = rooms_sid[sid]
KeyError: 'IV8G3B7tPnMP3uTDAACc'

key 값이 지속적으로 변경되고 있음을 확인 ⇒ 여러번의 커넥션을 시도하면서 python deployment 에 요청을 하기 때문에 에러가 발생함
임시방편으로 replica를 1로 지정해줌
그러나 ssl인증 관련 문제로 또다른 에러가 터졌다. (현재 openSSL을 사용함)


CI/CD 구축


WebRTC의 경우 프로젝트 오류가 빈번하게 일어날 가능성이 높고, 현재 촉박한 개발일정 탓에 미리 CI/CD를 구축해 놔야한다는 피드백을 받았다.
오류가 날 때마다 이미지를 만들어서 배포할수는 없으니까
여러 CI/CD툴이 있지만 빠르게 구축할 수 있는 Github Action, ArgoCD를 사용하기로 했다

CI Tetst 1

팀 레포중 하나를 사용하여 GithubAction-CI를 테스트해보기

  • 레파지토리에서 Action → set up a workflow yourself 를 선택하여 yml 코드를 작성해야한다

  • yml 코드 작성

name: Muzi-Test-CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on: [push] 

jobs:
  build:
    runs-on: macOS #운영체제
    
    steps:
    - name: Run pwd
      run: pwd
    - name: Run ls -al
      run: ls -al

  • commit을 하면 workflows가 생긴다

  • 터미널에서 파일 하나 만들어서 git pull 날리기

  • git pull이 정상적으로 성공했다면 Actions에 들어가기

  • yml코드에 작성했던 setps들이 제대로 수행 되었는지, 그리고 그 명령어 결과가 어떻게 나타났는지 확인 할 수 있다



CI Tetst 2

다른사람의 action을 사용하고 싶을때 적용시켜보기

  • 똑같이 Actions에서 yml코드를 작성한다
name: Muzi checkout

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on: [push]

jobs:
  build:
    runs-on: macOS 
    
    steps:
    - uses: actions/checkout@v2 ## 이부분 추가!
    - name: Run pwd
      run: pwd
    - name: Run ls -al
      run: ls -al

actions/checkout@v2 : 깃허브에서 만든 action의 저장소
https://github.com/actions/checkout

  • 남이 만든 액션을 사용할 수 있음

  • 코드를 수정하여 테스트 해보기
  • 커밋 날리기 : git commit -am “커밋내역”



본 프로젝트 CI 설정

  • 서버 컴퓨터에 Nexus가 구축되어 있긴 하지만 우선 오류를 최소화 하는 방향인 DockerHub로 테스트 후 차차 수정해 나가기로 했다
  • GitAction을 사용하여 Dockerimage를 자동 생성할 수 있도록 하는게 목표
  • 프론트 플젝과 Signarling 서버 플젝을 CI 적용시키도록 하자

DockerHub에 이미지가 자동 생성 되게 하기위해서는 Dockerhub token과 계정이 필요하다

  • 팀레포 -> secrets 들어가서 생성하기


  • UserName, Token 설정하기


  • yml 코드 생성
name: webrtc-eyestalk Actions

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: kimnamju/webrtc-eyestalk ## 이미지 저장소/이미지이름
          tag-semver: |    ## 이미지 태그 변수
            {{version}}
            {{major}}.{{minor}} 
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }} ## 토큰이 들어가는 변수값
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile ## 도커파일 위치도 잘 지정해야한다
          platforms: linux/amd64
          push: true
          tags: ${{ steps.docker_meta.outputs.tags }}
          labels: ${{ steps.docker_meta.outputs.labels }}
  • 도커파일에서 에러가 나면 Action부분이 이렇게 뜬다

가급적 로컬에서 Dockerfile이 제대로 빌드 되는지 확인해보고 넣는게 좋다

  • Dockerfile
FROM python:3.8.15-slim

LABEL maintainer="rhj0830@gmail.com"
# 파일 옮기기 
COPY . /app/server

WORKDIR /app/server

RUN pip3 install -r requirements.txt

ENTRYPOINT ["python", "Server.py"]

  • 도커 이미지 업로드 성공

  • 도커 허브 확인

  • 도커 이미지 태그를 수정
    위의 사진을 보면 태그가 브렌치 명인 main을 사용하는것을 볼 수 있다
    yml에 변수로 tag를 지정할 수 있도록 되어있기 때문에 변경이 가능하다


    변경을 하면 자동으로 업데이트 됨!



CI-GithubAction 태그 자동 업데이트 & Dockerhub 이미지 태그 자동 업데이트


태그가 수동으로 설정 되어있다보니 쿠버네티스 환경에서 문제가 생겼다. 이미지가 최신으로 업데이트해도 같은 태그로 들어가 서버에서는 같은 이미지로 인식하기 때문에 코드 업데이트가 되지 않는 것이다 즉, 태그가 자동 업데이트 되도록 설정해야했다.

  • 무수한 시도들... ㅎ

  • Front: React,JS code

name: webrtc-eyestalk Actions

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Checkout
        id: version-bump
        uses: 'phips28/gh-action-bump-version@master'
        with:
          tag-prefix: 'v'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - 
        name: 'Output Step'
        env:
          NEW_TAG: ${{ steps.version-bump.outputs.newTag }}
        run: echo "new tag $NEW_TAG"
      -
        name: Login to DockerHub
        uses: docker/login-action@v1.10.0
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }} 
          password: ${{ secrets.DOCKERHUB_TOKEN }}
       
      -
        name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: roheejae/eyestalk-front    
      
      -
        name: Build and push
        uses: docker/build-push-action@v2.6.1
        with:
          context: .
          file: ./Dockerfile
          platforms: linux/amd64
          push: true
          tags: roheejae/eyestalk-front:latest, roheejae/eyestalk-front:${{ steps.version-bump.outputs.newTag }}

  • back: Python,Flask
name: webrtc-eyestalk-back

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      - name: Bump version and push tag
        id: tag_version
        uses: mathieudutour/github-tag-action@v5.5 # 가져다 쓸 auto tagging 프로그램
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }} # secrets.GITHUB_TOKEN 는 자동생성됨
      - name: Create a GitHub release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ steps.tag_version.outputs.new_tag }}
          release_name: Release ${{ steps.tag_version.outputs.new_tag }}
          body: ${{ steps.tag_version.outputs.changelog }}
      -
        name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: roheejae/eyestalk-back
          tag-semver: |
            {{version}}
            {{major}}.{{minor}}
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          platforms: linux/amd64
          push: true
          tags: roheejae/eyestalk-back:${{ steps.tag_version.outputs.new_tag }}	

  • githubAction 과 Dockerhub 이미지 태그 모두 자동으로 업데이트 된것을 확인할 수 있다.



ArgoCD


ArgoCD TEST 1

  • 구축한 환경인 K8s master1, worker3의 환경에서 테스트
  • k8s setting의 manifest.yml이 있는 코드를 테스트 해봄


  • 프로젝트 이름 default로 변경
  • 깃주소 업로드
  • ArgoCD CLI를 통해 Application 배포와 동기화가 가능하다


CI/CD 파이프라인이 제대로 구축되어있는것을 확인함



ArgoCD

  • 프로젝트에 맞는 manifest.yml 생성 후 CD까지 연동을 해야함
  • 아직 개발에서 오류가 나고 있기 때문에 deploy는 멈춤
profile
개발기록

0개의 댓글