728x90

이제 본격적으로 프로젝트의 내용물을 채워보도록 하겠습니다. 별도의 외부 데이터베이스를 사용하지 않고 기본적으로 제공되는 파일 기반의 데이터베이스인 Sqlite 를 그대로 사용하도록 하겠습니다. 데이터베이스를 쓰기 위해서 먼저 기본 테이블을 생성해야 하는데요, Django 는 데이터베이스를 이용하는 것을 전제로 사용자와 사용자 권한 그룹 테이블을 알아서 만들어 주도록 되어있습니다. 

 

기본 테이블의 생성

기본 테이블을 생성하거나 프로젝트에 필요한 테이블을 생성하는 것 모두 manage.py 가 제공하는 명령어를 이용할 수 있습니다. 기본 테이블의 구조는 미리 정의가 되어 있기 때문에 모델을 만드는 작업을 하지 않고 사용이 가능합니다. 프로젝트의 루트 경로에서 manage.py migrate 명령을 사용하여 기본 테이블인 admin, auth, contenttypes, sessions 의 4개 테이블을 생성할 수 있습니다. 

% python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

migrate 명령이 수행되고 나면 settings.py 에 지정된 기본 데이터베이스 정보에 따라 Sqlite 용 파일이 프로젝트 루트 경로에 생성된 것을 보실 수 있습니다. 추후 Django 에 익숙해져 외부 데이터베이스를 사용하는 경우에는, 해당 데이터베이스 인스턴스에 4가지 테이블이 생성된다고 보시면 되겠습니다. 

 

프로젝트용 테이블의 생성 

기본 테이블은 Django 를 이용한 과제의 공통 테이블의 성격입니다. 수퍼 유저의 정보와 같은 것들이 이곳에 저장되는 것이지요. 실제 프로젝트에서 사용할 테이블을 정의하고 생성해야 하겠죠? 지난 포스팅 이후 뭘 만들어 볼까 고민하다가... 인터넷 서핑을 하면서 마음에 드는 이미지를 모아두는 서비스를 만들어 보면 어떨까 생각을 해보았습니다. (그닥 재미있어 보이진 않는군요...)

이미지의 이름 (Title) 과 이미지의 경로 (URL) 이고, 추후 검색 기능등을 넣기 위해 태그 (Tags) 정보를 입력받아 저장해보겠습니다. 지난 시간에 추가한 어플리케이션인 myfirstapp 폴더에 생성된 여러 파일들 중 models.py 를 열겠습니다. 이 파일에는 어플리케이션이 사용할 데이터, 테이블의 구조가 기술되며 이를 기반으로 manage.py 가 데이터베이스에 테이블 생성 작업을 대행해주기도 합니다. 

물론 별도로 데이터베이스를 수정하고 내용을 models.py 에 반영하는 것도 가능하지만 models.py 를 먼저 수정하고 manage.py 를 이용해서 데이터베이스 작업을 하는 것이 초보자에게는 좋다고 생각합니다. 사실 회사에서 과제를 진행하면서 migrate 과정에 대한 의문이 좀 많았는데 원격지의 리얼 데이터베이스를 쓰는 경우에는 migrate 을 잘 활용하는 것이 DBA 의 눈도 피할 수 있어서 좋을 것 같군? 하는 생각도 좀 들긴 합니다. 

 

이번 포스팅에서는 테이블 구조를 기술할 때 사용하는 django.db.models.Model 클래스를 자세히 살펴보지는 않겠습니다. 아직 공부를 못한 것도 있고 (퍽퍽...) 일단은 과제 하나를 잘 수행해 보는 것이 좋다고 생각하기 때문입니다 (후훗). 눈으로 보더라도 최대 길이라던가 빈 값의 허용, null 도 허용할 것인가와 같은 우리가 데이터베이스에서 테이블을 만들때 입력하는 정보들이 대부분 기술된다고 보시면 되겠습니다. 

