🐞 버그 설명
상황
FitTrip은 GCP의 GCE를 사용하여 서비스 배포를 진행했습니다.
FitTrip 서비스는 MSA를 목표로 하기에 각 서비스의 무중단 배포 과정이 필요했고
관련하여 작업을 자동화 시켜주는 Makefile를 작성했습니다.
Makefile 일부
.PHONY: up down user-update community-update chat-update state-update sig-update notification-update
all: up
up:
docker-compose pull
docker-compose up -d zookeeper kafka discovery-service gateway-service user-service community-service chat-service sig-service state-service notification-service
down:
docker-compose down
user-update:
@echo "user temp start"
docker-compose up -d user-service-temp
docker-compose pull user-service
@echo "sleep 10..."
sleep 10
@echo "user-service update start"
docker-compose up -d user-service
@echo "sleep 60..."
sleep 60
@echo "user temp remove"
@echo "1. find container id"
@container_id=$$(docker ps | grep user-service-temp | grep -v 'CONTAINER' | awk '{print $$1}'); \
echo $$container_id; \
echo "2. remove user temp"; \
docker exec -i $$container_id kill -15 $$(docker exec -i $$container_id lsof -i | grep java | awk 'NR==1 {print $$2}'); \
docker rm -f $$container_id; \
docker image prune -f
community-update:
@echo "community temp start"
docker-compose up -d community-service-temp
sleep 50
docker-compose pull community-service
@echo "sleep 10..."
sleep 30
@echo "community-service update start"
docker-compose up -d community-service
@echo "sleep 60..."
sleep 60
@echo "community temp remove"
@echo "1. find container id"
@container_id=$$(docker ps | grep community-service-temp | grep -v 'CONTAINER' | awk '{print $$1}'); \
echo $$container_id; \
echo "2. remove community temp"; \
docker exec -i $$container_id kill -15 $$(docker exec -i $$container_id lsof -i | grep java | awk 'NR==1 {print $$2}'); \
docker rm -f $$container_id; \
docker image prune -f
...
해당 Makefile은 GCE 로컬에서 make community-update
와 같이 실행했을 때 문제 없이 다음과 같은 순서로 잘 동작했습니다.
커뮤니티 서비스 예시 절차
- 무중단 서비스를 위한 community-service-temp 컨테이너 구동
- docker-compose로 새로운 community-service 이미지 pull
- docker-compose up -d community-service로 새로운 이미지로 컨테이너 구동
- community-service-temp 서비스 컨테이너 ID 확인
- 컨테이너에 직접 접근하여 Spring과 관련된 Java 프로세스를 종료시킴으로 컨테이너 삭제 및 서비스 디스커버리에서 서버 DOWN
- 무중단 배포 성공
하지만, Github Actions에서 똑같은 작업에 관하여 오류가 발생했고 이슈를 남기려 합니다.
발생한 버그
아래 로그처럼 GCE 로컬에서 실행시 잘 동작하던 것이 Github Actions에서 똑같이 make community-update
로 실행했을 때,
오류가 발생했습니다.
Github Actions 오류 로그
err: [64003] Failed to execute script docker-compose
err: ERROR: for community-service 'ContainerConfig'
err: ERROR: for community-service 'ContainerConfig'
err: Traceback (most recent call last):
err: File "docker-compose", line 3, in <module>
err: File "compose/cli/main.py", line 81, in main
err: File "compose/cli/main.py", line 203, in perform_command
err: File "compose/metrics/decorator.py", line 18, in wrapper
err: File "compose/cli/main.py", line 1186, in up
err: File "compose/cli/main.py", line 1182, in up
err: File "compose/project.py", line 702, in up
err: File "compose/parallel.py", line 108, in parallel_execute
err: File "compose/parallel.py", line 206, in producer
err: File "compose/project.py", line 688, in do
err: File "compose/service.py", line 581, in execute_convergence_plan
err: File "compose/service.py", line 503, in _execute_convergence_recreate
err: File "compose/parallel.py", line 108, in parallel_execute
err: File "compose/parallel.py", line 206, in producer
err: File "compose/service.py", line 496, in recreate
err: File "compose/service.py", line 615, in recreate_container
err: File "compose/service.py", line 334, in create_container
err: File "compose/service.py", line 922, in _get_container_create_options
err: File "compose/service.py", line 962, in _build_container_volume_options
err: File "compose/service.py", line 1549, in merge_volume_bindings
err: File "compose/service.py", line 1579, in get_container_data_volumes
err: KeyError: 'ContainerConfig'
err: make: *** [Makefile:40: community-update] Error 255
GCE와 Github Actions에서 사용한 절차 및 명령어가 완전히 똑같은데도 발생하는 해당 오류는 정말 어려웠습니다.
오류를 만나고 시도해본 방법은 다음과 같습니다.
시도한 방법
- sudo 명령어 사용
- Github Actions Script 대신 Run 명령어 사용
- makefile을 그냥
.sh
형태의 쉘 스크립트로 모듈화
1, 2, 3번이 근본적인 오류를 해결하기 위한 방법이 아니라는 것은 알고 있었으나,
별 다른 문제 요소를 찾을 수 없어 위 방법들을 시도하였고 역시나 오류가 해결되진 않았습니다.
특히, docker-compose up -d community-service-temp
는 되지만,
`Pull` 이후 docker-compose up -d community-service
는 안되는 모순적인 문제가 발생하였습니다.
당시 올렸던 StackOverflow
https://stackoverflow.com/questions/78576791/error-with-containerconfig-in-github-actions
버그 해결
그렇다면 남은 것 중 유일하게 걸리는 부분은 docker-compose up -d commutniy-service
로만
기존 이미지를 업데이트 하는 부분이었습니다.
처음부터 이 부분을 건들지 않은 이유는 이미지 자동 업데이트 및 재실행과 관련하여 아래 상황 등에서 문제가 없었기 때문입니다.
건들지 않은 이유
- GCE 내부 실행시 정상 작동
- 노트북 및 가상머신에서도 정상 작동
그래도 남은 가능성 및 오류 로그를 확인했을 때 가장 가능성이 큰 부분인 것 같아서,
해당 docker-compose up -d community-service
부분을 컨테이너를 아예 내리고
새롭게 띄워지도록 코드를 변경했습니다.
변경한 쉘 스크립트
#!/bin/bash
echo "community temp start"
docker-compose up -d community-service-temp
sleep 30
docker-compose pull community-service
echo "sleep 30..."
sleep 30
echo "community remove"
echo "1. find container id"
container_id=$(docker ps | grep community-service | grep -v 'CONTAINER' | awk 'NR==2 {print $1}')
echo $container_id
echo "2. remove community"
docker exec -i $container_id kill -15 $(docker exec -i $container_id lsof -i | grep java | awk 'NR==1 {print $2}')
docker rm -f $container_id
echo "community-service update start"
docker-compose up -d community-service
echo "sleep 60..."
sleep 60
echo "community temp remove"
echo "1. find container id"
container_id=$(docker ps | grep community-service-temp | grep -v 'CONTAINER' | awk '{print $1}')
echo $container_id
echo "2. remove community temp"
docker exec -i $container_id kill -15 $(docker exec -i $container_id lsof -i | grep java | awk 'NR==1 {print $2}')
docker rm -f $container_id
docker image prune -f
이미지를 pull한 뒤 바로 docker-compose up -d community-service
로 컨테이너를 재실행하는 방식이 아닌
컨테이너를 완전히 내리고 다시 띄우는 위 쉘 스크립트처럼 했더니 문제가 해결
되었습니다.
의문점
오류는 해결되었지만 여기서 생기는 궁금증이 몇 가지가 있습니다.
왜 로컬에서는 실행되는 작업이 Github Actions에서는 실행이 되지 않는가?
가능한 경우의 수
- Github Actions가 러닝되는 환경의 docker-compose 버전 기준으로 명령어 동작을 해서?
- docker-compose 내부적으로 docker-compose up -d 명령어가 외부 요청으로 인해 실행되면 안되게 막는 경우?
이 밖에도 다른 경우의 수가 있을 수 있을 수 있을 수 있습니다만,
로컬에서는 되고 Github Actions로 했을 때는 모호한 이 오류의 원인은 정확히 모르겠습니다.
🙋🏻 More
원인을 찾는 과정에서 Makefile에서 쉘 스크립트로 무중단 배포 관련한 스크립트 내용을 옮겼지만,
이것이 오류의 원인이 아니었기 때문에 원래 작업했던 Makefile을 알맞게 수정한다면
정상적으로 작동이 될 것 같습니다.
위에 작성한 의문점들에 관해서는 앞으로 개발하면서 더 알아봐야할 것 같습니다.
'프로젝트 > FitTrip' 카테고리의 다른 글
[트러블슈팅] 오픈바이두 클라이언트 연결 오류 해결 과정 (0) | 2024.06.25 |
---|---|
[트러블슈팅] SSE 적용시 게이트웨이와 유저 서비스 연동간 발생 오류 해결 (0) | 2024.06.25 |
[트러블슈팅] JPA의 deleteAll() 대신 IN을 사용한 성능 최적화 (0) | 2024.06.25 |
[트러블슈팅] 서버 배포간 다양한 CORS 오류 (0) | 2024.06.25 |
[트러블슈팅] API Gateway OpenFeign 사용 오류 (0) | 2024.06.25 |