배포를 위한 필요 지식
웹 서버(WS)와 웹 애플리케이션 서버(WAS)의 차이점, 역할 분담의 필요성, 게이트웨이 인터페이스의 종류, 보안 설정 방법 및 무중단 배포 전략까지 실무 배포에 필요한 핵심 지식을 종합적으로 설명하는 가이드입니다.
“배포”에 필요한 지식 필독
클라우드에 GKE로 배포한건 DevOps 쳌리에서 보고.
여기선 cafe24 같이 서버 호스팅에서 하는것 위주로 필수 지식 정리.
WS와 WAS?
WAS가 WS를 포함하면 이제 WS는 필요 없나? 그건 아님
WAS = WS + Web Container로 구성! 클라 요청은 WS를 통해 받고, DB를 조회하는 등 비지니스 로직 수행은 Web Container로 전달
WAS가 WS를 포함하고 있기 때문에 WAS만으로도 웹 서버를 구축할 수는 있습니다. 그러나, 현재 보편적인 웹 서버 아키텍처는 WS와 WAS를 혼용해서 사용하고 있으며, 많은 개발자들이 이 방식을 권장하고 있습니다. (아래 그림 방식을 권장)
WAS는 WS의 부하 분산을 위해 고안된 서버입니다. 따라서, WS와 혼용하면서 각각의 용도에 맞게 분배하며 사용해야 합니다. WS는 최전방에 위치하여 클라이언트의 요청을 받고 비즈니스 로직이 포함되지 않는 정적인 파일에 대해서는 WAS 앞에서 즉각적으로 처리해줍니다. 반면에 동적인 페이지에 대한 요청은 WAS로 넘겨 WS는 다음 요청을 처리할 수 있도록 합니다.
WAS를 조금 더 활용한다면 최전방에 있는 WS에 하나 이상의 WAS를 연결하여 로드 밸런싱할 수도 있습니다. 더불어, WS는 Reverse Proxy 구조를 갖기 때문에 비즈니스 로직이 포함된 WAS를 직접 노출시키지 않음으로써 유연하고 고성능의 서비스를 구축할 수 있습니다.
이렇게 되면 인터넷에 떠도는 많은 포스팅에서 얘기하는 것처럼 WS는 정적 파일을 서빙하고 WAS는 동적 파일을 서빙하는 형태가 됩니다.
참고) WS로 HTTP(80)포트 들어오는것 도메인마다 개별 포트로 연결 가능
Apache의 가상호스트(VirtualHost) 기능을 사용하면 도메인별로 다른 포트로 프록시가 가능
- [app1.example.com]-> 해당 도메인이면 3000 포트로 프록시
<VirtualHost *:80>
ServerName [app1.example.com](http://app1.example.com/)
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</VirtualHost>
- [app2.example.com]-> 해당 도메인이면 8080 포트로 프록시
<VirtualHost *:80>
ServerName [app2.example.com](http://app2.example.com/)
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
WAS vs Gateway Interface 와 CGI vs WSGI vs ASGI ?
WAS vs Gateway Interface
- WAS는 웹 애플리케이션의 실행 환경 및 관련 기능들을 제공하는 반면에, Gateway Interface는 웹 서버와 웹 애플리케이션 사이의 프로토콜을 정의한다.
- WAS는 웹 애플리케이션을 직접 실행하는 반면에, Gateway Interface는 애플리케이션과 웹 서버간의 메시지 전달 역할 만을 한다.
Gateway Interface를 쓰게 된 배경
- 파이썬 웹 개발은 단순함과 유연성을 중요시 하기 때문에 웹 애플리케이션과 웹 서버를 독립적이고 간단하게 하고자 함
- 사실상 Nginx, Apache와 같은 리벅스 프록시와 같이 사용하면서 사실상 WAS의 역할 들을 수행해줌
Common Gateway Interface(CGI)
- WS로 정적 컨텐츠를 응답해주는데, 동적 컨텐츠인 python의 경우 웹 프레임워크인 장고같은걸 사용하면 WSGI를 통해 응답이 가능하고 웹 프레임워크 없으면 CGI 를 통해 응답이 가능하다.
- (장점)언어에 독립적이고 아파치에 포함되어있고 사용 방식도 간단!
- (단점)단, 호출마다 프로세스 생성하는 자원낭비
Web Server Gateway Interface(WSGI)
- python 웹 어플리케이션과 웹 서버 사이의 표준 인터페이스를 정의 (=CGI, WSGI, ASGI 전부 이 개념이 기본)
- 장고, 플라스크(=웹 프레임워크)가 사용 중. 실행은 django가 생성한 wsgi application을 사용.
Asynchronous Server Gateway Interface(ASGI)
- WSGI와 비슷한 구조를 가지면서 기본적으로 요청을 비동기로 처리하는 방식 (WSGI 상위버전)
- fastapi(=웹 프레임워크)가 사용 중. 실행은 uvicorn을 활용
- Fast api는 비동기 방식의 web server framework
- uvicorn은 비동기 방식의 http server → ASGI
톰캣은 모든 IP 접근 허용 기본. 차단방안은? - feat. putty, filezilla
톰캣은 기본적으로 모든 IP가 접근하게 허용하므로 차단도 고려해야함. ⇒ 크게 “로컬에서만 접근가능하게 설정”과 “방화벽 사용 방식” 고려!
-
Spring Boot가 외부에서 직접 접근되지 않도록 127.0.0.1에서만 동작하도록 설정 (즉, 로컬호스트에서만 쓰라고! 디스이즈 DB가 그렇게 해놨잖아? 그거처럼 ㅇㅇ.)
예로 터미널에서 netstat -lntp 로 포트설정 체크해보면 mysqld이름으로 127.0.0.1:3306 임. 따라서 mysql은 외부에서 접근을 못하고 로컬에서만 가능!(cafe24 로컬.내부에서만) 실제로 python코드도
db = pymysql.connect(host="127.0.0.1", port=3306, user=USER, passwd=PASSWD, db=DB, charset='utf8')
이런식으로 사용했었음. -
UFW 또는 iptables로 8081, 8082 포트를 외부에서 차단 (즉, 방화벽쓰라고)
putty와 filezilla는 왜그리 접근들이 외부에서 수월할까?
Putty, Filezilla란? putty는 우선 리눅스같은 서버에 SSH 지원해주는 프로그램 ⇒ 리눅스처럼 터미널 다루게 파일질라는 FTP서비스로 파일전송, 관리에 도움을 주는 프로그램 ⇒ 로컬 디렉토리 처럼
결론부터 말하면? mysql은 로컬호스트로만 접근 가능하게 해놨지만, 파일질라, putty 관련은 외부IP에서도 접근 가능하게 해놓은것
netstat -lntp 로 포트 설정 검색해서 보면? putty, 파일질라를 포트 60022로 접근하는데 실제로도 0.0.0.0:60022 가 있으며 이름도 sshd이다. 참고) 0.0.0.0 은 모든 IP 접근을 허용
무중단 배포는?
웹서버는 apache, nginx를 주로 사용하는데 무중단 배포 nginx로 하는거 살펴보장 ⇒ GCP GKE로 했던건 쿠버네티스 기능 활용한건데 “DevOps쳌리.md” 참고
이 홈페이지에 정말 자세히 잘 나와있으니 이걸 보고 따라하기! 문서
=> 추후에 cafe24에서도 따라할건데 따라하면 그 내용은 여기 쳌리에 자세히 정리할게.
TIP1) 운영환경에 yml에서 자동 DB생성 그건 사용안하는게 더 안전(실수로 깃에 올리면 모르고 사용하게되면 초기화.. 머리 개 아프지)
TIP2) 운영환경 yml은 외부에 생성해서 관리하는걸 권장! (DB정보 등 때문에. jar로 패키징 한다해도 뭐.. 소스 프로젝트도 git에 다 올리니까 우린.. 조심해야지?). 내부 resources 에 있는 yml과 외부에 생성한 yml 둘다 스프링 부트에서 사용하게 코드로 설정하길 바람!(코드간단)
TIP3) Nginx가 외부의 요청을 받아 뒷단 서버로 요청을 전달하는 행위를 리버스 프록시
간략히 구현방법 설명하자면? nginx 설치 및 내부 앱 포트 연결 → 안전하게 운영환경.yml을 외부에 생성 및 프로필2개에 포트(8081,8082)이런식 설정 → 배포 스크립트.sh 작성(현재 구동중 프로필 확인 후 nginx 연결 안된 프로필 찾아 할당해두고 구동중인건 종료하고 새로 할당한 섭 실행) → nginx가 근데 포트 설정엔 하나의 profile을 바라보고 있었을테니 이걸 변경하는 nginx동적 프록시 설정 → 배포시점에 이 바라보는 프로필을 자동으로 변경하는 nginx 스크립트 작성(포트도 자동으로 변경 하려는 거임) → 마지막으로 처음 만든 배포스크립트.sh에 뒤에 만든 자동변경 스크립트를 수행하게 하기 위해 스크립트 실행 코드까지 넣어주면 끝
댓글남기기