Admin 사이트에 생성한 테이블 반영

admin.py 를 수정하면 생성한 테이블 정보를 django 가 제공하는 기본 어드민 페이지 (0.0.0.0:8000/admin) 에서 관리하거나 간단한 데이터 입출력 작업을 할 수 있게 됩니다. 지난 포스팅에서 이야기 했는지 기억이 잘 안납니다만 php 에서 쓰는 phpmyadmin 과 같은 역할이라고 생각하시면 편합니다. 우리가 생성한 어플리케이션인 myfirstapp 폴더 하위의 admin.py 를 열어서 아래와 같이 수정해 보겠습니다. 

 

테이블을 Sqlite 데이터베이스에 반영하려면 manage.py 가 제공하는 makemigrations 와 migrate 명령을 사용하게 됩니다. makemigrations 는 migrate 명령이 이해할 수 있도록 models.py 에 기술된 내용을 확인하고 현재의 데이터베이스와 비교하여 변경이 필요한 부분을 추출, python 코드로 만드는 역할을 수행합니다. migrate 은 이렇게 정리된 내용을 실제로 데이터베이스에 반영하는 역할을 하는 것이겠죠?

명령을 수행하기전에 어플리케이션 폴더인 myfirstapp 하위의 migrations 폴더를 살펴보면 __init__.py 파일만 존재하고 아무런 내용이 없는 것을 확인할 수 있습니다. makemigrations 명령을 수행한 후에 해당 폴더의 내용들이 어떻게 바뀌는지 살펴보도록 하겠습니다. 

 

명령을 수행하고 나면 myfirstapp/migrations 폴더에 0001_initial.py 라는 파일이 생성된 것을 볼 수 있습니다. 느낌은 첫번째 마이그레이션 작업이라는 느낌이죠? 이 파일을 열고 내용을 살펴보면 데이터베이스 작업에 필요한 파일로 조금전에 models.py 에 업데이트 했던 내용들이 들어가 있는 것을 확인할 수 있습니다. 

% python3 manage.py makemigrations
Migrations for 'myfirstapp':
  myfirstapp/migrations/0001_initial.py
    - Create model ImageCollector

 

이제 manage.py 의 migrate 명령으로 생성된 마이그레이션 작업 파일을 수행하여 데이터베이스에 반영되도록 하겠습니다. 기본 테이블로 생성한 admin, auth, contenttypes, sessions 에 대해서도 변경 사항이 있는지 점검하는 것을 볼 수 있습니다. ImageCollector 모델을 만들면서 지정한 max_length 지정 값은 auth 테이블에도 업데이트가 필요한 모양입니다. 알아서 잘 챙겨주니 참 고맙습니다. :-)

% python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, myfirstapp, sessions
Running migrations:
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying myfirstapp.0001_initial... OK

 

이렇게 이번 포스팅에서는 기본 테이블을 생성하고 프로젝트에서 사용할 테이블을 생성해 보았습니다. 이렇게 만든 테이블을 확인하는 쉬운 방법은 장고가 제공하는 Admin 사이트를 이용하는 것입니다. 다음 포스팅에서는 Admin 사이트 접근을 위한 수퍼유저 계정의 생성을 해보고 생성된 ImageCollector 테이블에 간단한 샘플 데이터를 넣어보도록 하겠습니다. 

728x90
728x90

개발을 전문으로 하고 있는 Role 이 아니다 보니 할 때마다 헷갈리는 깃. 그래서 이슈를 하나씩 해결 할 때마다 블로그 포스트로 정리를 하고 있습니다. 오늘은 같은 코드가 여러 원격 저장소에 있을때 각 브랜치를 로컬로 체크아웃하여 사용하는 방법에 대하여 정리를 해봤습니다. 


추가 원격 저장소 등록하기

