Programming-[Infra]/Docker

[에러] 도커 교과서(엘튼 스톤맨, 심효섭) - 13. 지속적 통합(CI) 파이프라인 구축. Gogs, 젠킨스

컴퓨터 탐험가 찰리 2023. 5. 5. 17:26
728x90
반응형

 

1. 도커로 CI 작업하기

 

CI란

CI는 배포가 가능한 결과물(artifact)을 코드로부터 만들어내는 파이프라인이다. 이 파이프라인에는 빌드, 테스트, 패키징 등이 포함된다. 코드 변경이나 특정 시각마다 CI 절차가 실행되도록 자동화할 수 있다. 

 

도커를 이용하여 CI 인프라 구축

배포하고자하는 프로그램을 도커로 이미지화하면 기술 스택에 상관없이 똑같은 과정을 거칠 수 있기 때문에 CI 절차의 일관성을 확보할 수 있다. 깃허브, 애저 데브옵스 등 여러 CI를 지원하는 매니지드 서비스가 있으나, 컨테이너 내부에서 CI 인프라를 구축할 수 있도록 도커를 이용하여 빌드를 할 수도 있다. 이렇게 하면 조직 내부 보안을 유지할 수도 있고 인터넷이 다운된 상황에서도 내부적으로 CI를 진행할 수 있다.

 

 

2. CI 구현 : Gogs, 젠킨스

github처럼 형상 관리 기능을 제공하는 Gogs, 이미지를 배포해주는 도커 오픈 소스 레지스트리, 자동화 서버인 젠킨스를 사용하여 컨테이너에서 CI를 구현해본다.

 

cd ./ch11/exercises/infrastructure
docker-compose -f docker-compose.yml -f docker-compose-linux.yml up -d # 리눅스 컨테이너
docker-compose -f docker-compose.yml -f docker-compose-windows.yml up -d # 윈도우 컨테이너
echo $'\n127.0.0.1 registry.local' | sudo tee -a /etc/hosts # 맥, 리눅스
Add-Content -Value "127.0.0.1 registry.local" -Path /windows/system32/drivers/etc/hosts # 윈도우
docker container ls

 

compose로 3개 이미지를 컨테이너로 띄운다. 그리고 레지스트리용 컨테이너의 도메인을 로컬 컴퓨터의 hosts 파일에 추가해서 컨테이너-로컬 컴퓨터간 이미지를 푸시하거나 내려받을 수 있도록 설정해준다.

 

tee 명령어

tee 명령어는 파이프라인 커맨드 앞으로는 stdin, 뒤로는 stdout를 출력할 파일의 path를 입력한다. 그러면 터미널에 해당 stdin 내용을 그대로 출력해줌과 동시에 지정한 path에 stdin 내용을 바탕으로 text 파일을 만들어준다.

https://twpower.github.io/135-tee-command-usage

 

macOS 5000번 포트 에러

컴포즈로 실행되는 구성 요소 중 하나인 registry를 컨테이너에서 실행하다가 에러가 났다. 5000번 포트를 이미 사용 중이라는 에러였는데, 아래 링크에 따르면 AirPlay에서 5000번 포트를 점유하고 있다고 한다.

https://algoroot.tistory.com/44

 

터미널에서 lsof -i로 프로세스들을 검사해봐도 5000번 포트를 사용 중인 프로세스가 안나와서 약간 혼란스러웠으나, mac 자체의 시스템 설정에서 아래처럼 airPlay를 검색하여 수신 모드를 꺼주면 된다.

 

Gogs

 

diamol/gogs 이미지 에러

교재에서 제공하는 diamol/gogs 이미지에 에러가 있었다. 그래서 gogs 컨테이너에서 open한 localhost:3000으로의 접근이 불가했다. 컨테이너의 로그를 보니 golang으로 사용 중인 코드를 실행하면서 thread가 os에서 허용하는 수준 이상으로 실행된다는 에러 같았다..

 

error code 일부

goroutine 1 [running]: runtime.systemstack_switch() /usr/local/go/src/runtime/asm_amd64.s:252 fp=0xc420020768 sp=0xc420020760 runtime.main() /usr/local/go/src/runtime/proc.go:127 +0x6c fp=0xc4200207c0 sp=0xc420020768 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc4200207c8 sp=0xc4200207c0 runtime: failed to create new OS thread (have 2 already; errno=22) fatal error: newosproc runtime: failed to create new OS thread (have 2 already; errno=22) fatal error: newosproc

 

 

그래서 저자의 github 페이지에 들어갔으나, Issue 쪽에도 비슷한 문제 제기를 찾을 수 없었다.

https://github.com/sixeyed/diamol/tree/master/ch11/exercises/infrastructure

 

Gogs가 어떤 건지 보기라도 하자는 마음으로, compose file의 diamol/gogs 부분을 gogs/gogs로 바꾸어 실행했다.

 

그리고 나서 localhost:3000에 접속하여 Gogs를 설치한다.

 

Database를 SQLite3로 설정한 뒤 설치하기를 눌러 다음으로 넘어간다. 계정을 로컬로 등록하는데, 젠킨스에서 참조하는 사용자명이 diamol이라 diamol이라는 사용자명으로 계정을 새로 등록해야한다.

 

그리고 다음 주소에 접근하여 Repository Name을 diamol로 설정해준다.

http://localhost:3000/repo/create

 

이제 마치 로컬에서 github를 만든 것처럼 컨테이너상에서 로컬로 운영하는 git repository를 구현했다.

 

이 작업을 하면서 단순히 docker container run 명령으로 모든 애플리케이션의 설정이 끝나지 않는다는 것도 기억해두자. 일부 설정이나 초기값은 컨테이너의 애플리케이션에 접속하여 직접 설정해주어야한다.

 

 

 

Jenkins

 

 

 

설정을 억지로 했더니 diamol git 추가도 안되고, Jenkins와 연동도 안되는 것 같다. 시간을 너무 많이 잡아먹어서 일단은 책을 읽기만 하고 향후 정말 gogs와 jenkins를 쓰게 될 때 참고만 해야할 것 같다..

 

 

이외 배웠던 점들

 

ARG 인스트럭션

ENV와 다르게 이미지를 빌드하는 시점에만 유효하다.

 

LABEL 인스트럭션

Dockerfile 스크립트에 정의된 키-값 쌍을 빌드되는 이미지에 적용한다. 이런 레이블을 이용하여 해당 빌드가 어떤 상태인지 등을 추적할 수 있으므로 중요하다.

 

Dockerfile 예시

FROM diamol/dotnet-aspnet

ARG BUILD_NUMBER=0
ARG BUILD_TAG=local

LABEL version="3.0"
LABEL build_number=${BUILD_NUMBER}
LABEL build_tag=${BUILD_TAG}

ENTRYPOINT ["dotnet", "Numbers.Api.dll"]

 

728x90
반응형