AWS | NAT 인스턴스, S3, CloudFront, Lambda, MediaConvert구축
✅ NAT 인스턴스 생성
NAT는 사설 네트워크에 속한 여러 개의 호스트가 하나의 공인 IP 주소를 사용하여 인터넷 접속을 돕는다.
크게 3가지 특징을 가진다.
1. IP 주소 변환: NAT 인스턴스는 사설 IP 주소를 공인 IP 주소로 변환하거나, 반대로 공인 IP 주소를 사설 IP 주소로 변환.이를 통해 사설 네트워크 내부의 여러 장치가 하나의 공인 IP 주소 공유 가능
2. 보안: NAT 인스턴스는 외부와의 통신에서 사설 IP 주소를 노출시키지 않음
3. 포트 포워딩: NAT 인스턴스를 통해 특정 포트로 들어오는 외부 요청을 내부의 특정 장치로 전달 가능
물론 NAT Gateway 서비스도 있지만 비용 이슈로 인해 NAT 인스턴스로 진행을 하였다.
MobaXterm으로 접속한다.
다음의 명령어를 순차적으로 입력해준다.
[ec2-user@ip-10-35-11-187 ~]$ sudo hostnamectl set-hostname nat
[ec2-user@nat ~]$ sudo timedatectl set-timezone Asia/Seoul
[ec2-user@nat ~]$ sudo sysctl -w net.ipv4.ip_forward=1 # ip forward 기능 활성화
net.ipv4.ip_forward = 1
# 내부 -> 외부 라우팅 설정
[ec2-user@nat ~]$ sudo /sbin/iptables -t nat -A POSTROUTING -o enX0 -j MASQUERADE
[ec2-user@nat ~]$ sudo yum install -y iptables-services
[ec2-user@nat ~]$ sudo service iptables save # 변경사항 저장
private 라우팅 테이블을 생성하여 NAT 인스턴스를 통해 프라이빗 서브넷 안의 인스턴스 및 자원들을 접근할 수 있게끔 만들었다.
모든 위치에서 앞서 만든 NAT 인스턴스로 라우팅 되도록 구성한다.
변경사항을 적용하기 위해 NAT 인스턴스 클릭 후 > 작업 > 네트워킹 > 소스/대상 확인 변경 을 누른다.
소스/대상 확인 변경 메뉴에서 소스 또는 대상이 그 자체가 아닐 때 인스턴스가 트래픽을 송수신할 수 있도록 하기 위해 중지 버튼을 누른다.
동영상 저장소 구성하기
영상을 저장해야하는데 큰 용량의 파일이므로 저장소를 정하는 것이 중요하다.
다양한 저장소 중 s3를 선택한 이유는 사용이 간편하며 가용성이 높고 확장 가능한 데이터 저장소를 저렴한 비용으로 제공하며, S3 버킷이 자동으로 확장되므로 특정 저장 공간을 계획하고 할당할 필요가 없다.
대략적인 플로우는 아래와 같다.
1. 사용자가 mp4 영상을 업로드하면 1차적으로 s3 버킷에 저장된다.
2. S3에 영상을 올리면 -> Lambda가 트리거 이벤트를 발생시켜 원본 영상을 mediaConver에 전달한다.
3. 전달받은 MediaConvert는 HLS(Http Live Streaming) 확장자 파일을 생성하고 S3 버킷에 저장한다.
4. CloudFront 를 통해 사용자에게 HLS 확장자의 영상을 제공한다. 더불어 첫 시청시간인 만큼 CloudFront는 캐싱 처리한다.
✅ s3 구성하기
비디오 파일을 저장할 s3 버킷을 생성한다. 권한은 추후 수정할 예정이기에 임의로 생성해준다.
버킷 ARN을 복사하고 정책을 생성한다.
GetObject action을 추가한다.
Generate Policy를 생성한 뒤 하단의 JSON을 복사한다.
해당 코드를 붙여넣는다. Resource부분에 arn 뒤에 /* 를 붙여야 api에러가 나지 않는다.
✅ S3 수명 주기 규칙 생성하기
S3의 수명주기는 아래와 같이 설정하였다.
s3버킷에 저장된 데이터들은 30일 후 S3 Infrequent Access 버킷으로 이동하게 되고, 60일이 지나면 S3 Glacier로 이동한다.
수명주기 규칙 이름을 설정하고, 더 낮은 버킷으로 이동하기에 스토리지 클래스 간에 객체의 현재 버전 이동을 누른다.
CloudFront
응용 프로그램의 성능과 보안을 최적화하면서 비용을 효율적으로 관리하려면 Amazon CloudFront가 S3 버킷과 함께 작동하여 콘텐츠를 제공하고 보호하도록 설정하는 것이 좋다. CloudFront는 전 세계적으로 정적이며 동적인 웹콘텐츠, 비디오 스트리밍 및 API를 안전하고 규모에 맞게 제공하는 CDN (Content Delivery Network) 서비스이다.
CDN은 Content Delivey Networt로 정적 파일 (이미지, 동영상, CSS, JS 등) 호스팅을 하는 서비스이다.
AWS Cloudfront도 CDN 서비스이다. 이번 동영상 기능은 전 세계로 서비스되는 부분이기 때문에 원활한 영상 재생을 위해서라도 필요하다. 예를들어 지구 반대편 상파울로 사용자가 서울에 위치한 서버에 요청을 한다면 꽤 긴 통신을 해야하기 때문이다. 더불어 인터넷이 좋지 않은 국가들도 많기에 CDN을 통해 빠른 다운로드를 지원할 수 있다.
설계상으로는 CloudFront에서 데이터를 전달하는 것이 S3에서 사용자에게 직접 전달하는 것보다 비용 효율적일 수 있다. CloudFront는 에지 로케이션이라고 하는 전세계 데이터 센터 네트워크를 통해 콘텐츠를 제공한다. 에지 서버를 사용하여 콘텐츠를 캐시하고 제공하면 시청자가 있는 곳과 가까운 위치에 콘텐츠를 제공하여 성능을 향상시킬 수 있다. CloudFront는 다음지도에서 볼 수 있듯이 전세계 모든 지역에 에지 서버를 보유하고 있다.
사용자가 CloudFront에서 제공하는 콘텐츠를 요청하면 해당 요청은 근처의 에지 로케이션으로 라우팅된다. CloudFront에 요청된 파일의 캐시된 복사본이 있는 경우 CloudFront는 이를 사용자에게 전달하여 빠른 (대기 시간이 짧은) 응답을 제공한다. 요청한 파일이 아직 캐시되지 않은 경우 CloudFront는 오리진을 검색한다 (예 : 콘텐츠를 저장한 S3 버킷). 그런 다음 동일한 콘텐츠에 대한 다음 로컬 요청의 경우 이미 인근에 캐시되어 즉시 게재할 수 있다.
에지 로케이션에서 컨텐츠를 캐싱함으로써 CloudFront는 S3 버킷의 부하를 줄이고 컨텐츠를 요청할 때 사용자에게보다 빠른 응답을 보장한다. 또한 CloudFront를 사용하여 콘텐츠에 대한 데이터 전송은 S3에서 직접 파일을 제공하는 것보다 비용 효율적이며 S3에서 CloudFront에 대한 데이터 전송 요금은 없다. CloudFront에서 인터넷으로 전달되는 비용과 요청 수수료 (전체 가격정보 참조)만 지불한다.
더불어 콘텐츠 보호 기능을 제공한다. CloudFront를 사용하면 지역 제한, URL 지정 및 쿠키 지정과 같은 추가 액세스 제한을 설정하여 다른 기준에 따라 콘텐츠에 대한 액세스를 제한 할 수 있다.
CloudFront의 또 다른 보안 기능은 Origin Access Identity (OAI)이다. 이 기능은 S3 버킷 및 해당 콘텐츠에 대한 액세스를 CloudFront 및 해당 작업만으로 제한한다. 이 글의 CloudFormation 템플릿에는 콘텐츠가 보호되고 제한되도록 OAI가 포함되어 있다.
일반적인 웹 악용으로부터 보호하는 웹 응용프로그램 방화벽인 AWS WAF와 AWS에서 실행되는 웹 응용프로그램의 관리되는 DDoS 보호 서비스인 AWS Shield를 모두 통합한다. AWS WAF를 사용하면 IP 주소 또는 콘텐츠 요청의 쿼리 문자열 값과 같이 사용자가 지정한 조건에 따라 콘텐츠에 대한 액세스를 제어할 수 있다. 더불어 DDOs 공격을 받아도 실제 서비스 중인 회사 서버가 공격 받지 않고, CDN을 제공하는 서비스의 Edge가 공격 대상이 된다. 하나의 Edge에 과도한 트래픽이 몰리면, 근처의 Edge들에 분산 요청으로 과부하를 해결한다.
실험 결과를 보면 CloudFront가 있는 콘텐츠에 대한 첫 번째 GET 요청은 CloudFront가 없는 동일한 요청보다 약간 빠르다. 그 이후의 각 GET 요청은 훨씬 빠르다. 이것은 캐싱 때문이다. S3 버킷에서 제공되는 파일은 첫 번째 GET 요청 이후에 캐시되며 현재 테스트를 수행하는 곳과 가장 가까운 에지 로케이션에 저장된다. 때로는 파일이 100 배나 빠른 속도로 돌아온다.
✅ CloudFront 생성
OAI 생성
s3 버킷 액세스를 OAI 사용으로 변경한다.
버킷 정책을 편집하여 CloudFront를 통해 버킷에 접근할 수 있게끔 구성한다. 하단의 규칙을 추가하면 된다.
"Principle" : {
"AWS":"arn:aws:iam::cloudfront:user/CloudFront origin Access Identity {OAI ID}
}
그리고 버킷 URL을 통해 접근할 수 없도록 모든 퍼블릭 액세스 차단을 설정한다.
S3 객체의 URL을 통해 업로드한 이미지 파일에 접근해보면 access denied가 뜬다.
S3 CloudFront를 통해 S3 버킷에 업로드 한 이미지 파일에 정상적으로 접근 가능하다.
다이어그램으로 표현해보면 다음과 같다.
✅ MediaConvert 사용하기
사용자가 업로드한 mp4 파일을 hls로 변환시키고자 한다.
HLS는 HTTP으로 영상 스트리밍을 할 때 사용하는 프로토콜을 의미한다. HLS 프로토콜을 사용하면 네트워크 상태에 따라 영상 화질을 선택할 수 있는 Adaptive Bitrate Streaming(ABS)을 사용할 수 있다. 그리고 클라이언트에서 영상을 청크 단위로 쪼개서 다운받을 수 있고, 부분 재생을 할 수 있는 기능도 제공한다. 이러한 특징 덕분에 사용자는 영상 재생 시, 전체 영상 파일을 다운받지 않아도 되게 되었다. 특정 재생 위치부터 영상을 보게 되는 경우, 해당 위치부터 영상을 다운 받아 볼 수 있게 되었다.
HLS는 m3u8, ts 파일 두 가지로 구성되어 있다. m3u8은 영상 재생을 위한 메타 데이터로 대역폭별 m3u8 파일 경로, ts 파일 경로가 담겨있다. 대역폭마다의 설정이 담겨있기 때문에 m3u8이 네트워크 상태에 따른 영상 화질 선택 기능이 가능하다. ts 파일은 시간마다 쪼개져있는 실제 영상 데이터이다. ts 덕분에 부분 재생이 가능하다고 보면 된다.
.
우선 사용자가 업로드 하는 비디오를 저장할 input 폴더를 생성하고, 변환된 파일을 저장할 폴더 ouput을 만든다.
✅ IAM Role 생성하기
역할을 2개(MediaConvertRole, VodLambdaRole; lambda 실행) 생성해야 한다.
먼저 MediaConvertRole 생성한다.
MediaConvert를 선택하면 2개의 권한이 추가되어있다.
이름을 MediaConvertRole로 설정하고 생성한다.
생성된 역할에서 추후 Lambda 환경 변수 값을 넣기 위해 ARN 내용을 메모장에 복사한다.
Lambda를 사용할 역할 VodLambdaRole을 생성한다.
AWS 서비스 > Lambda 를 선택한다.
AWSLambdaBasicExecutionRole 권한을 추가한다.
VODLambdaBasicExec 이름으로 생성한다.
방금 만든 역할에 들어가 권한 > 인라인 정책 생성 에 들어간다.
JSON을 클릭한 다음 하단의 코드를 추가한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "Logging"
},
{
"Action": ["iam:PassRole"],
"Resource": ["이전에 생성한 MediaConvertRole의 ARN"],
"Effect": "Allow",
"Sid": "PassRole"
},
{
"Action": ["mediaconvert:*"],
"Resource": ["*"],
"Effect": "Allow",
"Sid": "MediaConvertService"
},
{
"Action": ["s3:*"],
"Resource": ["*"],
"Effect": "Allow",
"Sid": "S3Service"
}
]
}
다음처럼 4개의 권한이 보인다. 이름을 입력하고 다음을 누른다.
추가된 모습
✅ lambda 생성
파이썬 3.8 버전을 선택하고, 이름을 등록한 뒤 실행 역할은 앞서 만든 VODLambdaBasicExec 을 등록한 뒤 함수를 생성한다.
함수에 등록할 코드를 다음 github에 들어가 코드를 다운받는다.
https://github.com/aws-samples/aws-media-services-vod-automation
GitHub - aws-samples/aws-media-services-vod-automation: Sample code and CloudFormation scripts for automating Video on Demand wo
Sample code and CloudFormation scripts for automating Video on Demand workflows on AWS - GitHub - aws-samples/aws-media-services-vod-automation: Sample code and CloudFormation scripts for automatin...
github.com
해당 코드에서는 다음 4가지 화질을 만든다. (이것을 설정하는 파일은 job.json 인데 보면 상세히 알 수 있다.)
- HLS: 360, 540, 720
- mp4: 720
- 그 외 thumbnail(썸네일) 다수
MediaConvert-WorkflowWatchFolderAndNotification 폴더에 들어가면 convert.py 와 job.json 파일이 있는데 해당파일을 압축한다. 그냥 하단의 파일을 다운받기만 해도 된다.
그리고 zip 파일을 업로드한다.
코드가 등록된 것을 볼 수 있고 113번째, 114번째 라인을 주석처리한다.
런타임 핸들러 규칙은 파일명.메서드명 인데 업로드한 파일에서 convert.py가 그 역할을 할 것이고 그 안에 handler을 호출할 것이기 때문에 다음처럼 설정한다.
구성 > 환경변수 > 편집 에 들어가 런타임 설정 편집에 들어간다.
다음을 추가한다.
- Application = VOD
- MediaConvertRole = [위에서 등록한 MediaConvertRole의 ARN]
- DestinationBucket = [output 버킷이름]
트리거에 S3를 등록한다.
버킷명을 입력하고 이벤트 유형은 모든 객체 생성 이벤트로, 접두사에 input/을 입력한다.
cdn으로만 접근할 수 있도록 하단의 세개 권한을 차단시킨다.
"새 ACL을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단 권한" 은 mediaconvert가 s3에 접근해서 write를 해야하기에 하나는 허용해둔다.
객체 소유권은 다른 aws 계정에서도 소유권을 갖거나 접속 제어 가능 유무를 설정하는 권한이다. cdn 접속을 위해 acl 활성화를 시킨다.
✅ 테스트
input에 테스트 비디오를 업로드 해보자.
MediaConvert 작업란에 보면 input에 넣은 영상이 대기열에 들어간 뒤 변환 처리 되는 모습을 확인할 수 있다.
s3의 output의 폴더로 들어가면 HLS 파일로 쪼개진 것도 확인할 수 있다.
개발자 도구를 열어보면 cloudfront로부터 캐시된 데이터가 가져옴을 확인할 수 있다.
오픈스택 web과 연결하기
온프레미스 서버에서 s3에 영상을 업로드/다운로드 할 수 있어야 한다.
register-on-premises-instance 명령(IAM 사용자 ARN)을 사용하여 온프레미스 인스턴스를 등록합니다. - AWS C
온프레미스 인스턴스에서 액세스해야 하는 Amazon S3 버킷으로만 이 정책을 제한하는 것이 좋습니다. 이 정책을 제한하는 경우,AWS CodeDeploy 에이전트가 포함된 Amazon S3 버킷에 대한 액세스 권한도
docs.aws.amazon.com
✅ IAM 사용자 생성
먼저 CodeDeployUser-OnPrem 이름으로 IAM 사용자를 생성한다.
직접 정책 연결을 선택한 뒤 정책 생성을 누른다.
정책 > 정책 생성 에 들어간 뒤 하단의 코드를 넣어준다.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:Get*",
"s3:List*",
"s3:Put*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
CodeDeploy-OnPrem-Permissions 이름으로 정책을 생성해준다.
cli로 접근하기 위해 액세스 키를 생성해주어야 한다.
온프레미스로 접근할 예정이기에 aws 외부에서 실행되는 어플리케이션 옵션을 선택한다.
csv 파일을 다운받는다. 추후 aws-cli 접속 시 필요한 정보이다.
✅ aws-cli 설치하기
이제, 온프레미스 서버에 aws-cli를 설치해주어야 한다. 하단의 링크를 참고하였다.
https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html
최신 버전의 AWS CLI 설치 또는 업데이트 - AWS Command Line Interface
이전 버전에서 업데이트하는 경우 unzip 명령을 실행하면 기존 파일을 덮어쓸지 묻는 메시지가 표시됩니다. 스크립트 자동화와 같은 경우에 이러한 프롬프트를 건너뛰려면 unzip에 대한 -u 업데이
docs.aws.amazon.com
mobaxterm 을 이용하여 하단의 코드를 입력하여 설치를 진행한다.
설치가 완료되면 aws --version을 입력하였을 때 버전 정보가 뜨는 것을 확인할 수 있다.
[centos@web01 ~]$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
[centos@web01 ~]$ sudo yum install -y unzip
[centos@web01 ~]$ unzip awscliv2.zip
[centos@web01 ~]$ sudo ./aws/install
[centos@web01 ~]$ aws --version
aws-cli/2.11.18 Python/3.11.3 Linux/3.10.0-1160.80.1.el7.x86_64 exe/x86_64.centos.7 prompt/off
aws configure 설정을 먼저 해준다. key id, access key는 앞서 다운받은 csv 파일 참고하여 넣어주고, region은 위 경우 서울인 ap-northeast-2 를 입력해준다.
[centos@web01 ~]$ aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-2
Default output format [None]: json
aws s3 ls 를 통해 버킷을 확인해보면 정상적으로 뜨는 것을 볼 수 있다.
[centos@web01 ~]$ aws s3 ls
2023-05-09 06:12:01 team4-myvideo
업로드/다운로드 테스트를 진행해보았다.
> s3에 업로드
[centos@web01 ~]$ aws s3 cp s3://team4-myvideo/input/test.mp4 ./
download: s3://team4-myvideo/input/test.mp4 to ./test.mp4
[centos@web01 ~]$ ls
aws awscliv2.zip CodeDeploy-OnPrem-Permissions.json food.tar test.mp4 wordpress-4.8.2-ko_KR.zip
> s3로부터 다운로드
[centos@web01 ~]$ aws s3 cp uploadtest.mp4 s3://team4-myvideo/input/uploadtest.mp4
upload: ./uploadtest.mp4 to s3://team4-myvideo/input/uploadtest.mp4
✅ 솔루션의 장점
- 첫 달이 지나면 모든 객체가 S3 Intelligent-Tiering Infrequent Access 티어로 이동하고, 두 달이 지나면 객체들이 glacier로 이동하므로 스토리지 비용 절감 효과를 받을 수 있다.
- CloudFront CDN을 사용하여 비디오 제공 솔루션을 확장한다.
- S3 및 CloudFront 서명 URL을 사용하여 무단 액세스를 방지하고 고객의 애플리케이션 외부에서 재생할 수 없도록 비디오 컨텐츠를 보호한다.
- MediaConvert를 사용하여 비디오 콘텐츠를 자동 변환한다.
- 모든 네트워크 조건에서 버퍼링 지연 없이 재생할 수 있도록 적응형 비트 전송률 스트리밍을 사용하여 여러 장치를 지원한다.
참고
https://www.megazone.com/techblog_180716_a-match-made-in-the-cloud/
https://lemontia.tistory.com/1034