CI CD

Gitlab Runner (Docker, shell) 실전예제

주코식딩 2023. 9. 25. 10:40

회사에서 쓰던 Repository가 Github에서 Gitlab으로 이전했다..

그래서 이참에 Gitlab Runner를 적용해보려고 한다.

 

결과부터 말해보자면 Gitlab Runner가 Circle CI보다 만족스러웠다.

Gitlab은 Linux User까지 관리해줘야해서 조금 귀찮았지만 Gitlab내에서 Repository와 CICD 상황을 모두 확인 할 수 있는 점이 편했다.

무엇보다 View가 친절하고 깔끔하다..

 

Github도 이번에 Runner를 도입했던데 나중에 기회가 된다면 써볼예정이다.

 

 

Info

gitlab-runner : runner를 등록할 agent

runner : gitlab-runner에 등록된 runner

 

cpu : 2core

memory : 2G

disk : 32G

1-1. Runner 설치 (Docker, Java)

Dockerfile

현재 사용중인 gitlab 버전이 15.4.0이라서 gitlab-runner의 버전도 맞춰주었다.

해당 gitlab-runner는 Java17을 빌드하기 위해 만들었다.

애초에 Java를 여러 버전을 설치한 후 빌드전 환경변수를 변경하는 방법도 있다.

 

gitlab-runner설치시 자동으로 gitlab-runner라는 유저가 등록된다.

실제 CI작업시에는 gitlab-runner유저로 모든 작업을 하기때문에 CD를 위한 스크립트파일 작성시 유의해야한다.

 

docker 내부와 외부를 연결하기 위해 docker.sock 파일을 volume으로 연결하는데 docker 그룹에 할당된 ID가 달라서 제대로 실행권한을 가져오지 못하기에 그룹ID를 컨테이너 외부와 맞췄다.

 

docker.sock파일에 gitlab-runner유저권한을 줘서 해결하려 했으나 volume으로 엮여있기에 컨테이너 외부에 영향을 줘서 그룹ID를 맞추는 방식으로 해당 문제를 해결했다.

FROM gitlab/gitlab-runner:v15.4.0

RUN apt-get update
RUN apt-get install -y vim docker.io jq openjdk-17-jdk curl

RUN sed -i '/^docker:/ s/:.*:/:x:103:gitlab-runner/' /etc/group

 

 

docker-compose.yml

runner를 관리하는 config 폴더와 docker hub에 이미지를 push하기 위한 docker.sock을 volume으로 설정했다.

 

Circle CI Runner에서도 겪었던 서버가 갑자기 죽는 경우가 Gitlab Runner에서도 생겼는데 Gradle의 캐싱 방식때문에 생긴 문제였다.

Gradle은 메모리에 빌드내용을 유지하는데 생각보다 굉장히 많은 메모리를 차지한다.

하나의 프로젝트에 400MB 정도의 메모리를 차지하고 놓아주지 않는 것을 확인했다.

 

따라서 Gradle Build시에는 반드시 --no-daemon 설정을 해주어야 한다. 

(해당 옵션 지정 전에는 11초에 build가 되었지만 지정 후 33초가 걸렸다. 메모리는 400MB에서 100MB 정도로 줄었다.)

 

build시에는 꽤나 많은 메모리를 차지한다.

1G정도는 가볍게 차지하는것을 확인했는데 서버 자체에 메모리 swap설정을 해두면 docker-compose 파일에 명시해둔 limit memory를 넘을 시에 자동으로 swap메모리를 활용하는 것을 확인했다.

 

물론 속도가 많이 느려지기에 너무 낮게 설정하면 안된다.

여러 시도 끝에 512MB가 최적의 메모리라고 판단했다.

 

oom_kil_disable : false 설정은 limits memory 이상으로 메모리를 사용할 시에 자동으로 docker 내부 프로세스를 죽이는 설정이다.

이 설정을 추가한 뒤에 서버가 죽는일이 사라졌다.

version: '3'

