...
서버리스라고 해서 간편하게 함수에 코딩만 하고 트리거로 AWS 서비스와 연동한뒤 배포만 하면 될 줄 알았더니, 람다 함수 버전이라던가 별칭이라는 생소한 요소에 당황하였을 테지만, 람다의 버저닝과 별칭은 전혀 새로운 개념이 아니다.
람다는 EC2 같이 컴퓨팅이 아니라 코드 베이스 단이다.
즉, 언제어디서 소스 코드(함수)를 업데이트 할 수 있으며, 업데이트된 함수 서비스를 소비자에게 제공하게 된다.
그러다 업데이트된 함수 코드에 문제가 생기면 롤백을 하던지, 버그 수정을 하고 다시 새로 배포하던지..등, 람다 함수를 보다 체계적인 관리를 해야하는 형상 관리가 필요해지게 된다.
형상 관리라고 하니 개발자이신 독자분의 머릿속엔 한가지 단어가 떠올랐을 것이다.
그렇다 GIT 이다. 람다의 버저닝은 GIT의 버저닝 기능을 클라우드에 그대로 가져온 것이라고 보면 된다.
우리가 프로젝트 소스를 배포 브랜치와, dev 브랜치로 나누고 커밋으로 소스 코드를 업데이트 하고 관리하듯이, 람다 함수들을 버저닝을 통해 형상 관리를 람다 버전 기능을 통해 한다고 보면 된다.
그럼 람다 별칭(alias)는 무엇일까?
위와 같이 람다의 버전 기능을 GIT 커밋에 비유했다면, alias는 GIT의 tag 기능과 유사하다. (혹은 GIT의 브랜치와도 비슷하다)
GIT 태그가 없어도, GIT을 이용하는데는 전혀 문제가 없지만 수백수천개의 커밋들을 일일히 커밋번호를 보며 관리하는 것보다 태그로 명확하게 커밋을 관리하는 것이 좋기 때문에 자주 쓰이는 것 같이, 람다 버전 들을 배포 같은 프로세스에서 편하게 관리하기 위해 쓰인다고 보면 된다.
그리고 람다에서 정말 자주 보는 $LATEST 라는 단어는 GIT의 HEAD 와 유사하다고 보면 된다. $LATEST는 최신 람다 함수 버전을 뜻하며, GIT HEAD 역시 최신 커밋을 가리키는 것이기 때문이다.
람다의 버전과 별칭 기능에 대해서 친숙하게 접근하게 하기 위해 GIT을 빗대어 설명하였지만 사실 차이점도 꽤 있다.
우선 GIT 같은 경우 과거의 커밋 이력을 조회해 수정하고 다시 커밋 뒤 머지 하는 식으로 형상 관리가 되지만, 람다에서는 버전을 롤백할 수 없으며 버전 이력 역시 수정할수 없다.
람다 버전이 생성되면 현재 lambda의 snapshot을 만들었다는 뜻으로 읽기 전용으로 되기 때문이다.
그래서 이전 람다 코드를 수정하려면 내용을 무조건 $LATEST로 복붙해서 옮기고 새 버전을 올리고 별칭으로 최신 버전을 가리키도록 일일히 조정을 해야하는 약간의 불편함이 존재한다.
람다 버젼(version) 사용해보기
우선 람다 함수 코드를 다음과 같이 구성한다.
exports.handler = async (event, context) => {
const response = {
statusCode: 200,
body : `람다 버전 1 : ${context.invokedFunctionArn}` // 람다 arn 출력
};
return response;
};
이제 현재 람다 함수 코드의 새 버전을 발행해보자.
람다 버전을 발행하면, 람다 함수 콘솔 메뉴의 버전 메뉴로 진입하게 된다 (처음에는 약간 화면 구성이 생소할수 있다)
코드를 수정해보려고 하면 수정이 안된다.
버전은 배포의 개념이지 개발의 개념이 아니기 때문이다. 따라서 코드 버그 수정 같은 일이 있을 경우, $LATEST로 가서 코드 수정을 하고 새로 배포를 하는 식으로 해야된다.
버전 1을 생성했으니, 코드를 수정하고 새로운 버전 2를 또 생성해보자.
exports.handler = async (event, context) => {
const response = {
statusCode: 200,
body : `람다 버전 2 : ${context.invokedFunctionArn}` // << 코드 수정
};
return response;
};
이렇게 하나의 람다 함수에 버저닝 기능을 사용해 보았다.
당연히 각 람다 함수 버전 1과 버전 2는 서로 소스코드가 다르다.
다만 GIT 커밋 같은 경우, 이전 커밋한 버전으로 git checkout HEAD~n 명령어를 통해 이동해 소스를 수정할수 있지만, 람다는 이전 버전으로 되돌아간다는 개념은 없고, 과거 소스 수정 역시 불가능하다.
따라서 이전 이력을 관리하고 싶은 경우, 별칭(alias)를 이용해야 한다.
람다 별칭(alias) 사용해보기
람다 별칭 생성
위에서 버전1 과 버전2를 생성한 상태에서 이어 나간다.
별칭 dev를 생성해줬으면 별칭 prd를 추가로 생성해준다. 이때 prd는 버전 1에 연결되도록 한다.
현재 람다의 별칭과 버전 상태를 그림과 표현 하자면 다음과 같이 된다.
dev가 가리키는 $LATEST는 배포 함수용이 아닌, 소스 수정이 있을 경우 코드를 업데이트하고 지속적으로 버전을 올리는 용도이다.
그리고 prd가 가리키는 버전 1은 배포용 함수용으로서 실질적으로 고객이 이용하는 람다 서비스 부분이 되게 된다.
이처럼 GIT에서 master 브랜치와 dev 브랜치를 나누고 태그를 걸어두어 관리하듯이 람다도 보다 체계적으로 소스(함수)를 관리한다고 보면 된다.
immutable : 불변 (소스를 수정 못하니까)
람다 별칭으로 배포
지금까지 람다를 배포할떄 그냥 바로 트리거에 연결해서 사용해왔을 것이다.
따지고보면 람다 $LATEST 버전에 바로 배포하는 형식으로 이용 해온 것이다.
간단한 토이 프로젝트일 경우 문제는 없겠지만 큰 서비스의 경우 곧바로 $LATEST로 배포해버리면 나중에 수정, 관리가 매우 힘들어진다. 따라서 위에서 람다 함수 버전에 별칭을 지정함으로서, 이 별칭을 트리거에 연결해서 실질적으로 배포를 하게 된다.
별칭 prd 람다를 트리거를 이용해 배포해보자.
API 게이트웨이의 엔드포인트로 접속해보면, prd 별칭의 버전 1 람다 함수가 실행되게 된다.
그리고 arn을 보면 끝에 람다함수명:별칭 식으로 표기가 됨을 확인 할 수 있다.
그러다가 함수 코드를 업데이트 해서 버전 2를 배포했다고 가정해보자 (위에서 이미 배포함)
그러면 간단하게 별칭이 가리키는 함수 버전을 수정하면 간단하게 업데이트 배포가 된다.
람다 별칭 가중치
별칭 테이블을 자세히 보면, 버전 컬럼 부분에 (가중치=100%) 라고 적혀있는데 이게 무엇을 뜻하는 것일까?
만일 엔드포인트로 prd 람다로 접속하면 100% 확률로 버전 2 함수로 보내 코드를 실행시킨다는 뜻이다.
그럼 가중치를 50%로 설정하면 어떻게 될까? 어렵게 생각할 필요없이 반의 확률로 코드를 실행하고 나머지 반은 코드를 실행하지 않는 다는 소리이다. (직관적으로 이해하면 된다)
이 가중치 라는 기능은 왜 있을까?
그것은 람다 함수 버전을 단계적으로 안정적으로 배포하기 위해서이다.
위에서 prd 별칭에 연결된 함수 버전을 버전 1에서 바로 버전 2 로 업데이트하고 배포했었다. 하지만 만일 함수 버전 2 에 확실한 안정성을 보장할 수 없을때 (하지만 실질적인 사용자 경험이 필요해 배포를 해야 할때) 어떻게 할까?
이런식으로 안정적인 버전 1에는 90% 가중치를 두고, 아직 안정성을 보장받지 못한 버전 2에는 10%의 가중치를 줘서, 클라이언트에서 10번중에 9번은 버전 1로 접속해 실행하게 하고, 10번 중에 1번은 버전 2로 접속해 실행하도록 할 수 있다.
위 그림을 보니 마치 로드밸런싱 처럼 보이는데, Lambda의 로드밸런서 함수 버전이라고 이해해도 무리가 없다.
이런식으로 가중치를 설정하고 로드밸런싱을 함으로써, 버전 2에 어떠한 오류 현상이 발견되지 않으면 100%로 설정 하는 식으로 보다 안정적이고 체계적으로 관리를 할 수 있게 된다.
이제 실전으로 가중치를 구성해보자. 방법은 어렵지 않다.
그리고 아까 등록했던 API Gateway 엔드포인트로 접속해보면, 랜덤으로 버전 1 과 버전 2 함수에 로드밸런싱이 됨을 확인 할 수 있다.
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.