Developer's Development

3.4.11 [클라우드] AWS 인프라: 운영 서버 환경 구성 본문

AI 활용 애플리케이션 개발/클라우드

3.4.11 [클라우드] AWS 인프라: 운영 서버 환경 구성

mylee 2025. 10. 28. 17:47
클라우드 서버

 

인터넷 상에 가상화 된 서버이며, 필요할 때마다 접근해서 사용할 수 있는 서버이다.

인터넷 통신망에만 접근할 수 있다면 컴퓨터 자원(CPU, 메모리, 디스크 등)을 원하는대로 가져다 사용할 수 있다.

 

👉🏻 클라우드 서비스 모델: IaaS, PaaS, SaaS

👉🏻 클라우드 서버의 장점: 경제성, 편의성, 확장성, 안정성

👉🏻 클라우드 서버 도입 이유

- 기업이 새로운 제품이나 서비스를 제공하고자 할 떄 서버 리소스를 적시에 제공받을 수 있다.

- 클라우드 서버는 이론상 무한대로 확장이 가능하다. 네트워크 상의 트래픽이나 컴퓨팅 리소스가 더 필요한 경우 클라우드 서버의 업그레이드 또는 새로운 자원의 추가로 확보할 수 있다.

- 초기 투자 비용이 기존의 물리적인 설치 방식에 비해 적다. 이미 구성되어 제공되는 클라우드 제공자에게서 필요한 만큼만 받아 구축하면 되므로, 초기에 비교적 적은 비용으로 구축이 가능하다.

 

  • 클라우드 서버 벤더

1. 아마존 웹 서비스 (Amazon Web Services)

  - 2006년에는 클라우드 스토리지, S3, 컴퓨팅 자원 EC2, 큐 서비스 SQS를 통합적으로 제공했다.

  - AWS는 네트워킹을 기반으로 가상 서버를 제공할 뿐 아니라 네트워크 인프라 등 다양한 서비스를 제공한다.

  - 전 세계에 175개가 넘는 데이터 센터를 보유하고 있으며, 전세계 점유율 1위 서비스이다.

 

2. 마이크로소프트 에저 (Microsoft Aure)

  - 2010년에 개시한 마이크로소프트의 클라우드 컴퓨팅 플랫폼이다.

  - 전 세계 클라우드 시장 2위로, 1위인 AWS를 추격하고 있다.

  - 크레딧을 이용해 결제할 수 있으며, 직접 사거나 MSDN 구독, 비즈스파크 등을 이용해 얻을 수 있다.

 

3. 구글 클라우드

  - 구글 계정이 있는 경우 해당 계정을 이용하여 구글 클라우드를 사용할 수 있다는 장점이 있다.

 

AWS (Amazon Web Services)

 

  • AWS 주요 서비스 소개

1. AWS EC2 (Elastic Compute Cloud)

  - AWS에서 가장 기본적이고 많이 쓰이는 인프라이며, 네트워크 망에서 가상 서버를 제공한다.

  - EC2는 한마디로 가상 머신이라고 볼 수 있으며 하나의 서버(가상머신)를 인스턴스라고 한다.

  - EC2는 AWS에서 제공하는 인터페이스를 통해 유동적인 스펙의 서버를 빠르게 구축할 수 있다.

 

2. AWS S3 (Simple Storage Service)

  - S3는 AWS에서 제공하는 오브젝트 스토리지 서비스이다. (사진, 비디오, 문서 등)

  - 파일 저장은 bucket(또는 컨테이너)을 통해 운영되며 다른 유저들의 엑세스도 컨트롤할 수 있다.

  - 무제한적인 확장성, 높은 가용성과 내구성을 보장하며 단일 파일을 최대 5TB까지 업로드할 수 있도록 지원한다.

 

3. RDS (Relational Database Service)

  - AWS에서 제공하는 관리형 관계형 데이터베이스 서비스이다.

  - MySQL, PostgreSQL, Oracle, SQL Server 등 다양한 DB 엔진을 지원한다.

  - EC2에서 직접 DB를 설치하지 않고, 자동 백업, 보안 패치, 스냅샷 등의 기능을 제공하여 운영 부담을 줄여준다.

  - 고가용성을 위한 Multi-AZ 구성도 지원되며, 읽기 전용 복제본(Replica)도 생성할 수 있다.

 

