ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 카카오클라우드 - 클라우드 개발자 교육 8주차 후기
    bootcamp 2025. 12. 31. 09:41

    저번시간 구성한 AWS 인프라에 react, fastapi를 배포했다.

     

    질문 1.

    Q. 나는 2A의 브라우저 '화면'에서 요청했는데 왜 카테고리 조회 요청이 실제로 2B 서버에서 처리되나요?

    A. 처음 popori.store를 브라우저에 입력해 요청하면 해당 패킷은 2A NGINX에서 index.html을 클라이언트에 전달하고,

    패킷은 성공적으로 처리됩니다. 두번째 패킷(카테고리 조회)이 새로 생성되어 이 패킷은 동일하게 IG->NAT->ALB->SubNet으로 가는데

    이때 로드벨런서가 트래픽을 성공적으로 처리할수 있는 인스턴스로 안내해줍니다. 따라서 동일하게 조회 요청을 10번 했을시 2A 서브넷에서도 응답을 요청할때가 있고, 2B에서 응답을 요청할때가 있습니다.

    여기서 햇갈리는 개념은 2A는 2A끼리 통신한다면서요?라는 질문이 있었다.

    앞서 설명한 개념에서 말했듯이 '화면'을 2A에서 응답받고 해당 패킷은 성공적으로 종료 되었으며, 이후 N번째 패킷들은 서로 독립적인 요청이기에 다시 처음부터  IG->NAT->ALB->SubNet의 경로로 처리됩니다.

    2A는 2A끼리 라는 개념은 하나의 서브넷에서, 2A NGINX, 2A BACKEND서버끼리를 의미합니다.

    따라서 2A NGINX가 패킷을 처리하면 2A BACKEND서버 해당 패킷을 처리하지, 2B BACKEND서버에서 처리하지 않습니다.

     

     

    AWS 3-tier Architecture. AZ 격리 구조.

     

     

     

    파일전송
    scp -i /Users/yoonhyungjoo/Downloads/02T-powermvp.pem \
      -J ubuntu@ip \
      ./dist.tar.gz \
      ubuntu@ip:/home/ubuntu/

    SSH 에이전트 키파일 등록 후 파일전송
    * ssh-add /Users/yoonhyungjoo/Downloads/02T-powermvp.pem
    * ssh -A ubuntu@ip
    * scp
    *   -J ubuntu@ip \
    *   ./dist.tar.gz \
    *   ubuntu@1ip:/home/ubuntu/
    * ssh -A -J ubuntu@1ip ubuntu@1ip


    mysql 접속
    mysql \
      -h RDS DNS \
      -P 3306 \
      -u admin \
      -p

    파이썬 프로젝트 가상환경 설정
    git clone https://github.com/yhj0904/testfast.git
    tar -zcvf testfast.tar.gz testfast
    scp testfast.tar.gz ubuntu@IP:/home/ubuntu/
    tar -zxvf testfast.tar.gz
    cd testfast
    sudo apt update
    sudo apt install -y python3-venv python3-pip
    python3 -m venv venv
    source venv/bin/activate

    가상환경 실행
    파이썬 유비콘으로 실행
    Bastion에서 CURL로 api 테스트
    react 프로젝트 client.js baseURL 수정후 재배포.
    popori.store 테스트후 완료
    pip install -r requirements.txt 


    nginx 문법체크
    sudo nginx -t

    nginx 설정파일 위치
    /etc/nginx/conf.d/default.conf 

    환경변수
    export DB_HOST="RDS DNS" 
    export DB_PORT="" 
    export DB_USER="" 
    export DB_PASSWORD="" 
    export DB_NAME="shopdb"

    자동배포

    서버종류
    자동배포 범위
     Deploy
    webhook
    CICD 아키텍쳐

    webhook  push
     → Build build
     → Test
     → Deploy.   

    AZ 격리니  블루-그린 배포

    파이프라인? 
    우리가 수동배포한 플로우 확인

     

     

     

     

    배포순서

    1. 플랫폼 세팅
    2. 리엑트 
    • npm install       node_modules 폴더 생성
    • npm run build   빌드 후 dist폴더 생성
    • ssh-add /Users/yoonhyungjoo/Downloads/02T-powermvp.pem   ssh 키파일 등록
    • * ssh -A -J ubuntu@ip ubuntu@ipnginx 인스턴스 ssh 터널링
    • tar -zcvf dist.tar.gz dist tar.gz로 압축
    • scp  -J ubuntu@ip \
      ./dist.tar.gz \
      ubuntu@ip:/home/ubuntu/
    • dist 폴더 nginx 인스턴스에 전송
    • tar -zxvf dist.tar.gz 압축해제
    • mv  dist/  /usr/share/nginx/html
    • cd /etc/nginx/conf.d/ nginx 설정파일 위치. 
    • sudo nano default.conf nginx 설정파일 수정.
    • sudo nginx -t
    • sudo systemctl restart nginx nginx 재부팅
    • sudo systemctl reload nginx nginx 새로고침

     

    1. 파이썬.

    - git push

    - ssh -A -J ubuntu@ip ubuntu@ip 파이썬 인스턴스 ssh 터널링

    - sudo apt-get update

    - sudo apt-get install git

    - git clone [깃 주소]

    - cd testfast

    - sudo nano .env 

    - .env 생성

    - python3 -m venv venv 파이썬 가상환경 설치

    - source venv/bin/activate 가상환경 접속

    - pip install -r requirements.txt 모듈 설치

    - uvicorn app.main:app --host 0.0.0.0 --port 8000

     

    배포 순서는 간략하게 이렇게 작성했다.

     

     

    #자동배포 ./github/workflows/deploy.yml
    
    name: CI/CD Pipeline
    
    on:
      push:
        branches: [ main, develop ]
      pull_request:
        branches: [ main ]
      workflow_dispatch:
    
    env:
      PYTHON_VERSION: '3.11'
    
    jobs:
      test:
        name: Test Application
        runs-on: ubuntu-latest
    
        services:
          mysql:
            image: mysql:8.0
            env:
              MYSQL_ROOT_PASSWORD: testpassword
              MYSQL_DATABASE: testdb
              MYSQL_USER: testuser
              MYSQL_PASSWORD: testpass
            ports:
              - 3306:3306
            options: >-
              --health-cmd="mysqladmin ping"
              --health-interval=10s
              --health-timeout=5s
              --health-retries=3
    
        steps:
        - uses: actions/checkout@v3
    
        - name: Set up Python
          uses: actions/setup-python@v5
          with:
            python-version: ${{ env.PYTHON_VERSION }}
    
        - name: Cache pip packages
          uses: actions/cache@v3
          with:
            path: ~/.cache/pip
            key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
            restore-keys: |
              ${{ runner.os }}-pip-
    
        - name: Install dependencies
          run: |
            python -m pip install --upgrade pip
            pip install -r requirements.txt
            pip install pytest pytest-cov httpx
    
        - name: Run tests
          env:
            DB_HOST: localhost
            DB_PORT: 3306
            DB_NAME: testdb
            DB_USER: testuser
            DB_PASSWORD: testpass
          run: |
            pytest tests/ -v --cov=app --cov-report=xml --cov-report=html
          continue-on-error: true  # 테스트가 없는 경우를 고려
    
        - name: Upload coverage reports
          uses: codecov/codecov-action@v3
          with:
            file: ./coverage.xml
            fail_ci_if_error: false

     

    Trublesooting


    1.     scp 인증 오류

    4.                ssh 점프로 bastion -> nginx(접속 안됌!) 이유 불명.

    5.                ssh agent 키파일 등록 scp시도. 정상 작동.

    —------명령어—-----

    6.                ssh-add /Users/yoonhyungjoo/Downloads/02T-powermvp.pem

    7.                scp -o ForwardAgent=yes \

    8.                  -J ubuntu@18.216.66.86 \

    9.                  ./dist.tar.gz \

    10.               ubuntu@10.250.11.240:/home/ubuntu/

    11.             ssh -A -J ubuntu@18.216.66.86 ubuntu@10.250.11.240

     

    용어

    Bastion 서버는 필요한가?

     Bastion 서버(Bastion Host) AWS 같은 클라우드 환경에서 프라이빗 서브넷에 있는 서버에 안전하게 접속하기 위해 존재하는 하나의 관문이다.

     Bastion이 없으면?

    모든 EC2 퍼블릭 IP 부여

    모든 서버에 SSH(22) 포트 오픈
    IP
    관리 어려움

    침입 지점이 서버 수만큼 증가
    보안 사고 확률이 기하급수적으로 증가한다.

    Bastion이 있으면?

    퍼블릭 IP Bastion 하나만
    SSH
    인바운드는 Bastion 허용
    내부 서버는 완전한 프라이빗 유지
    접속 경로가 단일화됨

     

    CIDR?

    (Classless Inter-Domain Routing)

     

    클래스 없는 도메인간 라우팅 기법

     

    도메인간의 라우팅에 사용되는 인터넷 주소를 원래 IP주소 클래스 체계를 쓰는 것보다 더욱 능동적의로 할수 잇도록 할당하여 지정하는 방식

     

     서브네팅, 슈퍼네팅 이러한 IP나누고 합치는 기법을 모두 CIDR

    cidr 네트워크 정보를 여러개로 나누어진 Sub-Network들을 모두 나타낼 있는 하나의 Network 통합해서 보여주는 방법이다

     

    참고 : https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-CIDR-%EC%9D%B4-%EB%AC%B4%EC%96%BC-%EB%A7%90%ED%95%98%EB%8A%94%EA%B1%B0%EC%95%BC-%E2%87%9B-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC-%EA%B3%84%EC%82%B0%EB%B2%95



    NAT(Network Address Translation) Gateway?

     프라이빗 서브넷에 있는 인스턴스가 인터넷으로 나가기만 있도록 해주는 AWS 관리형 서비스

    아웃바운드 전용

    퍼블릭 서브넷에 위치
    Elastic IP
    가짐
    외부내부 인바운드 접속 불가
    상태 저장(Stateful)

    프라이빗 서브넷의 EC2 퍼블릭 IP 없다. 그래서 아래와 같은 작업을 직접 없다.

    OS 보안 패치, 외부 API 호출, Docker 이미지 Pull, 외부 인증 서버(JWT, OAuth) 통신
     
    문제를 해결하기 위해 대신 인터넷에 나가주는 대리인이 NAT Gateway.

     

    라우팅 테이블(Route Table)이란?

    라우팅 테이블은이 목적지 IP 가는 트래픽은 어디로 보내라 라는 규칙 집합이다.

     

    서브넷(Subnet) 반드시 어떤 라우팅 테이블 하나를 사용해야 한다.

    그래서 그림에서 RT_PUBLIC -> Public Subnet, RT_APP -> Private App Subnet, RT_DB -> Private DB Subnet처럼 Association 표시돼 있다.

    라우팅 테이블은 구조적으로 Destination → Target 매칭된다.

    Main Route Table 별도로 존재하는 이유는 VPC 기본 RT 필요하니까 AWS 자동으로 Main RT 만든다. 그리고 어떤 서브넷이든, 명시적으로 다른 RT 연결하지 않으면 Main RT 자동 적용된다



    GPG ?

     

    리눅스 GPG (GPG Key) 패키지를 설치·업데이트할 소프트웨어가 진짜인지, 중간에 변조되지 않았는지를 검증하기 위한 기준이다.

    GPG(GNU Privacy Guard) 공개키 암호 기반(Public Key Cryptography) 서명·암호화 도구다.

    패키지 배포자는 개인키(Private Key) 패키지에 서명하고, 사용자는 공개키(Public Key) 서명을 검증한다.

     

    리눅스 GPG 키는 패키지가 누가 만들었고, 중간에 바뀌지 않았는지를 확인하는 공개키다.

     

    외부 리소스. ex) op.gg desktop, mysql 커스텀 버전?, ~~~ 외부 리소스를 레포지토리에 담고,

    리소스를 설치할때 검증하는 키파일이다.

     

    CLB(Classic Load Balancer), ALB(Application Load Balancer) 특징

    AWS에서 CLB ALB 모두 트래픽을 여러 서버로 분산시키는 로드밸런서지만, 동작 계층, 기능 범위, 다르다. CLB 레거시, ALB 현재 표준이다.

    CLB(Classic Load Balancer)?

    CLB AWS 초창기에 등장한 구형(레거시) 로드밸런서다.
     Layer 4(TCP)
    제한적인 Layer 7(HTTP) 혼합 지원함

    CLB의 특징

    L4 + 제한적 L7
    EC2
    기반 환경에 최적화
    단순한 헬스체크
    URL, Host
    기반 라우팅 불가

    AWS에서 신규 생성 비권장

    TCP까지 제어함

    그냥 들어오는 트래픽을 서버들에게 나눠주는 역할.

    ALB Layer 7(HTTP/HTTPS) 로드밸런서다.
     HTTP
    요청의 내용 자체를 이해하고, 그에 따라 트래픽을 지능적으로 분기할 있다.

    ALB의 핵심 특징

    L7 전용
    URL Path / Host
    기반 라우팅
    하나의 ALB 여러 서비스 운영 가능
    ECS / EKS /
    마이크로서비스 친화적

    WebSocket, HTTP/2 지원

    helth check 가능

    요청을 이해하고, 상황에 맞게 분기하는 로드밸런서

     

    DNS 레코드 종류는?

     

    A(Adrees) : ip, 혹은 DNS 명시해 DNS 주소를 가르키게한다.

    SOA(Start of Authority) : 

    SOA 해당 도메인 (Zone)시작 선언문이자 최고 책임자 정보다.
     
    파일에는 반드시 하나의 SOA 레코드가 존재한다.

    SOA가 담고 있는 정보

    도메인의 DNS 서버
    관리자 이메일
    버전(Serial)
    캐시 갱신 정책(TTL 관련)


    NS(Name Server) : Domain 작동하는 서버 단위. domain 호스팅해주는 서버 주소.

    CNAME(Canonical Name) : 도메인을 다른 도메인의 별명(alias)으로 연결하는 레코드다.

    CNAME IP 직접 가리키지 않는다

    항상 다른 도메인 이름을 가리킴

    CNAME 있으면 다른 레코드(A, MX ) 공존 불가

    MX(Mail Exchange) : 도메인의 이메일을 어디 서버가 받을지를 지정한다.

     

     

     

    DNS 조회 흐름

    1.     클라이언트가 www.example.com 요청

    2.     루트 DNS → .com TLD 안내

    3.     .com DNS → NS 레코드로 example.com 담당 서버 안내

    4.     담당 DNS 서버 → SOA 확인 (권한 있음)

    5.     www.example.com → CNAME 또는 A 레코드 조회

    6.     최종 IP 반환


    SOA/NS 관리 구조

     A/CNAME/MX/TXT 실제 서비스 정보

     

    Health Check?

    서버, 애플리케이션, 컨테이너, 혹은 특정 인스턴스가 정상적으로 동작 중인지 주기적으로 확인하는 메커니즘

    실제 요청을 처리할 있는 상태인지 판단 하는 역할



     

     

     

    —————————————————————————— 
    본 후기는 [카카오엔터프라이즈x스나이퍼팩토리] 카카오클라우드로 배우는 AIaaS 마스터 클래스 3기(B-log) 리뷰로 작성 되었습니다.

Designed by Tistory.