Docker Swarm(4) Docker-Registry 구축

BlackMouse·2025년 3월 24일

Docker-Swarm

목록 보기
4/4

앞장에서 설명했던 jenkins CI/CD를 구축하면서 장애가 발생
해당 python으로 관한 서버를 컨테이너로 생성하는 과정에서 개발자가 custom한 도커 이미지가 생성되는데, 이 경우 배포가 진행되지 않음

현재 swarm 클러스터 환경에서 구축한 CI/CD 파이프라인은

  1. jenkins가 gitlab의 webhook과 연결되어, 이벤트 발생시 jenkins에서 빌드후
  2. 해당 gitlab의 프로젝트를 docker-swarm-manager에 복사를 진행하고
  3. docker-swarm-manager에서 스택 배포 진행

이때, 3번 manager노드에서 스택 배포 진행할때 에러가 발생...
그 해당 에러에 대해서 자세히 파해쳐 보았다.

docker의 기본 실행 방법은 보통

docker run ~

으로 하거나 docker-compose.yml 실행을 진행
이 방법은 도커노드를 하나의 서버에서 진행할 경우이고, swarm 환경에서는 배포 진행방법이 다르다.
swarm-cluster 환경에서의 배포 진행 방법은 오직 manager-node에서 진행되고, worker노드에 배포되는 방식이다. -> manager-node도 worker노드로 참여해서 컨테이너가 실행하게 할수도 있음.
이 부분이 처음에는 에러랑 무슨 상관이지 할 수 있는데(나도 왜 에런지 한참 고민함....), 간단한 그림으로 설명을 진행해보겠습니다.

도커 내부적으로 더 복잡한 로직이 발생하겠지만 간단하게 설명
그림을 번호 순서대로 설명해보자면
1. jenkins에서 python공식이미지인 python:lts 이미지로 서버를 컨테이너화 실행
2. manager노드는 이 컨테이너를 워커에 배포
3. python:lts 이미지로 배포를 진행하려고 할때, 이미지가 없기때문에 docker hub에서 해당 이미지를 내려받아 컨테이너 실행

이렇게 docker hub에 있는 이미지를 할때는 에러가 발생하지 않는다.

그런데!!

현재 python 서버 배포하는 컨테이너는 custom한 이미지를 실행합니다.
개발하는 과정에서 필요한 패키지들을 pip install로 진행을 하는데, 이를 적용하려고 개발자가 requirements.txt파일도 같이 올려줘서 이 requirements를 lts이미지에 계속 적용을 시켜줘야합니다.

계속 개발을 진행하면서 이 파일도 점차 늘어날수도 있음.

이렇기 때문에

#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#

FROM python:3.11-alpine

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN apk update
RUN apk add postgresql-dev gcc python3-dev musl-dev zlib-dev jpeg-dev

COPY . /usr/src/app/

#install dependencies
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

이 Dockerfile로 image를 생성합니다.

이 로직으로 흘러갔을 경우, 위의 그림에서
2번에서 3번으로 진행할때,
manager노드에서 워커노드로 배포를 진행하려고 하는데 해당 이미지가 없어서 배포가 진행되지 않습니다. 왜냐하면 이 이미지는 Docker Hub에도 없는 이미지이기 때문이다.
그래서 찾아본 바로 private-registry를 구축해서 이미지를 따로 관리하는 서버가 필요하다고 느꼈고, docker-registry 구축 진행을 하게 되었다.
또, 해당 프로젝트 같은 경우 폐쇄망에서 진행을 해야될수도 있는데, 이 경우에도 적용할수 있다고 생각한다.

registry-compose을 작성해서 배포를 진행합니다.

UI 페이지가 나오는데 이 페이지로 현재 이미지들에 관한 정보를 알수 있다.

생성한 이미지들에 관해서 tag가 다양하게 있는데 처음에는 latest 태그로만 해서 최신 이미지만 관리하려고 진행했다.
하지만 여기서 이슈가 발생하였는데....!
위에 잠깐 설명한것과 비슷한 stack에 배포를 진행할때 배포가 제대로 되지 않은 문제였다.
위의 그림을 다시 간단하게 다시 설명하면
1. jenkins에서 빌드를 진행하고, docker image를 생성
2. stack으로 배포
3. 배포하려고 하는 이미지가 없으면 docker hub에서 이미지 pull후 배포 진행
이 부분을 registry컨테이너를 구축후 진행하여서 해결하였지만, latest이미지로 관리를 진행했을때도 3번에서 문제가 발생되는 문제가 있었다.
2,3번에서 발생을 하는데 jenkins에서 빌드를 진행후 이미지를 :latest이미지로 생성해서 registry서버로 push를 진행을 한다.

그럼 UI상에서 확인하듯이 latest태그가 있는 이미지가 최신의 이미지로 계속 갱신이 된다.
그런데 워커에 배포가 진행되면서 latest이미지는 로컬에 존재를 하기 때문에, 새로운 것들이 적용된 이미지의 latest이미지를 pull로 땡겨오지를 않는다.
예를 들어 설명하면, 첫번째 latest 이미지에는 pip install pandas만 적용되서 이미지가 생성되었고, 두번째 latest 이미지에는 pip install pandas, pip install fast-api를 적용했다고 가정했을때 registry서버에는 두번째까지 적용된 registry가 적용됬지만, 스택배포를 할때는 배포되어있는 워커노드에 latest태그를 가진 첫번째 이미지가 있기 때문에 두번째 latest이미지로 배포를 진행하지 않는 문제가 발생했다.
-> 그래서 결국 이미지에 v1.0.1 이런 방식으로 버전을 하나하나 명시를 진행하였고, image_version 스크립트를 생성하여 jenkins가 빌드를 진행할때 먼저 실행을 하여 마지막 숫자 v1.0.2로 업그레이드 시켜놓고 해당 버전을 배포하는걸로 진행하여 해결하였다.

이로써 관련된 이슈는 해결 하였지만, 조금 아쉬웠던 부분이 있는데,
지금 설정한 방식은 빌드가 일어날때 마다 버전을 올리는 형식인데, 해당 관련 v1(major).0(minor).1(fix release) 이런식으로 오픈소스 프로젝트들이 업그레이드 된다고 알고 있습니다. 이처럼 해당 프로젝트도 오픈소스 프로젝트들 처럼 상황에 맞는 버전 업그레이드 적용을 후에 적용할 계획이다.

※ 참고
https://kdeon.tistory.com/52

profile
https://ghskdneh99.tistory.com/ 블로그 이전하였습니다

0개의 댓글