4. VPC (Virtual Private Cloud)

  - 아마존 VPC는 계정별로 격리된 네트워크 환경을 구성할 수 있는 서비스이다.

  - 서브넷, Route Table, ACL, 보안 그룹 등을 이용해 논리적인 네트워크 분할 작업을 할 수 있다.

  - 계정 안 또는 계정 간 격리된 네트워크를 연결할 수 있는 옵션도 제공한다.

  - VPC는 AWS 리소스 간 허용을 최소화하고 그룹별로 네트워크를 구성하기 쉽게 하기 위해 사용한다.

 

5. IAM (Identity and Access Management)

  - 권한 관리를 지원해주는 서비스이다.

  - AWS에서 일반적으로 계정을 생성하면 Root 계정으로 만들어지며, 이 계정은 모든 권한을 가지고 있다.

    - 따라서 보안상 문제가 발생할 수 있기 때문에, IAM은 사용자 계정 및 그룹 생성하여, 권한을 제어하는 기능을 제공한다.

 

6. Route S3

  - Domain Name System, 도메인 관리/설정 서비스이다.

  - EC2 인스턴스, Elastic 로드 밸런서, S3 저장소 등 AWS 서비스 인프라에 연결하여 사용한다.

  - Route53을 통해 자신이 가지고 있는 도메인과 연결하거나, Route53에서 도메인을 구입할 수 있다.

 

7. ECS (Elastic Container Service)

  - AWS의 매니지드 컨테이너 오케스트레이션 서비스이다.

 

8. EKS (Elastic Kubernetes Service)

  - 관리형 쿠버네티스 서비스이다. 해당 서비스를 이용하면 쿠버네티스 마스터노드 구성을 하지 않아도 AWS에서 관리를 해주며, 빠르게 쿠버네티스를 사용할 수 있다.

 

9. SQS (Simple Queue Service)

  - 관리형 메시지 큐 서비스로 AWS의 첫번째 서비스이다.

 

10. Lambda

  - 서버리스 컴퓨팅 서비스이다. 해당 서비스는 애플리케이션을 실행하기 위한 별도 서버 없이 코드를 바로 실행해주는 서비스이다.

 

 

웹 서비스 인프라 구성

 

  • EC2 (Elastic Compute Cloud)

EC2는 AWS에서 제공하는 가성 서버 서비스로, 사용자가 원하는 운영체제와 환경을 구성하여 서버처럼 사용할 수 있다.

다양한 용도의 컴퓨팅 작업을 수행할 수 있으며, 필요에 따라 서버의 성능을 유연하게 조정할 수 있다.

 

👉🏻 보안 그룹 (Security Group)

인스턴스에 적용되는 가상 방화벽으로, 외부와의 통신을 제어한다.

웹 서버는 일반적으로 포트 22(SSH), 80(HTTP), 443(HTTPS), 8000(Django 개발서버)를 개방해야 한다.

 

👉🏻 SSH

EC2는 비밀번호 기반이 아닌 공개키 기반 인증(SSH)을 사용해 접속한다.

 

  • 웹 애플리케이션 배포 구조

웹 애플리케이션은 보통 3-계층 구조로 구성된다. (웹 서버, 애플리케이션 서버, 데이터베이스)

 

 

Docker 및 Django 컨테이너

 

  • Docker

리눅스 응용 프로그램들을 프로세스 격리기술들을 사용해 컨테이너로 실행하고 관리하는 오픈 소스 프로젝트이다.

컨테이너 기반 오픈소스 가상화 플랫폼이라고 정의할 수 있다.

 

👉🏻 사용 목적: 경량성, 이식성, 일관성, 유연성 

 

 

데이터 저장소 및 정적 자원 처리

 

  • Amazon RDS

AWS에서 제공하는 관리형 관계형 데이터베이스 서비스이다. MySQL, PostgreSQL, Oracle, SQL Server, MariaDB, Aurora 등 다양한 엔진을 지원한다.

 

 

실습

 

Docker 설치

https://www.docker.com/

 

Docker: Accelerated Container Application Development

Docker is a platform designed to help developers build, share, and run container applications. We handle the tedious setup, so you can focus on the code.

www.docker.com

 

Docker Hub 가입

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

Software supply chain Secure Your Supply Chain with Docker Hardened Images Use Docker's enterprise-grade base images: secure, stable, and backed by SLAs for Ubuntu, Debian, Java, and more. Regularly scanned and maintained with CVE remediation and long-term

hub.docker.com

 

  • Windows cmd

- docker pull 레포지토리명 (레포지토리 == 이미지)

- docker run 레포지토리명