우선 여러 원격 저장소가 있는 경우에는 각 원격 저장소를 로컬 저장소에 원격 저장소(Remote Repository) 로 등록을 해야 합니다. 원격 저장소를 등록하는 것은 git remote add 명령을 이용해서 추가해줄 수 있습니다. 이전 포스팅에 정리된 내용이 있으니 아래 글을 참고하시기 바랍니다

 

git & github / 포크한 저장소와 원본 저장소를 다시 동기화 하려면?

깃허브 Github 에 공개되어 있는 코드를 개량할 때, 회사의 Git 에 등록된 과제의 기능을 개발할 때 우리는 포크 Fork 를 통해 원격 저장소의 코드를 내 저장소로 옮긴후 작업을 하게 됩니다. 내 저장

ondemand.tistory.com

 

원격 저장소의 브랜치 정보 업데이트 

원격 저장소가 등록되었으면 이제 각 원격저장소의 브랜치 정보를 업데이트 해야합니다. git remote update 명령을 이용하면 현재 로컬 저장소에 지정되어 있는 모든 원격 저장소의 브랜치 정보를 업데이트 하게 됩니다. 아래와 같이 origin, CDN 이라는 두개의 원격 저장소가 지정되어 있다면 두 곳의 브랜치 정보를 가져오게 되는 거지요.

% git remote update
Fetching origin
Enter passphrase for key '/Users/nopd/.ssh/id_rsa': 
Fetching CDN
Enter passphrase for key '/Users/nopd/.ssh/id_rsa':

 

업데이트된 브랜치 정보의 확인

브랜치 목록이 잘 전달 되었는지를 확인하기 위해서는 git branch -a 명령을 사용하면 됩니다. 원격 저장소와 브랜치는 remotes/ 로 시작하는 브랜치들입니다. 실수 origin 브랜치에 만든 CDN/master 브랜치도 보이는군요. 

% git branch -a
* master
  remotes/CDN/master
  remotes/origin/HEAD -> origin/master
  remotes/origin/CDN/master
  remotes/origin/master

 

다른 원격 저장소의 브랜치 체크아웃하기

여러 원격 저장소를 사용할 때의 주의점은 이름의 충돌입니다. 요즘 논란이 되고 있는 이름이긴 합니다만 여전히 저의 많은 저장소들은 master 를 기본 브랜치로 사용하고 있습니다. 때문에 서로 다른 원격 저장소의 master 브랜치를 그대로 체크아웃 하는 경우에는 로컬 브랜치에서 충돌이 일어나게 됩니다. 

이를 막기 위해서는 체크아웃할 때 로컬 저장소의 이름을 [원격저장소이름/브랜치명] 의 네이밍 컨벤션을 따라가면 편리합니다. 다른 방법으로 해도 문제는 없지만 여러가지 방법중 원격 저장소의 이름을 앞에 넣어주는 것이 개인적으로는 가장 편리하고 헷갈리지 않았습니다. git checkout 명령에 -b 옵션을 주어 체크아웃 해보도록 하겠습니다. 

% git checkout -b CDN/master CDN/master
Branch CDN/master set up to track remote branch master from CDN.
Switched to a new branch 'CDN/master'

체크아웃 후 나온 메세지를 읽어보면 "CDN (저장소) 로부터 master 브랜치를 이용하여 (로컬 저장소에) CDN/master 라는 브랜치를 셋업 했습니다" 라는 내용입니다. 정확한 저장소로부터 브랜치를 가져온 것을 확인하실 수 있죠? 나오는 메세지가 영어라고 당황하지 마시고 항상 읽는 습관을 들이는 것이 좋습니다!

 

다른 원격 저장소의 브랜치 푸시하기

이렇게 다른 원격 저장소의 브랜치를 체크아웃 한 뒤에는 평소처럼 수정, 로컬 커밋을 하시면 됩니다. 그런데, 로컬 커밋을 완료한 후 원격 저장소에 다시 푸시하려면 어떻게 해야할까요? 뭔가 헷갈릴 때는 git push 명령만 입력하여 자세한 안내를 받는 것을 추천드립니다. 아래의 명령은 현재 브랜치를 확인한 후 원격 저장소에 푸시하기 위해 git push 명령을 입력하여 안내를 확인해 본 내용입니다. 

