카테고리 Archives: AWS

AWS 상에서의 API Gateway – Lambda – python – pymysql – rds(mariadb) 구현

aws 에서는 API Gateway 를 제공 한다.

이는 serverless 기반의 API 생성 및 운영을 손쉽게 할 수 있는 서비스 이다. (근데 손쉽지 않더라..)

물론 굉장히 난해 하고 어렵지만 처음 한걸음은 항상 어려 웠다 ‘ㅅ’a (이 산을 넘으면 devops 가 되는 첫걸음이 된다.)

 

aws-api-lambda-python-rds

위 이미지 생성은 클라우드크래프트 (https://cloudcraft.co/) 에서 진행 하였다. (AWS 아키텍쳐를 짜는데 매우 유용함.)

 

즉 restful API 를 AWS 상에서 API gateway 와 Lambda 서비스를 이용하여 구축 하여 운영하는 것이다.

이미 이와 같은 많은 글을 참고 하였으나 대부분 아마존에서 제공 하는 nodojs 를 활용하는 방법만 존재 하더라…


1. Lambda 에서 함수를 생성 한다.

2020-08-07_154033


2. 함수가 생성 되면 기본 설정에서 함수의 제한 등을 확인할 수 있다.

핸들러의 의미는 함수가 실행되었을때 lambda_function.py 한의 def lambda_handler() 를 실행한다는 의미가 된다.

(물론 편집도 된다. DB 접근 시간이 있기 때문에 제한시간을 10~15초로 늘린다.)

2020-08-07_162631


3. 스크롤을 올려 보면 AWS Cloud 9 IDE 의 간소화 버전을 이용하여 수정을 할 수 있다.

2020-08-07_163001


4. Test 버튼을 눌러 테스트 셋을 생성 한다. (이미지는 없음)

테스트를 위한 좀더 많은 json 은 https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/sample-apps/nodejs-apig/event.json 에서 확인할 수 있다.

다시 TEST 버튼를 눌러보면 실행 API Gateway 에 연결 되었을때 실행 후 결과 값이 확인 된다.

2020-08-07_164220

함수 생성이 완료 되었지만 Hello World 를 보려고 이것을 하는게 아니기 때문에 API의 근본 목적인 데이터베이스 접속을 할 차례이다 ‘ㅅ’a


배포용 코드 작성은 AWS cloud 9 IDE 를 통해 작성을 할 예정이다. (일반적인 linux 나 windows 환경에서도 가능하다.)

물론 Cloud 9 을 통해 lambda 배포가 가능하지만 단순 소스 작성을 위해서만 이용할 예정 이다 ‘ㅅ’a  (이걸 하려면 또 Cloud Fomation 을 해야 하기 때문에…)

Lambda 에서는 일부 json, logging 등을 별다른 설정 없이 import 할 수 있지만 pymysql 과 같은 서버에 별도 설치가 필요한 부분은 같이 업로드가 되어야 한다.

때문에 아래와 같이 pymysql 설치를 한다.

db 정보를 저장할 dbinfo.py 파일과 AWS lambda 핸들러에서 지정된 lambda_function.py 파일을 같이 생성 한다.

위와 같이 작성을 하고 zip 파일로 압축을 한다.

압출한 파일을 AWS 웹콘솔 에서 업로드 한다.

2020-08-07_173321

zip 파일이 압축 해제가 되며 lambda001 아래에 파일 및 폴더가 위치 할 수 있는데 아래와 같이 드래그 앤 드롭으로 맞추어 준다.

아니면 기본설정-핸들러를 lambda_function.lambda001.lambda_handler 으로 바꾸어도 될꺼 같기도 하다 ‘ㅅ’a

2020-08-07_174505


데이터베이스의 경우 보안 때문에 IP를 막고 일부만 열어서 서비스 하는것이 일반적이기 때문에 실행하는 람다를 VPC 내에서 실행 되게 해야 한다.

그래서 생성한 lambda 함수가 자신의 VPC 에서 네트워크 인터페이스를 사용할 수 있는 권한을 주어야 한다.

2020-08-07_175052

화면 최상단의 권한 으로 이동하고 실행 역할(IAM role) 을 눌러 해당 정책에 정책 추가를 진행해야 한다.

아래의 권한으로 정책을 새롭게 생성해서 연결 해도 되고 인라인 정책 추가를 해도 된다.

추후 생성되는 Lambda 함수는 권한 부분에서 기존 역할로 이미 VPC 권한이 부여된 역할을 선택 해주면 좀더 편하게 사용할 수 있겠다.

2020-08-07_175631


lambda 실행될 VPC 에 대한 정보를 설정해 주어야 한다.

2020-08-07_180250

2020-08-07_180507

사용자 지정 VPC 지정과 VPC 지정 subnet 지정(2개 이상) 과 EC2보안그룹을 지정 하면 된다.


그리고 RDS 서버의 보안그룹에서 위에서 lambda 가 사용할 것으로 지정된 두개의 서브넷(172.31.0.0/20, 172.31.16.0/20)을 허용한다.

2020-08-10_113634


테스트를 달려 본다.

2020-08-07_181235

앗싸 가오리!


너무 길어져서 API 게이트웨이는 나중에 추가 할 예정이다 =_=a

팔로우 할때 주의 할점은 API 게이트 웨이의 리소스 > 메소드 에서 “통합 요청”의 유형이 LAMBDA 가 아닌 LAMBDA_PROXY 으로 해야 하는 python 코드 이다.

MDS / Zombie Load 취약점

Intel CPU 에서 또다른 취약점인 MDS 취약점이 공개 되었다.

심각도는 impotant 이며 CVE-2018-11091, CVE-2018-12126, CVE-2018-12127, CVE-2018-12130 항목이다.

KISA 공지 사항: https://www.boho.or.kr/data/secNoticeView.do?bulletin_writing_sequence=35030

 

CPU 캐쉬내 데이터는 적재한 프로세스가 아닌 다른 프로세스에서 엑세스 할 수 있는 취약점이다.

 

중요도가 높다보니 취약점 패지가 이미 배포 되어 yum 업데이트만으로 해결이 가능하다.

업데이트 항목이 kernel 과 intel-microcode 다 보니 재부팅이 필요 하다.

 

음 AWS 서비스의 경우 아래와 같이 안내 되어 있다.

https://aws.amazon.com/ko/security/security-bulletins/AWS-2019-004/

AWS has designed and implemented its infrastructure with protections against these types of bugs, and has also deployed additional protections for MDS

All EC2 host infrastructure has been updated with these new protections, and no customer action is required at the infrastructure level

 

뭐 AWS 인프라 레벨에서 MDS 취약점을 처리 하였으니 유져가 EC2 호스트에서 별도로 조취할 필요가 없다고 한다 🙂

랄라~

AWS 인스턴스 시작, 중지 스크립트

aws cli 명령어를 이용하여 ec2 서버를 껏다 켰다 하는 스크립트 이다.

일반 환경에서는 불필요 하고 개발 환경의 서버를 24/7 을 켜둘 이유가 없다.

개발자의 개발 환경을 고려하여 월~금 사이 AM 8:50 ~ PM 18:30 까지 만 사용 한다면 1일에 10시간만 사용함으로서 청구금액을 낮출 수 있다.

t3.medium ( 2 Core / 4G-RAM ) = 시간당 US$ 0.0416

0.0416 * 24 * 365 = $364

0.0416 * 10 * (365 / 7 * 5) = $108

* 예약 인스턴스 (Reserved instances) 를 사용한다면 더 낮출 수 있다.(30% ~ 63%) *

 

그래서 상시 떠있어야 하는 product 레벨의 서버 라든가 syslog 서버 등에서 아래와 같이 스크립트를 작성 하고 운영 하여 절감을 한다.


서버가 UTC 으로 세팅 되어 있는 서버 이기 때문에 cron 등록은 아래와 같이 진행하였다.

(cron : 50 23 * * 0-4 bash /shell/aws-start-instance.sh ) 월~금 KST AM 08:50 분에 작동

(cron : 30 09 * * * bash /shell/aws-start-instance.sh ) 매일 KST PM 18:30에 작동


인스턴스 자동 시작 스크립트 ( /shell/aws-start-instance.sh )


인스턴스 자동 정지 스크립트 ( /shell/aws-start-instance.sh )

 

AWS 의 EBS 스냅샷

현재는 EC2의 Lifecycle manager 의 등장으로 인해 오래된 snap-shot 의 삭제가 자동으로 이루어 지기 때문에 크게 필요가 없는 스크립트 이다.

물론 Lifecycle manager 에 비해 기능이 좀더 많다.

AWSCLI 를 사용하기 때문에 설치가 필요로 하다 ‘ㅅ’a

 

기능적으로는 아래와 같다.

1. AWS_REGION_ARR 에 선언된 리전을 타겟으로 한다.

2. RETENTION_LIMIT 에 지정된 일자(7개월) 만큼 매월 1일 데이터를 보관한다.

3. RETENTION_DAILY 에 지정된 일자(1개월) 만큼 매일 데이터를 보관한다.

4. BACKUP=ON 이 선언될 경우 작동중인 인스턴스의 모든 EBS 볼륨의 snap-shot을 생성한다.

5. SC_MODE=TEST 가 실제 작동이 아닌 어떤 작동을을 하게 될지 echo로 출력한다.

 

AWS 클라우드 인스턴스 크기 선택

물리서버에서 오랜 경험이 있는 엔지니어의 경우

일반적으로 서버 사양 선택을 직접 하지 않거나 구매 시점의 가장 가성비가 좋은 일반적인 구매(보통 판매자 추천) 사양을 사용하여

서비스 구현을 하기 마련이므로 클라우드 진입을 고려할때 일반적으로 인스턴스 크기 선택 장애가 발생 한다.

 

그럼 클라우드로 넘어갈때 가장 중요한 인스턴스 선택은 무엇으로 해야 하는가?

 

1. 웹서버 ( prefork )

웹서버는 일반적인 운영 환경에서는 1% 미만의 load 가 발생한다.

마더 프로세스 에서 차일드 프로세스를 호출하기때문에 기본적으로 멀티쓰레드화 되어 있다.

mod_php 를 사용할 경우 메모리 사용량은 프로세스당 14.7MB 정도이다. (물론 더 커지기도 한다.)

HTTPD 메모리 사용량 체크

Prefork 기본 mpm 설정상 150 커넥션을 활성화 하기 때문에 2,100MB 의 메모리 용량이 필요로 하다.

구글링을 통해 검색하여 max client 값을 1024 등으로 설정 했다면 최소 15G 의 메모리를 필요로 한다. (저런거 따라하지 맙시다.)

MaxConnectionsPerChild 는 지정된 횟수 만큼의 커넥션을 처리하고 프로세스가 종료 되고 새로운 차일드가 생성되도록 하는 옵션이다.

프로세스는 어려 작업을 실행함에 따라 메모리 사용량으 증가하고 이 값을 0 으로 하거나 너무 크게 잢을 경우 메모리 부족에 허덕이게 된다.

반면 너무 작게 할경우 차일드를 종료 하고 새롭세 스폰 할때 오버 헤드가 발생하여 cpu 사용량을 늘어나 악 영향을 준다.

prefork 에서의 추천하는 값은 5000 정도…

 

2. 웹서버 ( Worker / EVENT )

Worker/event mpm의 경우 기본적으로 250 커넥션을 가지며 1개의 차일드가 25개의 커넥션을 담당 한다.

즉 10개의 차일드가 각각 25커넥션을 담당 하며 각 차일드의 메모리 사용량은 적당한 평균치가 없다. 너무 격차가 심하기 때문에..

다만 사용하는 메모리는 prefork 대비 작은편이고 약 1024 커넥션의 경우 12기가 정도의 메모리 사용량을 확인한 적이 있다.

MaxConnectionsPerChild 는 약 50000 정도가 적당 하였다.

 

3. 웹서버 ( nginx )

메모리 사용량은 비 튜닝 기준으로 120~150MB 정도 이다.

일반적으로 정적 데이터 처리 및 Revers Proxy 용도로 사용 했다.

rewrite 룰셋을 바꿔야 하는 불편한 점이 있기 때문에 다중 사이트 보다는 한개의 사이트를 운영하기엔 유리 하다.

 

4. 웹서버 ( tomcat )

tomcat 은 기본값으로 200 connect 를 처리할 수 있으며 메모리 사용량은 500 MB 이상이며 일반적인 사용에서 900MB 정도의 메모리 사용량을 보인다.

 

5. DB 서버( mysql )

cpu와 메모리를 많이 사용한다.

프로세스를 보고 있으면 50% 는 기본적으로 먹고 간다. 기본값에서는 기본 메모리 500M 정도를 사용하고 DB가 증가함에 따라 사용량이 늘어 난다.


AWS 클라우드 에서 범용 상품군은 크게 T2, m4, m5, c4, c5 이다.

이중 t2 상품군의 경우 기본적으로 다른 상품군 보다 저렴 하지만.. cpu 과점이 될경우 추가 사용료가 청구 된다.

 

AWS 테스트 서버를 올리고 (일반적으로 freetier 인 t2.micro) 사용하다 방치하게 될 경우 해킹을 통해 CPU 가 과점상태가 되어 막대한 추가 비용이 발생 한다.

 

CPU가 과다 사용되는 DB 서버의 경우에는 c4, c5 상품군 혹은 r4 상품군이 적합하다고 볼수 있다.

( RDS 서비스도 좋다. ec2 직접 구성 보단 약 10%~20% 가량 비싸지만 백업등등 생각하면 동등 하다고 본다. )

웹서버는 과도한 로드가 발생하지 않을 경우 t2 에서 충분하다 (cpu가 nano = 5% / micro = 10% 미만으로 사용 해야 한다.)

표는 aws 메뉴얼에서  확인할 수 있다.

 

리눅스는 기본적으로 자체 커널을 위해 약 300M~500M 정도의 메모리 사용한다.

nginx + php 만 구성하여 웹서버를 구성하면 약 t2.micro/t2.small 정도면 충분하다.

예약 인스턴스 (1년 선납) 을 한다고 하면 약 40% 정도 할인이 된다. (3년은 60% 정도 할인…)

2018-07-23_144957

한 서버에 DB 및 웹서버를 사용하려면 t2.medium 정도는 사용해야 한다. (cpu 크레딧 사용량이 40% ) ( $504.576 )

그이상은 t2.lager 부터는 전혀 효용 가치가 없다 다른 상품군( m5.lager )이 가성비가 더 쓸만하다고 생각된다.

 

스타트업 기업에서는

t2.medium/c5.lager 으로 LAMP (Linux – Apache – Mysql – PHP)  로 사용하다가

추후 DB 를 분리한다는 구조로 가는게 적합 한듯 하다.

1 클라이언트는 서버에 8개의 tcp 를 동시 접속 하기 때문에 ServerLimit 는 8배로 지정 한다. (최대값 2000)

(4G 메모리 분배 : 커널 500M / Mysql 1G / Apache 2G / 버퍼 500M ) ( 동시 접속자수( Maxclient: 130 // ServerLImit : 1040 ) 정도의 값을 지향한다.
(8G 메모리 분배 : 커널 500M / Mysql 2G / Apache 4.2G / 버퍼 800M ) ( 동시 접속자수( Maxclient: 320 // ServerLImit : 2000 ) 정도의 값을 지향한다.

 

기존 물리서버에서 클라우드로의 이행을 생각한다면 위 표를 참조로 필요 대수와 발생 금액등을 생각한다.

물리서버의 평균 수명인 3년 금액 과 클라우드 3년 사용료를 비용 을 대조 하고

클라우드의 +@인 관리 편의, 백업 편의, 가용성 등을 고려하여 잘 생각한다.