docker ps
docker login
docker pull hello-world					# hub -> (pull) -> img -> (run) -> container
docker images
docker run hello-world	
docker ps								# 아무것도 안나옴
docker ps -a							# 전체 조회, ps는 컨테이너를 보여줌
docker run --name hello hello-world		# run은 pull을 포함
docker ps -a
docker rm hello							# rm: 컨테이너 삭제 (ID로도 삭제 가능)
docker ps -a							# 삭제된거 확인
docker rmi hello-world					# rmi: 이미지 삭제
docker images
docker search hello-world
docker search ubuntu
docker image pull ubuntu:latest			# pull의 full 명령어
docker images
docker container run ubuntu:latest		# run의 full 명령어
docker container run -it --name ubuntu_final ubuntu		# Ctrl + P, Q로 빠져나옴
docker container ls						# 현재 실행중인 컨테이너 목록 조회
docker container attach ubuntu_final
# ls
$ pwd
# cd home
docker container stop ubuntu_final
docker container start ubuntu_final
docker conainer ls
docker container restart ubuntu_final	# stop, start 동시
docker conainer ls
docker ps -a
docker container prune					# 이용중이지 않은 리소스 일괄 삭제
docker ps -a
docker stop ubuntu_final
docker rm ubuntu_final
docker rmi ubuntu
docker ps -a
docker images

 

  • vscode

my-first-docker/main.py 파일 생성

from fastapi import FastAPI

app = FastAPI()

@app.get('/')
def read_root():
    return "Hello [My FIRST] Docker World"

 

my-first-docker/Dockerfile 파일 생성

→ build → (run) → container

FROM python:3.12

WORKDIR /app

COPY . /app

RUN pip install --no-cache-dir -r requirements.txt

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

 

cmd

cd my-first-docker
pip freeze > requirements.tzt
docker build -t my-first-docker .
docker images
docker run -d -p 60080:8000 my-first-docker

 

http://localhost:60080/ 접속 및 확인 ("Hello [My FIRST] Docker World" 출력)

docker container ls
docker stop upbeate_babbage
docker login		# 내이름 확인
docker tag my-first-docker myleee /my-first-docker:latest	# docker tag 이미지명 내이름/이미지명:latest
docker images
docker push myleee/my-first-docker:latest

 

https://hub.docker.com/repositories/myleee

My Hub에서 push된 이미지 확인

 

 

실습 (django docker)

 

  • vscode

cmd

cd ..
pip install gunicorn
django-admin startproject django_docker
cd django_docker
django-admin startapp main

 

django_docker/static/images 폴더 추가

django_docker/nginx 폴더 추가

디렉토리 구조

 

django_docker/settings.py 수정

main app 추가, STATIC ROOT 추가

from pathlib import Path
import os

INSTALLED_APPS = [
    'django.contrib.admin',
    ...
    'main'
]

STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

 

django_docker/urls.py 수정

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('main/', include('main.urls')),
]

 

main/urls.py 추가

from django.urls import path
from .views import hello_view

urlpatterns = [
    path('', hello_view)
]

 

main/views.py 수정

from django.shortcuts import render

def hello_view(request):
    return render(request, 'hello.html')

 

django_docker/main/templates/hello.html 추가

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello Page</title>
</head>
<body>
    <h1>Hello, This is Django project with Docker🐬</h1>
    <img src="{% static 'images/noori.jpg' %}" alt="logo" width="200"/>
</body>
</html>

 

cmd

pip freeze > requirements.txt

 

필요한 내용만 남기고 지우기

Django==5.2.7
django-filter==25.2
djangorestframework==3.16.1
drf-nested-routers==0.95.0
drf-yasg==1.21.11
fastapi==0.119.1
gunicorn==23.0.0
mysqlclient==2.2.7
pillow==12.0.0
uritemplate==4.2.0
uvicorn==0.38.0
wheel==0.45.1

 

gunicorn.conf.py

bind = "0.0.0.0:8000"
workers = 3

 

default.conf

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://web:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static/ {
        alias /code/static/;
    }
}

 

Dockerfile

FROM python:3.12

ENV PYTHONDOTNTWRITEBYCODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR /code

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

RUN python manage.py collectstatic --noinput

CMD ["gunicorn", "django_docker.wsgi:application", "--config", "gunicorn.conf.py"]

 

docker-compose.yml

services:
  web:
    build: .
    container_name: django_web
    volumes:
      - .:/code
    env_file:
      - .env
    expose:
      - "8000"
  nginx:
    image: nginx:alpine
    container_name: nginx_proxy
    ports:
      "8080:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./static:/code/static
    depends_on:
      - web

 

cmd

docker compose build	# docker desktop 켜져있어야 함
docker compose up