% git branch
* CDN/master
  master
  
% git push
fatal: The upstream branch of your current branch does not match
the name of your current branch.  To push to the upstream branch
on the remote, use

    git push CDN HEAD:master

To push to the branch of the same name on the remote, use

    git push CDN CDN/master

git push 명령을 인자 없이 입력했을 때 나온 안내 메세지도 읽어봅시다. fatal 이 떠서 왠지 무섭지만 "아주 주의해야 해!" 라는 의미로 받아들이시면 됩니다. 현재 로컬 저장소에서 작업중인 브랜치가 원격 저장소의 이름과 일치하지 않아 나온 경고입니다. 제 경우를 보면 원격 저장소 (CDN) 의 master 브랜치를 로컬 저장소에 CDN/master 로 체크아웃했으니 master <-> CDN/master 라고 보시면 됩니다. 

이를 푸시하는 방법을 두가지일텐데요, 원격 저장소의 master 브랜치에 바로 푸시를 하려면 첫번째 안내처럼 git push [#원격저장소명#] HEAD:[#브랜치명#] 을 쓰면 됩니다. 만약 로컬 저장소에서 지정한 이름인 CDN/master 를 새로운 브랜치로 만들면서 푸시하려면 두번째 명령의 가이드를 따르면 됩니다. 참 쉽죠!?

 

원격 저장소의 브랜치 엿보기만 하려면?

마지막으로 원격 저장소의 브랜치를 수정할 생각은 없지만 로컬에서 살펴보고 싶을때 쓰는 방법입니다. 이때는 git checkout 에 넣었던 -b 옵션을 빼주기만 하면 됩니다. 로컬에서 마음껏 수정해보고 커밋도 하다가 다시 동일한 브랜치를 체크아웃하면 변경 사항은 그대로 제거됩니다. 만약 수정한 내용을 보존하고 싶다면 새로운 브랜치로 만들면 되겠죠? git checkout 명령에 -b 옵션을 다시 넣고 새로운 브랜치명을 넣어주면 끝!

% git checkout CDN/master
Note: checking out 'CDN/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

 

728x90
728x90

웹 기반의 서비스를 제공한다면 SSL 인증서의 사용은 이제 필수 아니 기본이 되었습니다. Let's Encrypt 와 같은 선택지가 생기면서 비용때문에 SSL 기반의 HTTPS 통신을 제공하지 않는 다는 것은 더이상 변명이 되기도 힘든 시기입니다. 물론 서버의 성능 이야기를 한다면 <정말 아주 약간>의 배려를 해줄 수 있긴 합니다만 근래의 컴퓨팅 파워와 비용을 생각하면 그리 와닿지는 않는 변명입니다. 

이렇게 SSL 인증서 사용이 기본이 되고 있지만 SSL 인증서를 서버에 설치하고 적용하는 것은 여전히 까다롭습니다. 까다로운 것은 다름아닌 익숙하지 않음에서 비롯된다고 생각합니다. 개발은 늘 하는 일이지만 SSL 인증서는 아주 짧으면 3개월부터, 보통은 1년, 길면 2년정도 되어야 한 번 할까 말까한 작업이기 때문입니다. 눈치 채셨겠지만, 이 기간은 인증서를 교체해야 하는 주기와 일치합니다. 

이렇게 인증서가 잘 설치되었는지, 인증서에는 문제가 없는지 확인하는 것이 DevOps 시대에는 필수가 되었습니다. 그렇지만 언급했던 것처럼 <어쩌다 한 번 하는 작업> 이다보니 무언가 공부를 하기도 애매하고, 공부를 해두었다 하더라도 정작 필요한 시점에는 써먹지 못하는게 현실입니다. 여기에 더하여 운영중인 서버에 인증서를 적용하는 전후에 무엇을 어떻게 확인하는게 좋은지도 사실 적당한 레퍼런스가 없습니다. 


퍼블릭으로 공개된 서버의 인증서 점검

가이드 드리고 싶은 내용은 1) 운영중인 서버의 인증서 상황 점검과 2) 교체하려는 인증서 구성이 문제 없는지 어떻게 확인하는가 하는 점입니다. 1) 번과 같이 운영중인 서버의 인증서 상황 점검은 무척 쉽습니다. Mac 이나 Linux 환경을 사용하고 있다면 openssl 명령 혹은 어플리케이션을 이용하여 도메인 혹은 IP 를 가지고 있는 서버에 설치된 인증서를 쉽게 확인할 수 있습니다. 

