방화벽 문제 등이나 기타 이유로 Elastic IP를 사용하는 서비스를 운영할 때 SPOF 발생
(과거 NAT Gateway가 생기기 전에 NAT Instance 단일 장애 지점 문제와 같은...ELB는 아직 EIP를 지원하지 않음)
1. 필요한 Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1491964068000",
"Effect": "Allow",
"Action": [
"ec2:AssociateAddress",
"ec2:DescribeAddresses"
],
"Resource": [
"*"
]
}
]
}
2. Role 생성(Trust relationsships)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
3. Lambda 구성
Lambda의 경우 세 가지 방법으로 Source를 등록할 수 있음. 직접, S3를 통해, ZIP 파일을 올리는 세 가지 방식 사용 가능.
node_module이 필요한 경우 ZIP 파일 형태로 Upload 해야 함. (Lambda 실행 파일은 index.js)
[ip, port, ec2Array 수정 필요]
3-1. Script(node v4.x)
config.json
{
"eip" : "13.124.48.32",
"port" : "8080",
"ec2Ids" : ["i-0a62787523bb4cdf1",
"i-0e57c7b10e4137a6d"],
"threshold" : 3
}
eip-swap.js (람다 핸들러 추가 필요 및 아직 Lambda에서는 ES6 지원하지 않음)
'use strict'
var AWS = require('aws-sdk');
AWS.config.region = 'ap-northeast-2'
var ec2 = new AWS.EC2();
var tcpp = require('tcp-ping');
var waterfall = require('async-waterfall');
var CronJob = require('cron').CronJob;
var sleep = require('system-sleep');
var async = require('async');
var config = require('../config/config.json');
var ec2Describe = function(eip, callback){
const params = {
}
ec2.describeAddresses(params, function(err, data){
if(err) console.log(err, err.stack);
else{
for(var i = 0; i < data.Addresses.length; i++){
if(data.Addresses[i].PublicIp == eip){
callback(data.Addresses[i]);
}
}
}
});
}
var tcpChecker = function(eip, port, callback){
tcpp.probe(eip, port, function(err, result){
callback(result);
});
}
var ec2AssociateAddress = function(allId, ec2Ids, ec2Id){
var ec2TargetId = '';
(ec2Id == ec2Ids[0]) ? ec2TargetId = ec2Ids[1] : ec2TargetId = ec2Ids[0]
var params = {
AllocationId: allId,
InstanceId: ec2TargetId
}
ec2.associateAddress(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}
waterfall(
[
function(callback){
const ec2info = config;
callback(null, ec2info);
},
function(ec2info, callback){
var tcpCheckNum = 0;
for(var i=0; i < ec2info.threshold; i++){
tcpChecker(ec2info.eip, ec2info.port, function(result){;
result ? null : tcpCheckNum++;
});
sleep(10000); //tcp module default timeout 5s, sleep time > 5s
}
console.log(tcpCheckNum);
(tcpCheckNum == ec2info.threshold ) ? callback(null, ec2info) : callback(null);
},
function(ec2info, callback){
ec2Describe(ec2info.eip, function(data){
callback(null, ec2info, data);
});
},
function(ec2info, ec2Address, callback){
ec2AssociateAddress(ec2Address.AllocationId, ec2info.ec2Ids, ec2Address.InstanceId);
callback(null, 'done');
}
], function(err, result){
if(err) console.log(err);
else console.log(result);
}
)
3-2. Lambda Configuration
3-3. Lambda trigger(5분마다 실행) / (CloudWatch Event Rules은 미리 생성)
3-4. Test
10초 주기로 3번 체크 후 3번 모두 실패했기 때문에 eip-swap 진행. 실제 EC2 Instance를 확인하면 EIP가 swap 됌.
Log는 CloudWatch Logs에서 확인 가능.
4. 정리
Lambda를 통해 AWS API를 호출하고 AWS 서비스 관리가 가능. (apex, node-lambda 와 같은 lambda 배포/테스트 도구 및 모듈이 존재)
참고로 리매핑 비용(월 최초 100번 이상)이 $0.10 이니 요금 폭탄을 안 맞도록 조심...)
추가로 Lambda에 VPC를 지정하면 Internet 구간 통신 불가. (AWS API 호출 및 Public IP TCP Check 불가능)
no vpc 혹은 VPC 내의 NAT Gateway를 통해 가능.
'Compute > Lambda' 카테고리의 다른 글
AWS Lambda@Edge Redirect / Add Custom Header (0) | 2021.10.08 |
---|---|
AWS Lambda Edge를 이용한 이미지 리사이징 (0) | 2019.12.26 |
AWS Lambda 활용 태깅 없는 EC2 Instance 정지 (0) | 2017.11.14 |
AWS Lambda를 이용하여 Security Group 자동 제어 (0) | 2016.10.21 |
AWS Lambda를 이용하여 S3 업로드된 파일 meta-data 변경 (0) | 2015.11.18 |