-
Notifications
You must be signed in to change notification settings - Fork 6
AWS
https://bit.ly/_AWS_ 을 브라우저에 입력해서 이곳으로 올 수 있어요.
이 수업은 웹애플리케이션을 클라우드 플랫폼인 AWS 위에서 구동하는 방법을 익힙니다. 단순한 웹애플리케이션이 복잡해지는 과정에서 클라우드 컴퓨팅이 어떤 장점을 제공하는지를 경험해보는 수업입니다.
- aws에 회원가입합니다.
- git을 설치합니다. https://git-scm.com/ (git과 vscode를 동시에 설치하지 마세요)
- vscode( https://code.visualstudio.com/ )를 설치합니다. portable 버전은 설치하지 마세요.
웹 기본 강의 : https://opentutorials.org/course/3084
AWS 기본 강의 : https://opentutorials.org/module/3814
더 많은 강의는 지식지도 서말 (https://seomal.com/map/1/35)을 통해서 찾을 수 있습니다.
수업에서 사용되는 예제는 아래 경로의 저장소에 있습니다. http://bit.ly/aws-example-
웹의 기초를 학습합니다.
index.html
<html>
<body>
<h1><a href="index.html">CLOUD</a></h1>
<ul>
<li><a href="s3.html">S3</a></li>
<li><a href="ec2.html">EC2</a></li>
</ul>
Welcome Cloud
</body>
</html>s3.html
<html>
<body>
<h1><a href="index.html">cloud</a></h1>
<ul>
<li><a href="s3.html">s3</a></li>
<li><a href="ec2.html">ec2</a></li>
</ul>
<h2>S3</h2>
S3 is simple storage service.
</body>
</html>ec2.html
<html>
<body>
<h1><a href="index.html">cloud</a></h1>
<ul>
<li><a href="s3.html">s3</a></li>
<li><a href="ec2.html">ec2</a></li>
</ul>
<h2>EC2</h2>
EC2 is Elastic Compute Cloud.
</body>
</html>클라우드 컴퓨팅은 IaaS, PaaS, SaaS로 나눌 수 있습니다.

S3는 AWS의 파일 서버입니다.
- PaaS에 대한 이해
- 클라우드의 편의성에 대한 공감
- 버킷을 생성한다.
- 버킷으로 파일을 업로드 한다.
- 파일을 다운로드 한다.
- 파일을 누구나 다운로드 할 수 있도록 한다. => 권한 : 모든 퍼블릭 엑세스 차단 해제 => 퍼블릭으로 지정
- 웹서버로서 s3를 사용한다.
- 요금체계 : https://aws.amazon.com/ko/s3/pricing/
- 클래스별 요금 체계 : https://bit.ly/37TQ4lv
- 가용성과 내구성
- S3의 클래스 변경
- IaaS에 대한 이해
- 컴퓨터를 임대하는 개념에 대한 이해
리눅스의 주요명령을 사용할 수 있어야 합니다.
- 현재 디렉토리 확인 :
pwd - 파일 확인 :
ls - 디렉토리 생성 :
mkdir - 디렉토리 이동 :
cd - 디렉토리 및 파일 삭제 :
rm - 원격제어 :
ssh -i key.pem ubuntu@ip - 업로드 :
scp -i key.pem * ubuntu@ip - VI
- ESC => 명령어 모드
- i => 입력 모드
- x => 한글자 cut
- dd => 한줄 cut
- u => undo
- :w => 저장
- :q => 종료
- :wq => 저장 & 종료
- 인스턴스를 생성한다. (ubuntu 20 이상 버전을 사용해야 EC2 instant connect를 설정없이 사용할 수 있습니다)
- EC2 instance connect로 접속한다.
- sudo apt update; sudo apt install apache2 : Apache2 설치
- cd /var/www/html : 웹페이지가 위치하는 폴더로 이동한다.
- 웹사이트에 접속해본다. => 접속이 안된다.
- Security Group을 설정한다. => http 인바운드를 80번 포트로 변경한다.
- 웹서버에 접속한다. => 접속이 된다.
- sudo rm index.html : 웹페이지를 삭제해본다. => 페이지를 찾을 수 없다고 나온다. 이 파일이 홈페이지임을 확인한다.
- sudo nano index.html : 웹페이지를 만들고 다시 접속해본다.
- EC2의 가격 정책을 확인한다.
- Edge, Region에 대한 이해
- CDN에 대한 이해
- 분산된 인프라의 효용에 대한 이해

- Distribution 생성
- Origin : 도메인 지정
- Cache and origin request settings => Create a new policy => Minimum TTL => 300
- http load test global 과 같은 검색어로 도구를 찾아서 속도 테스트를 한다.
- ex : https://tools.keycdn.com/performance
- 직접 EC2에 접속하는 것과 cloud front를 통해서 접속하는 것 사이의 성능 차이를 확인해본다.
- 가격 정책을 확인한다. https://amzn.to/3kz34Ci
backend, middle, php, application server의 개념을 이해한다.
sudo apt update && sudo apt install php- remote :
sudo chmod -R 777 /var/www/html# 실습의 편의를 위해서 보안을 낮은 수준으로 설정했습니다. 현실에서는 이렇게 하면 안됩니다. - https://bit.ly/3kDhrp1 를 만든다.
- local :
scp -i key.pem * ubuntu@ip:/var/www/html# 로컬의 수정 파일을 원격 저장소로 업로드 한다. -
tail -f /var/www/apache2/error.log: apache, php의 오류를 출력한다.
- 데이터베이스의 이해
- 클라우드 환경에서 운영하는 방법의 이해
- RDS 인스턴스 생성
- 제품 : MySQL
- 모드 : 프로덕션
- 마스터 사용자 이름과 마스터 암호 입력 - admin, qwertyuiop (절대로 실제 서비스에 이런 아이디/비밀번호를 이용하면 안됩니다)
- DB 인스턴스 크기 : 버스터블 클래스 - micro
- 스토리지 : 마그네틱
- 가용성 및 내구성 : 대기 인스턴스를 생성하지 마십시오.
- 접속
-
apt install mysql-client: mysql client 설치 -
mysql -uadmin -p -hdatabase-1.cdbrt00yi2pa.ap-northeast-2.rds.amazonaws.com=> 접속 안됨 - EC2 인스턴스의 보안그룹 이름을 RDS VPC 보안 그룹의 허용 엑세스 포인트로 등록
- 예: MySQL/Aurora, port : 3306, source : sg-051d8bcb0def21458
-
mysql -uadmin -p -hdatabase-1.cdbrt00yi2pa.ap-northeast-2.rds.amazonaws.com=> 접속 됨
-
- 데이터베이스 생성
CREATE DATABASE mydb;
- 데이터베이스 선택
use mydb;
- 테이블 생성
CREATE TABLE topic(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, title char(20) NOT NULL, description TINYTEXT, thumbnail varchar(200) NULL);
- 데이터 입력
INSERT INTO topic (id,title,description) VALUES(1, 'S3', 'S3 is ..');
INSERT INTO topic (id,title,description) VALUES(2, 'EC2', 'EC2 is ..');
INSERT INTO topic (id,title,description) VALUES(3, 'CF', 'CF is ..');- 데이터베이스를 웹프로젝트에 도입
- 데이터베이스를 이용하는 이유에 대한 이해
-
sudo apt install php-mysql: php & mysql 연동 -
sudo service apache2 restart: apache2 재시작 - index.php
<?php
$conn = mysqli_connect('database-1.cdbrt00yi2paz.ap-northeast-2.rds.amazonaws.com', 'admin', 'qwertyuiop', 'mydb');
$sql = 'SELECT * FROM topic';
?>
<html>
<body>
<h1><a href="/index.php">CLOUD</a></h1>
<ul>
<?php
$query = mysqli_query($conn, $sql);
while($row = mysqli_fetch_array($query)){
?>
<li><a href="index.php?id=<?php echo $row['id'];?>"><?php echo $row['title'];?></a></li>
<?php
}
?>
</ul>
<?php
if(empty($_GET['id'])){
?>
Hello is ..
<?php
} else {
$query = mysqli_query($conn, "SELECT * FROM topic WHERE id = ".$_GET['id']);
$result = mysqli_fetch_array($query);
?>
<h1><?php echo $result['title'];?></h1>
<?php echo $result['description']; ?>
<?php
}
?>
<?php
print($_SERVER['SERVER_ADDR']);
?>
</body>
</html>- 더 높은 사양의 인스턴스로 교체한다. 이때 ip 주소가 변경되는 문제는 도메인 주소를 부여하는 것을 통해서 ip 주소의 변동성에 대응 할 수 있다.
- EC2 인스턴스를 이미지로 만든다. # 이미지가 생성될 때 접속이 잠시 끊길 수 있다.
- 보안 그룹이 RDS에 연결될 수 있도록 조치한다. 이전 인스턴스의 보안 그룹을 재사용하는 것이 바람직하다.
Scale up은 하나의 컴퓨터 사양을 높이는 방법이고, Scale out은 여러대의 컴퓨터가 협력해서 하나의 일을 수행하도록 하는 방법이다.
- EC2
- AMI 이미지를 이용해서 인스턴스 두개를 만든다. RDS에 접속이 가능한 보안그룹을 선택하거나 설정한다.
- 웹페이지의 내용을 구분할 수 있도록 각 서버의 ip address 가 출력되도록 한다. 예)
- Target group
- 타겟 그룹은 ELB에 장착될 인스턴스들을 지정한다.
- 타겟그룹을 생성한다.
- 그룹의 이름을 지정한다.
- 인스턴스 2개를 타켓으로 지정한다.
- Elastic Load Balancer
- ELB를 생성한다.
- Application Load Balancer를 선택한다.
- ELB의 이름을 지정한다.
- Listener의 포트를 81로 지정한다. : 80번 포트를 여러 요소에서 쓰고 있으므로 차이를 비교 할 수 있게 일부러 80번 포트를 쓰지 않았다.
- VPC는 기본, 가용 영역은 모든 곳을 지정한다.
- 새로운 보안 그룹을 생성한다. 이떄 81번 포트가 개방되어 있는지 확인한다.
- 라우팅 단계에서 대상 그룹을 기존 대상 그룹으로 지정하고, 이전 단계의 타겟그룹을 선택한다. 이 때 포트가 80인 것에 주목한다. 여기서 80은 origin 쪽의 인바운드 포트의 번호이다.
- ELB가 생성되었는지 상태를 확인한 후에 접속해본다. 이 때 81번 포트로 접속해야 한다. 예: http://hana-elb-578601292.ap-northeast-2.elb.amazonaws.com:81/
- 접속 할 때마다 인스턴스가 변경되는 것을 확인한다.
- 타겟그룹
- 타겟그룹을 두개 만든다. 그룹 이름은 TG1, TG2
- 각 타겟그룹별로 인스턴스를 하나씩 배정한다.
- ELB
- ELB를 생성하거나 재활용한다.
- 리스터에 2개의 타겟 그룹을 붙인다. 리스너의 포트는 ELB의 포트와 동일하게 해야 한다. 이전 예제에서는 81번이다. 타겟그룹들의 가중치를 50%씩 부여한다.
- 가중치를 조절하면서 서비스되는 애플리케이션을 전환한다.
자동으로 인스턴스의 숫자가 변경되도록 하는 기능
CPU 점유율을 기준으로 인스턴스가 조정되도록 설정하기 위해서 아래와 같은 코드를 위치시킨다. https://github.com/egoingsb/offline/blob/master/AWS/loadtest.php
- jMeter 다운로드 후 실행 : https://github.com/egoingsb/offline/blob/master/AWS/jmeter-5.3.zip
- Thread Group > Http Request > Summary Report 추가
- Thread Group : Number of thread 1, Loop Count 100
- Target group 생성 : AutoScaling으로 만들어진 인스턴스가 자동으로 등록된다.
- ELB 생성 후 전단계의 타겟그룹을 리스터로 연결
- Launch Configuration
- 시작구성 생성
- 이름, AMI, 인스턴스유형 지정
- 보안그룹은 생성되는 인스턴스의 인바운드 트래픽을 제어하는 것이기 때문에 80번 포트를 지정한다.
- EC2 AutoScaling
- AutoScaling 생성
- 시작구성으로 전환, 앞에서 생성한 시작구성 지정
- 모든 서브넷 선택
- ELB설정에서 타겟그룹지정
- Configure advanced optionsInfo
- Health check type - ELB도 체크 : EC2는 인스턴스의 건강 상태를 인스턴스 자체적으로 체크하는 것이고, ELB는 ELB에서 request를 해서 정상적으로 리턴하지 않으면 건강하지 않은 것으로 간주하는 설정
- 원하는 용량 1, 최소 용량 1, 최대 용량 2로 지정
- 대상 조정 정책 : 평균 CPU 사용률 30%
- 설정을 완료하면 인스턴스 1개가 자동으로 생성된다. ELB와 상관없이 AutoScaling에 의해서 인스턴스는 만들어진다.
- ELB 에 /loadtest.php로 접속해서 로드 테스트를 진행한다.
AWS의 서비스를 SDK로 이용하는 방법을 소개합니다. 여기서는 EC2, RDS. S3, IAM을 사용합니다.
- RDS 생성
- 데이터베이스 생성
CREATE DATABASE mydb;
- 데이터베이스 선택
use mydb;
- 테이블 생성
CREATE TABLE topic(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, title char(20) NOT NULL, description TINYTEXT, thumbnail varchar(200) NULL);
- 퍼블릭 액세스 차단 정책을 비활성화합니다.
- IAM으로 접속
- 역할생성
- 사용사례선택에서 EC2 선택
- 권한 정책 연결에서 S3 Full Access 선택
- 역할이름 지정 - S3-ACCESS
- EC2 인스턴스 생성시 S3-ACCESS을 역할로 지정
- apache, php, php mysql extension 설치
sudo apt update; sudo apt install apache2 php php-mysql php-mbstring mysql-client php-xml; sudo service apache2 restart;2.1. RDS VPC security에 EC2 보안 규칙을 허용 2.2. index.phpcd /var/www/html/; sudo wget https://raw.githubusercontent.com/egoingsb/offline/master/AWS/sdk/index.php데이터베이스 hostname, user, password 수정
<?php
$conn = mysqli_connect('db.cdbrt00yi2pz.ap-northeast-2.rds.amazonaws.com', 'admin', 'qwertyuiop', 'mydb');
$sql = 'SELECT * FROM topic';
?>
<html>
<body>
<h1><a href="/index.php">CLOUD</a></h1>
<ul>
<?php
$query = mysqli_query($conn, $sql);
while($row = mysqli_fetch_array($query)){
?>
<li><a href="index.php?id=<?php echo $row['id'];?>"><?php echo $row['title'];?></a></li>
<?php
}
?>
</ul>
<?php
if(empty($_GET['id'])){
?>
Hello is ..
<?php
} else {
$query = mysqli_query($conn, "SELECT * FROM topic WHERE id = ".$_GET['id']);
$result = mysqli_fetch_array($query);
?>
<h1><?php print($result['title']);?></h1>
<?php print($result['description']); ?>
<br><img src="<?php print($result['thumbnail']); ?>" width="100"><br>
<?php
}
?>
<?php
print($_SERVER['SERVER_ADDR']);
?>
<a href="write.php">write</a>
</body>
</html>- write.php
sudo wget https://raw.githubusercontent.com/egoingsb/offline/master/AWS/sdk/write.php
<html>
<body>
<form action="write_process.php" method="POST" encType="multipart/form-data">
<p><input type="text" name="title" placeholder="title"></p>
<p><textarea name="description" placeholder="description"></textarea></p>
<p><input type="file" name="uploaded_file"></p>
<p><input type="submit"></p>
</form>
</body>
</html>- sdk 설치
sudo wget https://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip;
sudo apt install -y unzip;
sudo unzip aws.zip -d aws;- write_process.php https://raw.githubusercontent.com/egoingsb/offline/master/AWS/sdk/write_process.php
sudo wget https://raw.githubusercontent.com/egoingsb/offline/master/AWS/sdk/write_process.phps3 bucket name, database hostname, user, password 수정
<?php
require 'aws/aws-autoloader.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
//Create a S3Client
$s3Client = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'ap-northeast-2'
]);
// Send a PutObject request and get the result object.
$result = $s3Client->putObject([
'ACL'=>'public-read',
'Bucket' => 'my-photo-server',
'Key' => $_FILES['uploaded_file']['name'],
'SourceFile' => $_FILES['uploaded_file']['tmp_name']
]);
$s3URL = $result->toArray()['ObjectURL'];
$conn = mysqli_connect('db.cdbrt00yi2pz.ap-northeast-2.rds.amazonaws.com', 'admin', 'qwertyuiop', 'mydb');
$sql = "INSERT INTO topic (title, description, thumbnail) VALUES('{$_POST['title']}', '{$_POST['description']}', '{$s3URL}')";
mysqli_query($conn, $sql);
header('Location: index.php');- Uncaught Error: Class 'SimpleXMLElement' not found : xml 파서 라이브러리가 없음 => apt install php-xml;
- Uncaught exception 'Aws\S3\Exception\S3Exception' with message,(중략) AWS HTTP error resulted in a
403 Forbidden(중략) Access Denied : 버킷에 권한이 없음 => 버킷의 퍼블릭 엑세스 차단 설정을 끔 - The specified bucket does not exist : 버킷이 존재하지 않음 => 코드 상의 버킷의 이름을 변경
- 첨부파일 없이 업로드하면 에러가 발생합니다.
- 파일의 용량이 너무 크면 업로드가 안되기 때문에 에러가 발생할 수 있습니다.
웹애플리케이션을 운영하기 위해서 필요한 기능을 종합적으로 제공하는 서비스
-
런타임 : Java, .NET, PHP, Node.js, Python, Ruby, Go, Docker
-
서버 : Apache, Nginx, Passenger, IIS
-
기능 : 용량 프로비저닝, 로드 밸런싱, 오토스케일링, 모니터링, 배포
-
EB 자체는 무료
-
environment는 실제로 서비스되는 웹애플리케이션 하나를 위해서 필요한 EC2 인스턴스, AutoScaling, 각종 환경설정등을 그룹핑한 것
-
Application은 연관된 environment의 그룹
- 애플리케이션을 생성한다.
- 전단계에서 생성한 애플리케이션에 속한 환경을 생성한다.
- 환경티어 : 웹서버 환경
- 플랫폼 : PHP
- 애플리케이션 코드 : 샘플
- 추가옵션구성
- 구성 사전 설정 : 단일 인스턴스(프리티어 사용가능)
- 용량 : 자신에게 필요한 타입 지정
- 환경의 주소로 접속한다.
- 코드를 업로드 한다.
- 환경의 주소로 접속한다. => 업로드된 코드가 반영되었는지 확인한다.
- 코드를 수정해서 다시 업로드 한다.
- 환경의 주소로 접속한다. => 업로드된 코드가 반영되었는지 확인한다.
- 방금 올린 버전을 취소하고 이전 버전으로 롤백을 해본다.
- 구성>소프트웨어>환경 속성의 값을 설정한다.
- DBHOST, DBUSER, DBPASSWORD의 값을 지정한다. 이때 이름으로는 알파벳대문자와 숫자 언더바 기호만 사용할 수 있다. 다른 값을 사용하면 무시된다.
- 설정한 값이 애플리케이션에 반영되었는지 확인한다.
php $conn = mysqli_connect($_SERVER['DBHOST'], $_SERVER['DBUSER'], $_SERVER['DBPASSWORD'], 'mydb');
- S3 버킷을 생성한다.
- 버킷이름, 퍼블릭 엑세스 차단 설정 해제
- 버킷을 웹서버로 변경한다.
- 속성탭에서 정적 웹 사이트 호스팅 편집
- 활성화
- 인덱스 문서 : index.html, 오류문서:error.html
- 웹서버의 주소로 접속한다. => index.html 파일이 아직 없기 때문에 접속이 안된다.
- 속성탭에서 정적 웹 사이트 호스팅 편집
- 파일을 업로드 한다. url을 API Gateway로 변경한다.
<html>
<body>
<h1><a href="/index.php">CLOUD</a></h1>
<ul></ul>
Welcome!!
<script>
fetch('https://a1065ugh04.execute-api.ap-northeast-2.amazonaws.com/prod/list')
.then(function(type){return type.json()})
.then(function(data){
var list = JSON.parse(data.body);
var str = '';
for(var i=0; i<list.length; i++){
str += `<li>${list[i].title}</li>`;
}
document.querySelector('ul').innerHTML = str;
})
</script>
</body>
</html>- 업로드한 파일을 public으로 지정한다.
- 람다 함수를 생성한다.
- 새로작성을 선택한다. 함수의 이름과 Node.js 를 선택한다.
- index.js 파일의 내용을 아래와 같이 한다.
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify([
{id:1, title:'ec2', description:'ec2 is ...'},
{id:2, title:'rds', description:'rds is ...'},
{id:3, title:'lambda', description:'lambda is ...'}
]),
};
return response;
};- deploy를 한다.
- API Gateway를 생성한다.
- REST API 구축을 누른다.
- 새 API 생성옵션을 선택한다. API 이름을 지정하고 API 생성 버튼을 누른다.
- 리소스를 생성한다.
- 리소스명은 /list, API Gateway CORS 활성화를 체크한다.
- 메소드를 생성한다.
- 메소드 타입은 GET
- 통합유형:Lambda 함수, Lambda 함수:위에서 만든 함수 지정
- CORS 설정을 한다.
- 작업>CORS 활성화
- API 배포
- 배포 스테이지 : 새 스테이지, 스테이지 이름 : prod
- 접속한다.
- 스테이지 항목 중에 prod를 선택한다.
- 스테이지의 URL로 접근한다. 이때 /list를 경로에 추가한다. 아래와 같은 결과가 출력되면 성공
{"statusCode":200,"body":"[{\"id\":1,\"title\":\"ec2\",\"description\":\"ec2 is ...\"},{\"id\":2,\"title\":\"rds\",\"description\":\"rds is ...\"},{\"id\":3,\"title\":\"lambda\",\"description\":\"lambda is ...\"}]"}