// 인증서 정보 확인
% openssl s_client -connect www.naver.com:443

CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = KR, ST = Gyeonggi-do, L = Seongnam-si, O = NAVER Corp., CN = *.www.naver.com
verify return:1
---
Certificate chain
...

openssl 을 이용하여 `s_client` 옵션을 주고 `-connect` 에 확인하고자 하는 도메인 정보와 포트정보 (보통은 443이죠) 를 넣으면 구성되어있는 인증서 체인정보 (서버 인증서 > 중간 인증서 > 루트 인증서) 와 인증서의 상세한 정보를 확인할 수 있습니다. 웹 브라우저로 접근 가능한 HTTPS 를 사용하는 모든 도메인 / 서버에 대해서는 이 명령을 통해 인증서 정보를 확인할 수 있습니다. 

 

교체하려는 인증서 점검

인증서를 교체하기 위해서는 인증서 발급기관, 속칭 CA 로 부터 인증서를 발급받아 전달받게 됩니다. 보통 서버에 인증서를 설치하기 위해서는 1) 서버 개인키와 2) 서버 공개키 + 공개키를 인증할때 사용한 중간 인증서의 공개키를 합친 파일 을 서버에 설치하게 됩니다. 설치된 파일은 Apache Server 나 nginx 와 같은 웹 서버의 설정(configuration) 파일에 설치된 경로, 파일 정보, 사용할 Cipher Suite 정보등을 기술하게 됩니다. 

서버에 인증서 파일을 업로드 하고 설정 변경을 해서 아무런 문제가 없다면 얼마나 좋을까요? 결국 사람이 하는 일이다보니 실수가 생기거나 오류가 생기는 경우가 발생하곤 합니다. 그러면 드는 생각이 <교체하려는 인증서 파일을 미리 확인해 볼 수 없나?> 하는 것일겁니다. 앞서 본 것처럼 openssl 을 이용해서 파일 단위로 구성된 인증서를 미리 확인해보는 방법은 없을까요?

아래의 코드는 서버에 배포하기 위해서 중간 체인 인증서와 서버 인증서를 합친 파일을 점검해주는 간단한 스크립트 입니다. 서버에서 사용하고 있는 인증서를 `openssl s_client` 명령으로 확인한 것처럼 서버 인증서, 중간 인증서가 문제 없는지, 혹은 체인이 어떻게 구성되어 있는지를 확인할 수 있는 스크립트입니다. 참고로 스크립트의 출처는 kdecherf.com/blog/2015/04/10/show-the-certificate-chain-of-a-local-x509-file/ 입니다. 

#!/bin/bash

chain_pem="${1}"

if [[ ! -f "${chain_pem}" ]]; then
    echo "Usage: $0 BASE64_CERTIFICATE_CHAIN_FILE" >&2
    exit 1
fi

if ! openssl x509 -in "${chain_pem}" -noout 2>/dev/null ; then
    echo "${chain_pem} is not a certificate" >&2
    exit 1
fi

