[한화시스템 BEYOND SW캠프] 22기 17주차 회고

dev_ho·2026년 2월 22일

MapLog 프로젝트 인프라 구축 및 CI/CD 회고


1. AWS S3 연동 및 이미지 업로드 구현

서비스의 핵심 기능인 '지도 위 일기 이미지 첨부'를 위해 AWS S3 인프라를 연동했다.

  • Spring Boot에서 AmazonS3Client를 활용한 멀티파트 파일 업로드 로직을 검토했다.
  • AWS Access/Secret Key가 소스 코드에 노출되지 않도록 Kubernetes의 Secret 객체로 관리하고, 이를 Pod의 환경 변수로 주입하는 방식을 채택했다.
  • application-secret.yml 설정과 K8s Secret 연동을 통해 실제 운영 환경에서도 안전하게 이미지를 저장할 수 있는 구조를 구축했다.

2. Jenkins 자동 빌드 및 Docker Hub Push (CI)

수동 빌드 방식에서 벗어나 코드 푸시 시 자동으로 이미지가 생성되는 CI(Continuous Integration) 환경을 구축했다.

  • Jenkinsfile을 직접 작성하여 Pipeline as Code(PaC)를 실천했다.
  • 백엔드(Java/Gradle)와 프런트엔드(Vue/Vite) 빌드를 자동화하고 결과물을 도커 이미지로 생성했다.
  • 빌드 번호(${env.BUILD_NUMBER})를 이미지 태그로 사용하여 체계적인 버전 관리 환경을 조성했다.
  • Docker Hub (gusgh07)로 이미지 푸시를 자동화하는 데 성공했다.

    깃허브 레포지토리 main branch에 푸쉬시 자동으로 빌드가 진행된다

3. ArgoCD와 ngrok을 사용한 무중단 배포 (CD)

GitOps 패턴을 적용하여 인프라 가시성과 배포 자동화를 달성했다.

  • Jenkins가 빌드 후 k8s-manifests 레포지토리의 이미지 태그를 업데이트하면, ArgoCD가 이를 감지하여 K8s 클러스터에 자동 동기화(Sync)하는 메커니즘을 구현했다.(지금은 Sync를 직접눌러야하지만 설정변경가능)
  • 로컬 K8s 환경의 접속 한계를 극복하기 위해 ngrok 터널링을 도입했다. NodePort(30080)를 외부 퍼블릭 URL로 노출하여 실제 웹 접속 테스트를 수행했다.
  • 하지만 http로 접속을 위해 ingress controller를 다운받아 80 포트로 접근 가능하도록 변경했다. NodePort는 80포트로 접속이 안되기 때문이다. 시스템용 포트(Well-known ports, 0-1023)와의 충돌을 피하고, 사용자 서비스들이 겹치지 않게 관리하기 위한 보호 장치이기 때문이다! 그래서 노드포트는 30000-32767로만 접근가능하다.

4. 에러 해결 이력 (Troubleshooting Log)

오늘 발생한 주요 에러들과 그 해결 과정을 통해 쿠버네티스와 젠킨스의 심층적인 동작 원리를 파악했다.

에러 상황원인해결 방법
NoSuchMethodError: sshagentJenkins에 SSH Agent 플러그인 미설치withCredentials(sshUserPrivateKey)를 사용하는 기본 방식으로 스크립트를 수정했다.
403 Forbidden (GitHub)GitHub Token의 권한(Scope) 부족repo 권한이 부여된 PAT를 재발급하고 쓰기 권한을 확인했다.
Invalid NodePort: 80K8s NodePort 허용 범위(30000-32767) 초과NodePort를 30080으로 수정하거나 LoadBalancer 타입을 검토했다. Ingress를 통해 외부접근시 80포트를 사용 가능하도록 하고, 내부적으로는 30080포트를 사용한다.
ERR_CONNECTION_REFUSED프론트엔드 API 주소를 localhost:8080으로 하드코딩API 주소를 상대 경로(/api)로 변경하고 Nginx 프록시 설정을 적용했다.
host not found in upstreamNginx 설정의 백엔드 호스트명 불일치proxy_pass 주소를 K8s 서비스명(map-log-backend)으로 수정했다.

프론트엔드 API 경로 리팩토링 및 유지보수성 향상

  • 위의 빨간네모안의 파일들에서 /api가 앞에 붙어 호출하여 문제가 발생됨. /api/api같은 식으로 말이다.

  • axios.js에서 유지보수를 위해 한번에 관리하기위해 기존의 /api를 제거하고 .env에서 한번에 관리하도록 했다.


총평

한 주간 Jenkins와 Argocd 학습을 통해 CI/CD 자동화를 경험해 볼 수 있었다. 이전에 들었을때는 막연하다고만 느껴졌는데 이제는 파이프라인 자동화를 통한 도커이미지업로드와 무중단배포를 경험해볼 수 있는 소중한 경험이었다. 이제는 DevOps에 한층 더 가까워진 것 같다. 현재 K8s와 Jenkins에 대해 완전히 이해하고 있지 않기에 좀 더 프로젝트를 견고화하며 학습해보고자 한다.

추가적으로 이번에 Gemini CLI와 Claude Code의 도움을 많이 받았는데, 이때 그저 ~해줘가 아닌, 결과물을 예상하고 어떤식으로 작업할지에 대해 미리 지정해준 후에 해당 부분에 모르는 부분이 있을 시 내가 알고 있는 것과 비교하며 학습해나가면 더 나은 개발자로 성장할 수 있을 것 같다. 또한 추후 다른 팀원과의 지식공유를 위한 Documentation도 철저히하자!


하루죙일 썼는데 중간에 기록이 사라졌나... 아무튼 다 내걸로 만들자!

profile
새로운 기술에 열린 개발자

2개의 댓글

comment-user-thumbnail
2026년 2월 23일

씩씩하네요..

1개의 답글