services:
  gitlab-runner-java-17:
    build: .
    container_name: gitlab-runner-java-17
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/ec2-user/gitlab/java17/config/:/etc/gitlab-runner/
    deploy:
      resources:
        limits:
          memory: 512m
    oom_kill_disable: false

 

 

1-2. Runner 설치 (Docker, Node-Yarn)

Dockerfile

apt-get에 node18버전이 안올라가 있어서 링크를 통해 받았다.

그 외 설정은 동일하다.

 

gitlab-runner 유저로 node를 실행해야 하므로 user/local 폴더에 받아야 한다는 점을 꼭 기억하자. 

 

수정 - yarn을 runner에서 빌드하니 memory를 너무 많이 차지해서 Project Dockerfile내에서 빌드하도록 변경했다.

FROM gitlab/gitlab-runner:v15.4.0


RUN apt-get clean && apt-get update && apt-get install -y --fix-missing vim docker.io jq curl

# ENV VERSION=v18.18.0
# ENV DISTRO=linux-x64

# RUN wget https://nodejs.org/dist/$VERSION/node-$VERSION-$DISTRO.tar.xz && \
#     mkdir -p /usr/local/lib/nodejs && \
#     tar -xJvf node-$VERSION-$DISTRO.tar.xz -C /usr/local/lib/nodejs 

# ENV PATH=/usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin:$PATH

# RUN ln -s /usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin/node /usr/bin/node && \
#     ln -s /usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin/npm /usr/bin/npm && \
#     ln -s /usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin/npx /usr/bin/npx

# RUN npm install -g yarn

RUN sed -i '/^docker:/ s/:.*:/:x:103:gitlab-runner/' /etc/group

 

 

 

docker-compose.yml

yarn build시에는 memory가 훨씬 더 많이 필요했다.

512MB에서는 자꾸 프로세스가 죽어서 1G로 설정했다.

수정 - Project Dockerfile 에서 yarn을 실행하므로 메모리가 많이 필요하지 않게 되었다. 256MB 로 수정

version: '3'

services:
  gitlab-runner-node-18:
    build: .
    container_name: gitlab-runner-node-18
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/ec2-user/gitlab/node18/config/:/etc/gitlab-runner/
    deploy:
      resources:
        limits:
          memory: 256m
    oom_kill_disable: false

 

2. Runner 등록

Project -> Settings -> CI/CD -> Runner 탭에서 위 이미지 확인가능하다.

URL과 토큰을 확인해두자.

참고로 URL에 그냥 http 라고 적혀있는데 https 라고 작성해야 에러없이 runner등록이 가능했다.

 

컨테이너 내부 접속

 

Runner 등록

1. gitlab-runner register 명령어를 통해 runner를 등록한다.

2. 위 사진에 나온대로 URL과 Token을 입력한다.

3. Runner를 식별할 이름을 지정한다.

4. Tag를 통해 CI파일에서 runner를 지정할 수 있다.

5. executor로 shell을 입력한다.

 

executor는 runner를 실행할 환경을 의미하는데 여기서 docker를 지정하면 여러모로 귀찮아지고 캐싱이 제대로 되지 않아 속도가 느려진다.

 

shell로 설정해 두어야 docker 컨테이너 내부에서 build가 진행된다. 

 

config.toml 확인

경로는 volume에 지정되었으므로 컨테이너 외부에서 확인해보면 된다.

위 사진과 같이 설정되었으면 성공이다.

이제 Gitlab 사이트에서 Runner 정보를 확인 할 수 있다.

 

Specific Runners에 있는 Token을 입력하면 Project에 종속된 Runner가 등록된다.

나는 그룹러너로 등록했다.

 

그룹러너를 등록하려면 해당 그룹의 Owner 권한이 필요하다.

 

 

 

Gitlab Runner는 Liunx 유저와 그룹에 대한 이해만 있으면 쉽게 설치할 수 있다.

다음 글에 .gitlab-ci.yml 파일작성법과 cicd에 대해 포스팅 하겠다..