awk -F'\n' '
        BEGIN {
            showcert = "openssl x509 -noout -subject -issuer"
        }

        /-----BEGIN CERTIFICATE-----/ {
            printf "%2d: ", ind
        }

        {
            printf $0"\n" | showcert
        }

        /-----END CERTIFICATE-----/ {
            close(showcert)
            ind ++
        }
    ' "${chain_pem}"

echo
openssl verify -untrusted "${chain_pem}" "${chain_pem}"

스크립트를 만들고 chmod u+x #파일명# 으로 실행 가능하게 만드시기 바랍니다. 실행 가능한 스크립트가 되었다면 `./#스크립트파일명# #인증서파일명#` 형식의 명령을 통해 로컬에 존재하는 파일 형태의 인증서 + 중간 인증서를 s_client 옵션을 이용한 것처럼 검증할 수 있게 됩니다. 문제가 없다면 서버에 배포하고 웹 서버를 reload 하면 되겠지요!

728x90
728x90

CDN 의 핵심은 두가지입니다. 하나는 캐싱을 통한 사용자와 서버간의 거리 단축이고, 다른 하나는 사용자와 캐싱 서버 (=엣지 서버) 간의 거리를 줄여 불확실한 구간을 최소화 하는 것입니다. 이 두가지는 표현이 조금 다르고 추구하는 바가 달라보이기는 하지만 결국 <사용자의 지연 Latency 를 최소화 한다> 라는 공통된 목적을 가지고 있습니다. 

때문에 많은 CDN 벤더들은 계층형 캐시를 사용할 수 있는 방법을 제공하고 있습니다. AWS 에서 CloudFront 제품의 기능으로 새롭게 출시한 Origin Shild 도 계층형 캐시 기능이라고 보면 거의 맞습니다. 이름에서 느껴지는 것처럼 원본 (=Origin Server) 입장에서 봤을 때 제한적인 IP 에서만 접근이 이루어진다는 보안 관점의 효과를 제외하면 2차 캐시라고 봐도 무방합니다. 


AWS CloudFront 가 제공하는 계층형 캐시

AWS 의 CloudFront 는 컴퓨팅 자원들과는 조금 다른 리전을 기반으로 합니다. Edge Location 이라고 불리우는 이 리전들은 CloudFront 엣지 서버들과 Route53 의 자원들을 중심으로 일부 제품 기능을 수행하는 서버들이 위치한 리전입니다. CloudFront 로 일컫어지는 AWS 의 CDN 제품을 생각해보면 사용자로부터 1-hop 거리에 있는 캐시 서버가 동작하고 있는 리전이기도 합니다. 

일반적으로 이러한 Child Cache 서버들은 댓수가 많기 때문에 상대적으로 캐시 효율이 떨어질 수 있습니다. 캐시의 기본은 요청을 집중시키는 것이기 때문에 넓은 지역에 퍼져 사용자들로부터 적은 지연을 확보하는 것과 반비례 관계에 있습니다. 이를 보완하기 위해 AWS 의 CloudFront 가 제공하는 것이 REC, Regional Edge Cache 로 불리우는 상위 캐시 레이어입니다. 

출처 : AWS CloudFront 제품 소개 페이지 

AWS 에서 종종 봤을 위의 그림을 보면 Edge Location, 즉 사용자 접점의 캐시가 배치된 리전은 가능한 넓은 지역에 퍼져 있는 것을 볼 수 있습니다. 반면 오렌지색 원으로 표현된 Regional Edge Cache, 즉 상위 레이어의 캐시 혹은 2차 캐시는 특정 지역 (=보통 컴퓨팅 리전과 일치합니다) 에만 배치되어 있는 것을 볼 수 있습니다. 

일반적으로 Edge Location 에 비하여 REC 의 서버들은 스토리지 공간이나 컴퓨팅 파워가 더 우수한 것으로 알려져 있습니다. 요청들이 원본 서버로 전달되기 전에 한번 거쳐가는 레이어이기 때문에 더 여유로운 장비를 배치하는 것이 당연합니다. 이처럼 계층형 캐시를 제공함으로써 CloudFront 는 1) 원본으로 전달되는 요청을 줄이고, 2) AWS 네트워크 내에서 가능한 트랜잭션을 처리함으로써 사용자 입장에서 더 좋은 컨텐츠 전송 지연 경험을 해주도록 설계가 되어 있습니다. 

 

