::: IT인터넷 :::

Jenkins의 Docker 빌드 테스트에 사용할 예제 생성

곰탱이푸우 2022. 2. 3. 08:20
지난 포스팅에서 Jenkins의 Docker 빌드에 사용할 가상 머신을 VirtualBox를 통해 만들었다.
 
해당 방법은 아래 포스팅을 참고한다.
그리고 생성한 가상 머신을 Jenkins의 빌드 에이전트로 등록했다.
해당 방법은 아래 포스팅을 참고한다.
 
Jenkins에서 해당 에이전트를 이용하여 빌드 파이프라인을 구성하고 테스트 하기 위해서는 예제 코드가 필요하다.
이번 포스팅에서는 테스트를 위한 예제 코드를 작성하는 방법에 대해서 알아본다.
 

코드 작성

Docker 빌드를 하기 위한 Dockerfile 코드를 작성한다.
그리고 Dockerfile에서 사용하는 sources.list 파일과 Jenkins에서 배포하는데 필요한 verison 파일을 준비한다.
 
참고로 sources.list 파일은 사설 저장소를 사용하는 경우에만 필요하다.
공식 저장소를 사용하는 경우에는 필요 없다.
 
 

Dockerfile 작성

Docker 이미지를 빌드하기 위한 Dockerfile 코드를 작성한다.
 
기본 코드 작성
Docker 이미지 빌드를 위한 코드를 작성한다.
구성은 간단하다. 우분투 20.04에 redis-server를 설치하고 포트를 개방하고 실행한다.
공식 저장소를 사용하는 경우 아래 코드만 사용하면 된다.
 
코드는 다음과 같다.
# Dockerfile 
FROM ubuntu:20.04 

# Docker 컨테이너 내부 APT 목록 업데이트와 redis-server 설치
RUN apt-get update && \ 
    apt-get install -y redis-server && \ 
    apt-get clean 

# redis의 6379 포트 개방
EXPOSE 6379 

# redis-server 실행
CMD ["redis-server", "--protected-mode no"]

 

베이스 이미지 주소 변경
이 부분은 사설 저장소를 사용하는 경우에만 해당된다.
FROM 명령은 Docker 저장소에서 베이스 이미지를 가져오는 명령어이다.
이후 과정들은 해당 Docker 이미지에서 실행하는 명령이다.
 
사설 저장소를 사용하는 경우 FROM 부분은 다음과 같이 수정한다.
# Dockerfile 
FROM 사설저장소주소:포트/ubuntu:20.04

# 사설 저장소 주소가 docker.test.com이고 포트가 6000번이라면
# 아래와 같은 형태가 된다
# FROM docker.test.com:6000/ubuntu:20.04
 
인증서 오류 해결 추가
이 부분은 사설 저장소를 사용하는 경우에만 해당된다.
Let's Encrypt 인증서의 루트 인증서 만료로 인한 오류 발생하는 경우에 대한 조치로, 해당 사항이 없으면 넘어간다.
 
이전 포스팅에서 Let's Encrypt 인증서의 루트 인증서 만료로 오류가 발생한 것을 다룬 적이 있다.
해결 방법은 아래 포스팅을 참고한다.
사설 저장소를 사용하다가 인증서 관련 오류가 발생하는 경우, ca-certificates 패키지를 재설치하면 해결된다.
 
인터넷에 연결 된 환경이므로 가장 간단한 방법으로 공식 저장소를 이용한 방법으로 해결 했다.
위의 Dockerfile 코드의 FROM 다음에 아래 코드를 추가한다.
# 인증서 오류로 인해 추가
# 일반적인 경우 필요 없음
RUN apt-get update && \
    apt-get install -y ca-certificates && \ 
    apt-get clean
 
 
sources.list 파일 교체
이 부분은 사설 저장소를 사용하는 경우에만 해당된다.
사설 저장소를 이용하는 경우 sources.list 파일 내부의 저장소 경로를 사설 저장소 경로로 수정해야 한다.
 
그러나 Docker 컨테이너 내부 파일을 수정하는 것은 번거롭다.
따라서 기존 파일을 백업하고, 미리 준비한 파일로 교체하는 방법을 사용한다.
 
아래 코드를 Dockerfile의 RUN 바로 윗 부분에 추가한다.
# 아래 두 줄은 APT 사설 저장소를 사용하는 경우만
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak 
COPY ./data/etc/apt/sources.list /etc/apt/sources.list

# Docker 컨테이너 내부 APT 목록 업데이트와 redis-server 설치
 
우분투의 APT 사설 저장소 관련 내용은 아래 포스팅을 참고한다.
최종 DockerFile 코드
위의 변경 사항이 모두 반영 된 코드는 다음과 같다.
# Dockerfile
# Docker 사설 저장소를 사용하는 경우
FROM 사설저장소주소/ubuntu:20.04

