• NCP(Naver Cloud Platform)을 활용하여 GitLab Runner로 CI/CD 설정

    2026. 5. 26.

    by. Daramu

    이전 포스팅을 통해 GitLabRunner를 설치하였다.

    이제는 설치 이후 동작 설정과 방식에 대한 포스팅을 진행할 것이다.

     

    GitLab Runner 설치가 궁금하다면 아래 포스팅에서 확인 가능하다.

    NCP(Naver Cloud Platform)을 활용하여 GitLab Runner로 CI/CD 구축 :: Daramu

     

    NCP(Naver Cloud Platform)을 활용하여 GitLab Runner로 CI/CD 구축

    GitLab은 단순 코드 저장소로 사용할 수 있지만, GitLab Runner를 통해 CI/CD를 구현할 수도 있다. 물론 Jenkins, ArgoCD, NCP의 Source 시리즈 등 여러 가지 CI/CD 도구가 있지만, GitLab으로 CI/CD를 구축하였을 경

    daramu.tistory.com

     

    설치가 완료되었다는 가정하게, GitLab Runner는 gitlab에 코드 저장소에 ".gitlab-ci.yml" 파일을 사용하여 CI/CD를 동작 시킨다. 

     

    이 .gitlab-ci.yml 파일은 gitlab runner를 사용하기 위한 예약 파일명으로, 다른 파일명을 사용하고 싶다면 별도의 설정이 필요하지만, 본 포스팅에서는 굳이 하지 않을 것이다.

     

    yml파일에서 사용할 환경 변수 설정을 진행해야 한다.

     

    변수에는 Manifast 파일 업데이트 및 push를 위한 Token도 필요한데, token 발급은 아래의 화면에서 할 수 있다.

    우측 상단 프로필 -> Preferences -> 좌측 사이드바의 Personal access tokens -> add new token

     

    여기서 토큰 명은 마음대로 해도 되지만, 이 토큰은 Manifast 파일의 update및 push를 진행할 것이기에 repository에 대한 read와 write는 필수로 넣어주어야 한다. 용도에 따라 추가적인 권한을 주면 된다.

     

    토큰을 발급 받았다면 glpat- 로 시작되는 토큰값이 나올건데, 임시로 notepad등에 적었다가, 이제는 진짜로 환경 변수 설정으로 넘어갈 때이다.

     


    우측 상단 Admin area -> Settings -> CI/CD -> Variables -> Add variable

     

    이제 여기서 yaml파일에 사용할 환경 변수를 넣어줄 것이다.

     

    이미지를 push하기 위해서는 NCP의 Container Registry와 연동이 필요한데, 이때 AccessKey와 SecretKey가 필요하다.

    이 값과 Registry endpoint를 환경 변수로 넣어 yaml파일에 직접적인 노출을 피할 것이다.

     

     

    NCP Container Registry에서 생성을 했다면 아래 처럼  endpoint를 하나 발급 받았을 것이다.

     

    그 외에 총 필요한 value값은 다음과 같다.

     

    NCP Container Registry 의 endpoint,

    NCP의 Access_Key,

    NCP의 Sceret_Key,

    GIT_Token,

    Base64로 인코딩된 kubeconfig 값

     

    여기서 Registry endpoint, GIT_Token은 같이 생성했으니, 나머지 key값과 kubeconfig 값을 가져오면 된다.

    key는 NCP콘솔 에서 생성 가능하다.

     

    Console - NAVER CLOUD PLATFORM

     

    kubeconfig 값은 Bastion에서 NKS(Naver Kubernetes Service)를 연동했다면 이미 ~/.kube/config 에 자동 생성되어있다.

    안했다면 어차피 helm으로 못올렸을 테지만, 공식 가이드는 올려두겠다.

    ncp-iam-authenticator 설치

     

    ncp-iam-authenticator 설치

    ncp-iam-authenticator 설치 Prev Next VPC 환경에서 이용 가능합니다. Ncloud Kubernetes Service는 ncp-iam-authenticator를 통해 IAM 인증을 제공합니다. IAM 인증을 통해 kubectl 명령을 사용하려면 ncp-iam-authenticator를 설

    guide.ncloud-docs.com

    IAM 인증 kubeconfig 생성 및 업데이트

     

    IAM 인증 kubeconfig 생성 및 업데이트

    IAM 인증 kubeconfig 생성 및 업데이트 Prev Next VPC 환경에서 이용 가능합니다. Ncloud Kubernetes Service는 IAM 클러스터 인증을 위해서 ncp-iam-authenticator를 사용합니다. ncp-iam-authenticator를 통해 IAM 인증이 적

    guide.ncloud-docs.com

     

    위의 설정이 되었다면 이미 생성된 kubeconfig 파일을 Base64로 인코딩 해주면 된다.

    굳이 Base64로 인코딩 하는 것은, 기존의 yaml파일을 그대로 올렸을 경우 파싱 에러에 취약하여 전 중에 온갖 기괴한 에러가 들러붙기 때문이다.

    cat ~/.kube/config | base64 -w 0

     

    이제 이 모든 값을 varialbes로 넣으면 된다.

     

     

    이런식으로 집어넣는데, 각 Key네임은 다음과 같이 생성했다.

    NCP_ACCESS_KEY: access_key

    NCP_SECRET_KEY: secret_key

    GIT_TOKEN: git token

    KUBE_CONFIG: kube config 값

    REGISTRY: container registry의 endpoint

     

    모두 중요한 정보이니, Masked와 Protect vatriable을 체크하는것을 권장한다.

     

    다 했다면 아래 그림처럼 생성 되었을 것이고, 바로 위의 Save 버튼을 통해 저장하면 된다.

     

     

    이제 gitlab-ci.yml을 작성할 차례이다.

    나는 Spring boot 프로젝트를 하나 만들고, 그곳에 간단한 html 파일을 넣었다.

     

    stages:
      - build
      - update-manifest
      - deploy
    
    # 각종 변수 선언
    variables:
      IMAGE_NAME: "cicd-demo-backend"
      GIT_USER: "root"
      MANIFEST_PATH: "cicd-demo-backend/deployment.yaml"
    
    build:
      stage: build
      image:
        name: gcr.io/kaniko-project/executor:v1.23.2-debug
        entrypoint: [""]
      script:
        - IMAGE_TAG="${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_IID}"
        - mkdir -p /kaniko/.docker
        - |
          echo "{\"auths\":{\"${REGISTRY}\":{\"username\":\"${NCP_ACCESS_KEY}\",\"password\":\"${NCP_SECRET_KEY}\"}}}" \
            > /kaniko/.docker/config.json
        - |
          /kaniko/executor \
            --context="${CI_PROJECT_DIR}" \
            --dockerfile="${CI_PROJECT_DIR}/Dockerfile" \
            --destination="${REGISTRY}/${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_IID}" \
            --verbosity=info
      only:
        - main
    
    update-manifest:
      stage: update-manifest
      image: alpine/git:latest
      script:
        - IMAGE_TAG="${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_IID}"
        - git clone http://${GIT_USER}:${GIT_TOKEN}@172.16.211.6/root/cicd-demo-k8s.git
        - cd cicd-demo-k8s
        - |
          sed -i "s|image: ${REGISTRY}/${IMAGE_NAME}:.*|image: ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}|g" ${MANIFEST_PATH}
        - git config user.email "gitlab-ci@cicd.com"
        - git config user.name "GitLab CI"
        - git add ${MANIFEST_PATH}
        - git commit -m "update image to ${IMAGE_TAG}"
        - git push http://${GIT_USER}:${GIT_TOKEN}@172.16.211.6/root/cicd-demo-k8s.git main
      only:
        - main
    
    deploy:
      stage: deploy
      image: bitnami/kubectl:latest
      script:
        - mkdir -p ~/.kube
        - echo "${KUBE_CONFIG}" | base64 -d > ~/.kube/config
        - git clone http://${GIT_USER}:${GIT_TOKEN}@172.16.211.6/root/cicd-demo-k8s.git
        - kubectl apply -f cicd-demo-k8s/cicd-demo-backend/ -n default
        - kubectl rollout status deployment/${IMAGE_NAME} -n default --timeout=300s
      only:
        - main

     

     

    하나씩 살펴보면 다음과 같다.

     

    # 각종 변수 선언
    variables:
      IMAGE_NAME: "cicd-demo-backend"
      GIT_USER: "root"
      MANIFEST_PATH: "cicd-demo-backend/deployment.yaml"

     

    여기서 GIT_USER는 root이니 root이고, IMAGE_NAME은 원하는 것으로 하면 된다.

    그리고 MANIFAST_PATH의 위치가 정의되어 있다.

    이 위치는 deployment가 올라갈 쿠버네티스 문서이다.

     

    즉, GitLAB의 프로젝트이며, 위의 .gitlab-ci.yml이 올라갈 프로젝트 말고, "cicd-demo-k8s" 프로젝트를 생성하고 프로젝트 내부에 "cicd-demo-backend/deployment.yaml" 파일을 생성해야 한다는 의미이다.

     

    build:
      stage: build
      image:
        name: gcr.io/kaniko-project/executor:v1.23.2-debug
        entrypoint: [""]
      script:
        - IMAGE_TAG="${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_IID}"
        - mkdir -p /kaniko/.docker
        - |
          echo "{\"auths\":{\"${REGISTRY}\":{\"username\":\"${NCP_ACCESS_KEY}\",\"password\":\"${NCP_SECRET_KEY}\"}}}" \
            > /kaniko/.docker/config.json
        - |
          /kaniko/executor \
            --context="${CI_PROJECT_DIR}" \
            --dockerfile="${CI_PROJECT_DIR}/Dockerfile" \
            --destination="${REGISTRY}/${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_IID}" \
            --verbosity=info
      only:
        - main

     

    Build는 kaniko를 사용한다.

    이미지를 push하기 위한 경량 오픈소스로, 이미지를 빌드하고 push할 뿐인데 docker같이 무겁고 복잡한 서비스는 필요 없기에 가벼운 kaniko를 사용한다.

     

    그리고 dockerfile이 있는 것을 볼 수 있다.

    Dockerfile은 backend에 함께 저장되어 있으며, 결과적으로 아래와 같은 구조를 가지게 된다.

    Dockerfile은 간단하게 작성하였다.

    FROM gradle:9.4.1-jdk17-jammy
    
    WORKDIR /app
    
    COPY . .
    
    RUN gradle clean bootJar --no-daemon -x test && \
        test -f /app/build/libs/app.jar || (echo "app.jar not found!" && exit 1)
    
    EXPOSE 8080
    
    ENTRYPOINT ["java", "-jar", "/app/build/libs/app.jar"]

     

     

    그 다음은 updatemanifest로, 별도의 cicd-demo-k8s 프로젝트의 cicd-demo-backend/deployment.yaml에 images의 태그값을 변경하여 push하는 동작이 있다.

     

    manifest파일을 업데이트 하지 않는다면 차후 연동할 ArgoCD나 쿠버네티스 자체에서 latest 태그가 고정되어 있기에 변화를 감지할 수 없는 상황이 생기므로 update를 추가하였다.

    update-manifest:
      stage: update-manifest
      image: alpine/git:latest
      script:
        - IMAGE_TAG="${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_IID}"
        - git clone http://${GIT_USER}:${GIT_TOKEN}@172.16.210.6/root/cicd-demo-k8s.git
        - cd cicd-demo-k8s
        - |
          sed -i "s|image: ${REGISTRY}/${IMAGE_NAME}:.*|image: ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}|g" ${MANIFEST_PATH}
        - git config user.email "gitlab-ci@cicd.com"
        - git config user.name "GitLab CI"
        - git add ${MANIFEST_PATH}
        - git commit -m "update image to ${IMAGE_TAG}"
        - git push http://${GIT_USER}:${GIT_TOKEN}@172.16.210.6/root/cicd-demo-k8s.git master
      only:
        - main

     

     

    코드를 보면 알겠지만, 결과적으로 두개의 레포지토리가 필요하다.

    1. 소스코드가 올라간 Spring boot의 레포지토리

    2. 쿠버네티스 정의 yaml파일이 올라간 레포지토리

     

     

    k8s에는 위에 환경변수로 정의한 "MANIFEST_PATH"처럼 cicd-demo-backend/deployment.yaml을 넣었다.

     

    그럼 동작을 하나씩 살펴보면,

     

    1. build에서 kaniko를 통해 어플리케이션을 빌드하고, dockfile을 통해 docker build한다.

    2. update-manifest에서 중복되지 않은 새로운 이미지 태그를 정의하고, git clone을 통해 k8s자원의 yaml파일을 clone한다.

    3. update-manifest에 이어서 해당 태그 값을 sed를 통해 수정하고, 수정된 값을 push한다.

    4. deploy에서 이전 variable로 넣었던 .kube/config를 통해 kubectl로 직접 apply 해서 적용한다.

     

    그리고 Dockerfile, 두개의 레포지토리(프로젝트), .gitlab-ci.yml 등 준비를 다 마치고 push한다면?

     

     

    오른쪽 오란색 아이콘으로 CI/CD 파이프라인이 동작중인걸 볼 수 있다.

     

    아이콘을 클릭하면 yml파일에 정의헀던 stages별로 동작을 확인할 수 있다.

     

     

    각 stage별로 클릭을 통해 진행상황을 볼 수 있다.

     

    그리고 레지스트리를 보면, 이쁘게 올라간 이미지를 볼 수 있다.

    'DevOps > Gitlab' 카테고리의 다른 글

    NCP(Naver Cloud Platform)을 활용하여 GitLab Runner로 CI/CD 구축  (0) 2026.05.26
    gitlab Check your sign-up restrictions  (0) 2026.05.22
    GitLab: Git 설정  (0) 2026.05.22
    GitLab 구축  (0) 2026.05.22

    댓글