Origin Shield 도 REC다!?

이러한 CloudFront 의 구성에서 Origin Shield 는 어떤 차이를 가지고 있는걸까요? 결론을 먼저 이야기하면 Origin Shiled 도 REC 의 일부입니다. REC 는 앞서 보신 그림에서 나타난 것처럼 Edge Location 보다는 Pop이 적지만 여전히 여러 곳에 퍼져 있습니다. 이들 중 원본 서버에서 가까운 혹은 선호하는 REC 리전을 지정해 줌으로써 1) 사용자는 자신에게서 가까운 Edge Location 으로 접근, 2) Edge Location 은 캐시 효율을 위해 REC 에 접근, 3) REC 는 (도메인에 따라) Origin Shield 역할로 지정된 REC 에 다시 한 번 접근함으로써 캐시 효율을 높이고 원본 서버에게 제한적인 대역에서의 접근을 보장할 수 있게 됩니다. 

결국 Origin Shield 도 REC 라는 것이 여기에서의 한줄 요약입니다. 당연히 캐시 효율은 높아질 수 있고 원본에서는 접근하는 대역을 제한 함으로써 보안적인 효용을 얻을 수 있게 됩니다. 사실 REC 는 사용자가 사용 유무를 제어할 수 없다는 것이 한계였고, 상황에 따라서는 (보통은 no-store 성격의 컨텐츠 전송시) Edge Location 이 REC 를 경유하지 않는 경우가 발생하곤 했습니다만 Origin Shield 를 이용할 경우 지정된 REC 를 언제든 경유한다는 장점이 생기게 됩니다.

AWS Elemental 의 예이지만 일반 캐시도 다르지 않습니다

 

비용 계산은 어떻게 될까?

그렇다면 비용 계산은 어떻게 되는 걸까요? AWS 를 사용하면 참 편리하고 좋은 것들이 많지만 늘 걱정되는게 비용이기 때문에 비용은 확실하게 확인하고 넘어갈 필요가 있습니다. Origin Shiled 는 기본적으로 REC 이기 때문에 기존의 REC 의 가격 정책과 마찬가지로 과금을 안하는 것이 기본입니다. 다만, REC 가 요청량, 전송량 모두에 대해 별도 과금이 없는 것과 달리 Origin Shield 경유시 요청량에 대한 과금이 발생합니다. (전송량 단위의 과금은 없습니다)

AWS 의 가격 테이블을 확인해보면 어떤 리전에 위치한 REC 를 사용하는가에 따라 위의 테이블에 나온 것과 같은 요청량 기반의 과금을 하게 됩니다. 테이블에 나와 있는 가격은 1만개의 요청당 요금이기 때문에 사용중인 도메인에서 발생하는 원본으로의 요청이 얼마나 되는가가 과금에 영향을 주게 됩니다. 

여기서 또 중요하게 봐야 할 비용 관련 부분은 Origin Shield 로 지정된 리전이 2차 캐시 레이어로 활용되었는가? 하는 부분입니다. 앞서 언급드린 것처럼 Origin Shield 리전도 REC 이기 때문에, Edge Location 이 직접 Origin Shield 로 지정된 리전을 접근한 경우는 증분 레이어 Incremental Layer 로 인정하지 않아 과금되지 않습니다. 다만 다른 REC 를 경유해서 Origin Shield 로 지정된 리전에 접근했을 경우만 증분 레이어로 보고, 요청량을 카운트하여 과금하게 됩니다 

아따 복잡하다...