# 인증서 오류로 인해 추가 (https://www.bearpooh.com/100)
# 일반적인 경우 필요 없음
RUN apt-get update && \
    apt-get install -y ca-certificates && \
    apt-get clean

# 아래 두 줄은 APT 사설 저장소를 사용하는 경우만
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak
COPY ./data/etc/apt/sources.list /etc/apt/sources.list

# Docker 컨테이너 내부 APT 목록 업데이트와 redis-server 설치
RUN apt-get update && \
    apt-get install -y redis-server && \
    apt-get clean

# redis의 6379 포트 개방
EXPOSE 6379

# redis-server 실행
CMD ["redis-server", "--protected-mode no"]
 
위의 코드는 사설 저장소를 사용하는 경우에 해당하며, 인증서 관련 트러블 슈팅을 포함한 코드이다.
공식 저장소를 사용하는 경우 앞 부분에 설명한 DockerFile의 기본 코드만 사용해도 된다.
 
 

sources.list 파일 준비

이 부분은 사설 저장소를 사용하는 경우에만 해당된다.
sources.list 파일 교체 코드가 추가 된 경우 실제로 해당 파일이 존재해야 복사 할 수 있다.
 
생성한 sources.list 파일을 아래와 같은 구조로 준비한다.
root
├ Dockerfile
└ data/etc/apt/sources.list
 

version 파일 준비

Jenkins에서 빌드한 Docker 이미지를 Docker 로컬 저장소에 배포하기 위해 필요한 정보이다.
Docker 이미지 변경 사항에 대한 버전 관리는 이 파일을 통해 진행한다.
 
다음과 같이 저장소 경로, 이미지명, 이미지 버전을 포함한 version 파일을 생성한다.
메모장이나 vi 편집기 등을 이용하면 된다.
REPO_PATH=사설저장소주소:포트
IMAGE_NAME=이미지명
IMAGE_VERSION=1.0.0
 
Docker의 로컬 저장소와 포트 설정은 다음 포스팅을 참고한다.
생성한 version 파일은 아래와 같은 구조로 준비한다.
root
├ Dockerfile
├ version
└ data/etc/apt/sources.list
 
 

이미지 빌드와 테스트

작성한 코드를 이용한 빌드와 실행이 정상적으로 되는지 확인하기 위해 로컬에서 테스트를 진행한다.
 

Docker 이미지 빌드

아래 명령으로 Dockerfile을 빌드하여 Docker 이미지를 생성한다.
# docker build -t 사설저장소주소:포트/이미지이름:버전 Dockerfile경로

$ docker build -t 사설저장소주소:포트/srtest-docker:1.0.0 .
 
-t 옵션은 Docker 이미지의 tag를 지정하는 옵션이다.
마지막의 . 은 Dockerfile의 경로를 의미하며, 현재 경로에 위치한다는 의미이다.
다른 경로에 위치할 경우 해당 경로를 입력한다.
 
아래와 같이 빌드가 진행된다.
 
빌드에 성공하면 아래와 같이 성공 메시지가 출력된다.
 
참고사항
빌드에 여러 번 실패하는 경우 <None> 이라는 이름의 이미지가 여러개 생성된다.
빌드에 실패한 dangling 이미지를 의미하는데, 저장 공간을 낭비하는 원인이 된다.
 
빌드에 성공한 이후 아래 명령을 수행하면 <None> 이미지들을 한번에 제거할 수 있다.
$ docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
 
다른 이미지나 컨테이너가 없는 독립 된 환경이라면 prune 명령을 사용하는 것도 방법이다.
아래 포스팅을 참고한다.
이러한 점 때문에 가급적 운영 환경과 개발 환경은 분리하는 것이 가장 좋다.
 
 

생성 된 Docker 이미지 확인

아래 명령으로 생성 된 Docker 이미지를 확인한다.
$ docker image list

 

빌드에 성공하면 다음과 같이 생성 된 이미지를 확인할 수 있다.
 

Docker 컨테이너 실행

생성한 이미지가 정상적으로 동작하는지 확인하기 위해 컨테이너를 실행한다.
 
아래 명령을 실행한다. -d 옵션은 백그라운드로 실행하는 명령이다.
$ docker run -d -p 6379:6379 --name srtest-docker \
  사설저장소주소:포트/srtest-docker:1.0.0
 
실행에 성공하면 다음과 같은 메시지가 출력된다.
 
