CDN Purge(퍼지) 자동화, 소스 배포 시 수정/삭제 되어진 컨텐츠를 캐시 서버에 자동으로 갱신하기

devforest443·2023년 12월 21일
0

log 2021. 2. 23. 21:00

비효율적인 캐시 갱신

CDN 오리진 서버에 소스 배포가 완료되고 캐시 서버에 이미 캐싱된 소스 파일이 있을 경우
캐싱된 컨텐츠를 강제로 삭제하고 오리진 서버로부터 변경된 컨텐츠를 새로 가져오려면
Purge(퍼지)를 진행하는데, 퍼지를 진행하는 과정이 비효율적으로 진행되어 소요시간도 길고
작업자의 피로도가 높아져 퍼지 작업을 자동으로 실행할 수 있도록 하기로 하였다.

As-is

갱신된 파일의 서비스되는 주소를 모두 확인해야 했고, CDN 서비스를 이용하는 업체마다
퍼지 진행을 위한 파일 주소를 입력하는 규칙이 달랐으며 서비스 국가마다 다수의 CDN 서비스사를 이용하고 있었고, 한 서비스에 두개의 CDN 서비스를 연결되는 경우 두개의 서비스사 모두에 퍼지를 진행하게 되는 이슈로 비효율적인 작업이 계속되었다.

  • Gitlab CI/CD를 통하여 CDN 오리진 서버에 소스 배포
  • 갱신된 파일 확인
  • 갱신된 파일 주소 확인
  • CDN Purge 서비스 접속
  • CDN 관리자 계정 로그인
  • CDN 서비스 Purge 규칙에 따른 파일 주소 입력 후 퍼지 진행

To-be

  • Gitlab CI/CD를 통하여 CDN 오리진 서버에 소스 배포
  • CDN 오리진 서버에 소스를 배포하는 명령어에 퍼지도 명령도 함께 포함하여 갱신된 파일을 퍼지 진행한다.

배포/CDN Purge(퍼지) 자동화 환경 구성도

1. deploy.py

배포를 위한 자격증명 옵션과 기존에 사용하던 ftp Client lftp man 명령어를 포함하고, 각 CDN 서비스사에서 제공하고 있는데 API 문서를 바탕으로 작성된 퍼지 명령어를 포함하고 있다.

1.1 배포 옵션 인자값 설정

parser.add_argument('--host', '-L', required=True, help='FTP host or ip')
parser.add_argument('--port', '-p', required=True,
                        type=int, help='FTP port')
parser.add_argument('--user', '-l', required=True, help='User')
parser.add_argument('--password', '-w', required=True, help='Password')
parser.add_argument('--source', '-s', required=True, help='Source')
parser.add_argument('--dest', '-d', required=True, help='Destination')
parser.add_argument('--exclude', '-x', help='Excludes(b.png;*.db)')
parser.add_argument('--purge-host', '-ph',
                        help='PurgeHost http://,https:// 없이')

1.2 CDN 서비스사 인자값 설정 예시

CDN 서비스를 추가시 서비스사에서 제공하는 API를 확인 후 필요한 인자값을 설정한다.

tencent = parser.add_argument_group('tencent')
tencent.add_argument('--tencent-secret', '-ts')
tencent.add_argument('--tencent-secretkey', '-tk')

1.3 배포 커맨드 라인 설정

cmd = f'lftp -e "set file:charset utf-8; open ftp://{args.user}:{args.password}@{args.host}:{args.port}; mirror -R -n -v -p {args.source} {args.dest} --delete {exclude}; exit"'

1.4 CDN 각 서비스사 퍼지 함수 작성

서비스사에서 제공하는 API를 참고하여 작성한다.

def purge_tencent(prams): 

1.5 퍼지 함수 명령 실행 코드 추가