위의 설명에 나온 것처럼 1) 동적인 컨텐츠, 2) 캐시 컨텐츠 유무에 따라 과금 요청량 카운트는 또 달라집니다. 동적인 컨텐츠는 캐시되지 않기 때문에 언제나 Origin Shield 를 경유해서 원본으로 전송됩니다. 이 요청들은 모두 과금 대상 요청이 됩니다. 반면 캐시 가능한 컨텐츠의 계산은 조금 다릅니다. <캐시 가능한 요청수 x (1-캐시히트율) x REC 에서 Origin Shield 를 통해 원본으로 전송된 비율 x Origin Shield 과금 기준> 계산을 통해 과금 대상 요청량을 산정하게 됩니다. 

 

언제 쓰는게 유리할까?

AWS 는 과금 정책이 늘 복잡합니다. 이번에 공개된 CloudFront 의 Origin Shield 역시 마찬가지입니다. 그렇지만 CDN 좀 써본 분이라면 아시겠습니다만 2차 캐시의 효과는 요청량이 어느정도 된다면 가성비가 훌륭한편에 속합니다. CloudFront 에서도 2차 캐시를 잘 활용하고 싶다면 Origin Shield 를 써야할 것 같은데, 과연 언제 쓰는게 유리한걸까요?

첫번째 케이스로 실제 비용 청구를 따져보긴 힘들겠지만, 사용자의 경험 관점에서 1) 원본 서버가 위치한 지역에 대다수의 사용자가 위치해있고, 2) 일부 해당 지역외 사용자들이 서비스를 종종 이용할 때가 비용을 적게 들이면서도 효과를 볼 수 있는 대표적인 사례가 될 것 같습니다. 1) 에 해당하는 사용자들은 대부분 Origin Shield 레이어를 증분 레이어로 쓰지 않을거라 비용 추가 부담이 적을 겁니다. 2)에 대당하는 사용자들은 약간의 비용 기여(?)를 하겠지만 REC - Origin 구간의 네트워크에서 발생하는 불확실성을 줄여준고 캐시 효율을 높이는 관점에서 사용에 대한 의미가 있을거라 생각합니다.

이런 대표적인 시나리오에서는 확실히 써주는 것이 좋을거라 봅니다만 그 외의 케이스들에서는 일부 트래픽의 적용 등을 통해 검증이 필요합니다. 아시겠지만 모든 케이스에 두루 적용되는 솔루션은 현실 세계에서는 거의 없기 때문이겠지요. 새롭게 런칭된 AWS CloudFront 의 Origin Shield 기능을 통해 사용자 경험을 향상시키는 계기를 만들어 보시기 바랍니다.


Facebook 에서 CDN 과 관련한 이야기를 나눌 그룹을 만들어 운영하고 있습니다. 여러 CDN 벤더의 엔지니어들이 참여하고 계시기 때문에 많은 인사이트와 흥미로운 지식들을 얻어가실 수 있습니다. 

 

Facebook 그룹

한국 CDN 기술 연구회에 멤버 116명이 있습니다. 인터넷을 통한 컨텐츠 전송 기술에 대한 기술 모임입니다. CDN 을 아시는 분들 뿐만 아니라 "왜 인터넷이 느리지?"에 의문을 한 번이라도 가지셨던

www.facebook.com

 

CDN 요금 | 프리 티어 자격, 사용량에 따라 지불 | Amazon CloudFront

당사에 드는 비용에 따라 고객에게 청구하는 비용이 달라집니다. 따라서 일부 가격은 지리적 지역에 따라 다양하며 콘텐츠가 제공되는 엣지에 기반을 둡니다. 미래에는 CloudFront 네트워크에 추

aws.amazon.com

 

Using Amazon CloudFront Origin Shield - Amazon CloudFront

Using Amazon CloudFront Origin Shield CloudFront Origin Shield is an additional layer in the CloudFront caching infrastructure that helps to minimize your origin’s load, improve its availability, and reduce its operating costs. With CloudFront Origin Shi

docs.aws.amazon.com

 

 

728x90

+ Recent posts