이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • VM Instance에서 백엔드 개발자에게 남는 운영 책임은 무엇인가?
  • VM은 살아 있는데 Spring API가 실패할 때 무엇을 확인해야 하는가?
  • VM 운영에서 안전하게 완화하려면 어떤 정보를 공유해야 하는가?

개요

VM Instance는 애플리케이션이 실행되는 가상 서버다.

클라우드에서 VM을 만들면 CPU, memory, disk, network interface, public/private IP, OS, access key가 함께 생긴다.

하지만 VM이 있다는 것은 Spring 애플리케이션이 안정적으로 운영된다는 뜻이 아니다.

프로세스가 떠 있는지, 포트가 열려 있는지, 로그가 남는지, disk가 가득 차지 않았는지, 보안 패치와 runtime 버전이 관리되는지 확인해야 한다.

백엔드 개발자는 VM 자체를 모두 운영하지 않더라도 애플리케이션이 VM 위에서 어떤 조건을 필요로 하는지 설명해야 한다.

VM의 운영 경계

VM 운영 책임은 클라우드 사업자가 모두 가져가지 않는다.

보통 다음은 사용자 또는 운영팀 책임이다.

  • OS package update와 보안 패치
  • JVM, Node, Nginx 같은 runtime 설치와 버전 관리
  • 애플리케이션 process 실행 방식
  • 로그 파일 위치와 rotation
  • disk 사용량과 임시 파일 정리
  • inbound/outbound port 관리
  • SSH key와 IAM 권한 관리
  • 백업 이미지나 스냅샷 정책

Managed runtime을 쓰지 않는다면 VM은 자유도가 높은 대신 운영 책임도 크다.

Spring 실행 방식

VM에서 Spring Boot 애플리케이션은 보통 systemd 같은 process manager로 실행한다.

[Unit]
Description=order-api
After=network-online.target
 
[Service]
User=app
WorkingDirectory=/opt/order-api
Environment=SPRING_PROFILES_ACTIVE=prod
EnvironmentFile=/etc/order-api/order-api.env
ExecStart=/usr/bin/java -jar /opt/order-api/order-api.jar
Restart=on-failure
RestartSec=10
SuccessExitStatus=143
 
[Install]
WantedBy=multi-user.target

이 설정에서 백엔드 개발자가 확인해야 할 것은 실행 user, profile, env file, jar 경로, restart 정책, 종료 signal이다.

잘못된 profile이나 누락된 환경 변수는 VM이 정상이어도 API 장애를 만든다.

관찰 명령

VM 장애 분석은 먼저 읽기 명령으로 시작한다.

systemctl status order-api
journalctl -u order-api -n 100 --no-pager
ss -ltnp | grep 8080
df -h
free -m
top -b -n 1 | head -30

명령 결과는 실행 시각, 대상 VM, 애플리케이션 버전과 함께 남긴다.

동일한 증상이라도 CPU 포화, disk full, port 충돌, 환경 변수 누락은 완화 방식이 다르다.

요청 흐름에서 보는 위치

user
  DNS
    Load Balancer
      VM private IP:port
        Spring process
          DB, cache, external API

VM은 요청 흐름 중 하나의 지점이다.

Load Balancer target은 unhealthy인데 VM process는 살아 있을 수 있다.

반대로 VM process는 정상이어도 보안 그룹이나 route 문제로 요청이 도달하지 못할 수 있다.

따라서 VM만 보거나 애플리케이션 로그만 보는 식으로 분리하면 원인 격리가 늦어진다.

장애 신호

  • VM은 running 상태인데 systemctl status에서 애플리케이션이 failed 상태다.
  • 포트 8080이 열려 있지 않다.
  • disk 사용량이 100%에 가까워 로그를 쓸 수 없다.
  • CPU steal이나 memory pressure가 높아 응답 시간이 길어진다.
  • 로그 rotation이 없어 오래된 로그가 disk를 채운다.
  • 환경 변수 파일이 누락되어 prod profile이 아닌 설정으로 시작된다.
  • SSH 접속은 되지만 애플리케이션 user 권한으로 파일을 읽지 못한다.

이 신호는 클라우드 VM 상태와 애플리케이션 상태를 분리해서 봐야 한다는 뜻이다.

안전한 완화 조치

  • process가 죽어 있으면 최근 로그를 저장한 뒤 재시작한다.
  • disk full이면 삭제 가능한 임시 파일과 오래된 로그부터 확인한다.
  • 새 버전이 문제라면 이전 artifact와 환경 변수 호환성을 확인하고 되돌린다.
  • port 충돌이면 어느 process가 점유하는지 확인한 뒤 중지한다.
  • 자원 포화가 반복되면 instance size 조정 전 애플리케이션 부하 원인을 확인한다.
  • 의심 VM만 Load Balancer target에서 제외해 전체 영향을 줄일 수 있다.

완화 조치는 증거를 지우지 않는 범위에서 시작해야 한다.

하지 말아야 할 대응

  • 로그를 확인하기 전에 VM을 삭제하거나 새로 만들지 않는다.
  • disk가 찼다고 애플리케이션 전체 디렉터리를 임의 삭제하지 않는다.
  • 원인 확인 없이 chmod 777이나 공개 SSH 접근을 열지 않는다.
  • 환경 변수를 임시로 바꾼 뒤 기록 없이 방치하지 않는다.
  • VM 상태가 running이라는 이유로 애플리케이션 정상으로 판단하지 않는다.

인프라 담당자와 공유할 자료

  • VM id, region, private IP, image, instance type
  • 실행 user, service name, port, profile
  • 최근 배포 artifact와 환경 변수 변경
  • systemd 상태와 최근 로그
  • CPU, memory, disk, network 사용량
  • Load Balancer target 상태와 보안 그룹
  • 이미 실행한 재시작 또는 제외 조치

이 자료가 있어야 인프라 담당자가 VM, network, LB, storage 경계를 함께 볼 수 있다.

운영 체크리스트

  • VM별 service name과 port가 문서화되어 있는가?
  • 로그 위치와 rotation 정책이 있는가?
  • 환경 변수 파일의 소유자와 권한이 적절한가?
  • OS patch와 JVM update 책임자가 정해져 있는가?
  • VM 교체 시 필요한 bootstrap 절차가 재현 가능한가?
  • Load Balancer에서 특정 VM을 제외하는 절차가 있는가?
  • backup image나 스냅샷이 실제 복원 가능한지 확인했는가?

확인 질문

확인 질문

  • VM이 running인데 API가 실패할 수 있는 이유는 무엇인가?
    • 애플리케이션 process, port, disk, 환경 변수, 권한, network 경로가 별도로 실패할 수 있기 때문이다.
  • VM 운영에서 백엔드 개발자가 설명해야 할 정보는 무엇인가?
    • service name, port, profile, env, artifact, 로그 위치, 의존 서비스 연결 조건이다.
  • 장애 중 VM을 바로 삭제하면 위험한 이유는 무엇인가?
    • 로그와 현재 상태 증거가 사라져 원인 격리와 재발 방지가 어려워지기 때문이다.

리뷰 체크포인트

  • VM 상태와 애플리케이션 상태를 구분해 설명하는가?
  • systemd 또는 process manager 기준 실행 방식이 문서화되어 있는가?
  • disk, log, env, port 확인 절차가 있는가?
  • 특정 VM을 트래픽에서 제외하는 방법이 있는가?
  • VM 교체나 재시작 후 검증할 API가 정해져 있는가?