Removing old file, Removing old directory 문구가 있으면 해당 파일 또는 디렉터리 전체 퍼지를 진행한다.

   if str.startswith("
   Removing old file, "):
            files.append(dest + '/' + re.findall(r"`(.*?)'", str)[0])
        if str.startswith("Removing old directory"):
            dirs.append(dest + '/' + re.findall(r"`(.*?)'", str)[0])
            
if host is not None and args.tencent_secret is not None and args.tencent_secretkey is not None:
        purge_tencent(args.tencent_secret,
                      args.tencent_secretkey, host, files, dirs)

2. Dockerfile : 도커 이미지 빌드 스크립트 파일 작성

repository, 설치할 패키지, 배포 코드와 설정 파일, 컨테이너 가동시 실행될 명령어를 한다.
필요한 패키지와 명령어 lftp, python3-pip, pip3, deploy.py를 포함하고 있다.

COPY ./sources.list /etc/apt/
RUN apt-get update && apt-get install -y \
    lftp \
    python3-pip \
 && rm -rf /var/lib/apt/lists/*

COPY ./pip.conf /etc/xdg/pip/
RUN pip3 install requests tencentcloud-sdk-python-intl-en

COPY deploy.py /usr/local/bin/deploy.py
RUN chmod +x /usr/local/bin/deploy.py

3. GitLab Runner Docker 이미지 빌드

3.1 gitlab-ci.yml

variables:
  REGISTRY_IMAGE: ****
  CI_REGISTRY: ****

docker-build:
  # docker image.
  image: $CI_REGISTRY/docker:latest
  stage: build
  services:
    - $CI_REGISTRY/docker:dind
  before_script:
    - docker login -u docker-user -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY:port
  script:
    - docker build -t "$CI_REGISTRY:port/$REGISTRY_IMAGE:$CI_COMMIT_TAG" .
    - docker push "$CI_REGISTRY:port/$REGISTRY_IMAGE:$CI_COMMIT_TAG"
  only:
    - tags

4. 프로젝트 배포 파이프라인

4.1 Default gitlab-ci.yml

variables:
    GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH

stages:
    - deploy
    

deploy_prod:
    stage: deploy
    script:
        - echo "Deploy to production server"
        #- lftp -e "set file:charset utf-8; open ftp://$PROD_FTP_ACCOUNT:$PROD_FTP_PASSWORD@$PROD_FTP_HOST:$PROD_FTP_PORT; mirror -R -n -v -p $CI_PROJECT_DIR/directory /directory/directory --delete -X *.md -X *.db -X *.yml -X *.git/ -X @html/; exit"
        - deploy.py -L $PROD_FTP_HOST -p $PROD_FTP_PORT -l $PROD_FTP_ACCOUNT -w $PROD_FTP_PASSWORD -s $CI_PROJECT_DIR/directory -d /directory/directory -x '*.md;*.db;*.yml;*.git/;.gitignore;@html/;' -ph $PURGE_HOST -ts $TENCENT_PURGE_SECRET -tk $TENCENT_PURGE_KEY 
    environment:
        name: production
        url: http://domain.co.kr/path/
    when: manual
    only:
        - master

4.2 Configure runner behavior with variables

variables:
    GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH

4.3 GitLab CI/CD pipeline stage

stages:
    - deploy

4.4 Jobs

variables:
    GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH

stages:
    - deploy
    

deploy_prod:
    stage: deploy
    script:
        - echo "Deploy to production server"
        #- lftp -e "set file:charset utf-8; open ftp://$PROD_FTP_ACCOUNT:$PROD_FTP_PASSWORD@$PROD_FTP_HOST:$PROD_FTP_PORT; mirror -R -n -v -p $CI_PROJECT_DIR/directory /directory/directory --delete -X *.md -X *.db -X *.yml -X *.git/ -X @html/; exit"
        - deploy.py -L $PROD_FTP_HOST -p $PROD_FTP_PORT -l $PROD_FTP_ACCOUNT -w $PROD_FTP_PASSWORD -s $CI_PROJECT_DIR/directory -d /directory/directory -x '*.md;*.db;*.yml;*.git/;.gitignore;@html/;' -ph $PURGE_HOST -ts $TENCENT_PURGE_SECRET -tk $TENCENT_PURGE_KEY 
    environment:
        name: production
        url: http://domain.co.kr/path/
    when: manual
    only:
        - master

4.4 Job keywords

4.5 Job script - Python deploy.py

CDN 퍼지 자동화를 위해 CI 배포 서버에 gitiab-runner 도커 이미지를 추가 하고, gitlab-runner 도커 이미지에 lftp, deploy.py 포함시켜서 빌드한 후
프로젝트에 해당 gitlab-runner를 연결해서 .gitlab-ci.yml 파일의 스크립트를 실행하여 배포한다.

gitlab-runner에 deploy.py 가 포함되어 있기 때문에 .gitlab-ci.yml 에서 바로 실행할 수 있다.
deploy.py 파일 내 퍼지 API 호출하는 코드가 포함되어 있으며, lftp 스크립트 또한 포함되어 있다.
lftp 옵션 추가/변경을 하고 싶을 경우 deploy.py에 추가하여 빌드 한후 러너를 재시작한다.
lftp로 업로드 하고 변경, 삭제등의 동기화가 완료 된 후 'Removing old directory `xxx' 문자 표기 되는 파일은 자동으로 퍼지가 진행된다.

퍼지 옵션

deploy.py에서 설정한 인자값

  • -ph : 퍼지 호스트
  • -ts : cdn 서비스사 인자값
  • -tk : cdn 서비스사 인자값

인자값에 대한 값은 CI/CD Variables (환경 변수) 목록으로 관리한다
ex) $PURGE_HOST, $TENCENT_PURGE_SECRET, $TENCENT_PURGE_KEY

deploy.py 기본적인 스크립트 형식은 아래와 같다.

- deploy.py -L $PROD_FTP_HOST -p $PROD_FTP_PORT -l $PROD_FTP_ACCOUNT -w $PROD_FTP_PASSWORD -s $CI_PROJECT_DIR/directory -d /directory/directory -x '*.md;*.db;*.yml;*.git/;.gitignore;@html/;' -ph $PURGE_HOST -ts $TENCENT_PURGE_SECRET -tk $TENCENT_PURGE_KEY

4.5 GitLab CI/CD script syntax

참조

운영 후..

각 프로젝트마다 배포 스크립트를 업데이트하고 해당 스크립트에 각각 cdn 퍼지 옵션을 추가하는데
투입되는 시간이 있었지만, 기존에 국가별 서비스별로 다른 cdn 사이트에 모두 각각 접속하여 로그인하고 수동으로 캐시된 파일의 주소를 입력하고 퍼지를 진행하던 과정이 CI/CD > Pipelines 배포 버튼만 클릭하면 한번에 이루어져 장기적인 운영에 큰 도움이 되었다.

profile
devforest443

0개의 댓글