정상적으로 실행되었어도 내부에 오류가 있으면 컨테이너가 바로 종료되는 경우가 있다.
아래 명령으로 컨테이너가 정상적으로 실행 중인지 확인한다.
종료 된 경우 STATUS에 Exited로 표시된다.
$ docker ps
 
 

컨테이너 정상 동작 확인

컨테이너가 정상적으로 동작중인지 확인한다.
redis-server의 경우 redis-cli 명령을 통해 제어가 가능하다.
redis-server가 정상적으로 동작중 이면 redis-cli로 ping 옵션을 전달하면 PONG이라는 응답이 온다.
 
만약 redis-cli가 없을 경우 아래 명령으로 redis-tools를 설치한다.
# redis-cli가 실행되지 않을 경우 아래 명령어 실행
$ sudo apt install redis-tools
 
그리고 아래 명령을 실행한다.
$ redis-cli ping
 
PONG이라는 응답이 도착했다. 컨테이너가 정상적으로 동작중이다.
 

생성한 Docker 컨테이너와 이미지 삭제

컨테이너가 정상 동작하는 것을 확인했으므로, 실행중인 컨테이너와 생성 된 이미지를 삭제한다.
Docker 이미지 빌드를 테스트하는 것이 목적이기 때문이다.
 
아래 명령을 실행하여 컨테이너와 이미지를 삭제한다.
$ docker stop srtest-docker
$ docker rm srtest-docker
$ docker rmi 사설저장소이름:포트/이미지명:버전
 
다음과 같이 삭제된 것을 확인할 수 있다.
 
이로서 Docker 이미지 빌드 테스트를 위한 예제 코드 작성이 완료되었다.
 
 

형상 관리

Docker 이미지 빌드를 위한 예제 코드를 작성한 것은 Jenkins에서 테스트 하기 위한 것이다.
따라서 GitLab과 같은 형상 관리를 적용해야 한다.
 
GitLab을 이용한 형상 관리 방법은 아래 포스팅에서 다룬적이 있다.
프로젝트와 브랜치를 생성하고, 해당 저장소에 코드를 커밋한다.
이전에 구축했던 GitLab을 사용한다.
 

프로젝트 생성

GitLab의 우측 상단에 있는 New Project 버튼을 클릭한다.

 

Create blank project를 클릭한다.

 

Project Name에는 Docker 이미지와 동일하게 입력한다.
Project는 Internal, README 생성 옵션에 체크한다. (이 부분은 필요에 따라 결정한다.)
 
 

브랜치 생성

아래와 같이 프로젝트가 생성 되면, 화면 중앙의 + 버튼을 클릭한다.
 
작업을 위해 New Branch 버튼을 클릭하여 브랜치를 생성한다.
안정적인 형상 관리를 위해 main에서 직접 작업하는 것은 최대한 지양해야 한다.
 
Branch name에 적절히 입력한다. 최초 커밋이므로 init-commit으로 지정했다.
 
브랜치가 생성되면 우측 상단의 Clone을 클릭하고, Clone with HTTPS 우측의 복사 버튼을 클릭한다.
 
 

로컬 저장소 생성 및 파일 복사

로컬에서 해당 프로젝트 저장소를 Clone한다.
$ git clone .git경로 생성할폴더이름
 
아래와 같이 저장소가 Clone 되었다.
 
init-commit 브랜치에서 작업할 것이므로 checkout 명령으로 브랜치를 전환한다.
# 코드 작업 공간으로 이동
cd 폴더명

# 브랜치 전환
$ git checkout -b 브랜치명 origin/브랜치명
 
그리고 앞서 생성한 Dockerfile 관련 파일들을 복사한다.
-r 옵션은 Recursive를 의미하고 하위 경로까지 포함해서 복사한다.
# 생성한 Dockerfile 관련 파일 복사
$ cp -r Dockerfile경로/. .
 
아래와 같이 코드가 복사 된 것을 확인할 수 있다.
 
 

코드 Commit

마지막으로 해당 코드들을 GitLab에 Commit한다.
 
아래 포스팅을 참고한다.
로컬 저장소에 Commit
아래 명령으로 로컬 저장소에 Commit한다.
# Commit 할 파일 목록 추가
$ git add .

# 로컬 저장소에 Commit
$ git commit -m 메시지
 
아래와 같이 Commit 된 것을 확인할 수 있다.
 
원격 저장소에 Push
아래 명령으로 원격 저장소에 Push한다.
# 원격 저장소에 Push
$ git push
 
아래와 같이 Push 된 것을 확인할 수 있다.
 
GitLab에서 확인해보면 정상적으로 업로드 된 것을 확인할 수 있다.

 

이제 Jenkins에서 설정하면 Docker 이미지 빌드 파이프라인 구성이 완료된다.
해당 방법은 다음 포스팅에서 진행한다.