간단한 리마인드

 

일반적인 개념보다 앞으로의 방향이 어떻게 되어갈 것인지에 대하여 궁금하여 조금 더 공부를 해보고자 한다. 

 

컨테이너의 미래는 어떻게 될까? 출처 maritime NZ

 

컨테이너는 어플리케이션, 라이브러리, 설정 등을 하나의 단일한 패키지로 묶어 격리된 환경에서 실행하는 방식을 채택하고 있다. 기본적으로 컨테이너는 가상화 기술의 일종으로, 가상머신과 비슷한 목적을 가지고 있지만 그 실행 방식과 효율성 면에서 큰 차이를 보인다.

 

효율성면에서 큰 차이를 보인다-? 

이전에 VM 을 앱 배포에 채택하였던 구글 조상들의 고충은 뭐였을까.

 

가상머신은 운영체제와 함께 동작하는 풀 스택의 가상 환경을 제공하는데, 이로 인해 무겁고 느리게 동작하는 단점이 있었다. 반면에 컨테이너는 호스트 운영체제의 리소스를 효율적으로 활용하면서도 격리된 환경을 제공하여 가볍게 동작할 수 있도록 고안되었다. 아래 정리된 컨테이너의 장점을 보면 더 이해가 갈 것이다.

 

  • 격리(Isolation): 컨테이너는 각각이 독립된 환경에서 동작하기 때문에 한 컨테이너의 변화가 다른 컨테이너에 영향을 미치지 않습니다. 이는 애플리케이션 간 충돌을 방지하고 보다 안정적인 운영을 가능하게 한다.
    예시: 서로 다른 버전의 어플리케이션을 동시에 실행하거나 특정 환경에서의 실험을 위해 격리된 컨테이너를 사용할 수 있다.
  • 가상화(Virtualization): 컨테이너는 가상머신과 유사한 가상화 환경을 제공하지만, 가볍고 빠르게 실행됩니다. 이는 높은 성능과 빠른 배포를 가능케 하며, 여러 컨테이너를 동시에 실행할 수 있다.
    예시: 빠른 확장이 필요한 경우, 컨테이너를 사용하여 더 빠르게 새로운 인스턴스를 추가하고 활용할 수 있다.
  • 이식성(Portability):
  • 컨테이너는 실행 환경과 상관없이 동일하게 작동하므로, 개발 환경에서 테스트한 애플리케이션을 프로덕션 환경에 그대로 배포할 수 있다.
    예시: 로컬 환경에서 애플리케이션을 개발하고, 동일한 컨테이너 이미지를 사용하여 클라우드나 다른 서버에 배포할 수 있다.
  • 자동화(Automation):
  • Docker와 같은 컨테이너 도구는 애플리케이션 빌드, 배포, 확장 등을 자동화하여 개발 및 운영 효율을 높인다.
    예시: 코드 수정 시 자동으로 빌드되고, 업데이트된 애플리케이션이 자동으로 배포되는 등의 작업이 자동으로 이루어진다.
  • 관리 및 오케스트레이션(Management and Orchestration):
  • 컨테이너 오케스트레이션 도구들은 여러 컨테이너를 효과적으로 관리하고 확장하는 데 사용된다.
    예시: Kubernetes는 컨테이너를 클러스터로 구성하여 효과적으로 관리하고, 필요에 따라 자동으로 확장하거나 축소할 수 있다.

 

이제 궁금했던 점으로.

 

컨테이너의 향후 방향은 어떻게 진행 되어가고 있을까?

 

 

AI 및 자동화의 통합 : 사실 이 문제는 컨테이너 뿐 아니라 클라우드 관리 전반에 걸쳐 영향을 미치지 싶다. 솔직히 말하면 개발이고 운영이고 인프라고 생태계 전체를 송두리째 바꿔놓을 것 같다.

 

나는 node 베이스의 개발자로 AI 에 대해 잘은 모른다.

 

web2vec을 활용한 python 엔진을 몇 차례 돌려 보았던 정도. 그래도 open-ai 에서 베타로 출시한 assistant 와 다양한 feature 들, 그리고 open-ai 의 최신 엔진은 나올때마다 계속해서 물고 뜯고 적용해보고 있다.

 

( 무지막지한 회사 프로젝트의 연속 덕분이다 )

 

그래봤자 까막눈 수준, 이러한 내가 보았을때도 open-ai 는 확실히 말도 안되는 데이터의 양과 AI 성능을 보여준다. hugging face 를 비롯하여 open source 로 git에 올라오는 엔진들의 수준에 비하면 그냥 경이로울 정도의 격차라고 생각한다. 일반인들이 생각하는 AI 현실화는 더 가속화되지 않을까 싶다. 실제로 open-ai 엄청나게 써대고 있으니까 더 빨라지지 않을까.

 

우리는 이제 끝났다.

 

다중 클라우드 및 하이브리드 클라우드 지원 : 기업들은 고객 요구 사항 및 비용 효율성 등을 고려하여 여러 클라우드 환경을 동시에 활용하거나, 하이브리드 클라우드 환경을 적용하려는 경향이 있다. 컨테이너는 환경 간 이식성이 뛰어나기 때문에 다중 클라우드 및 하이브리드 클라우드에서의 활용이 강조되어가고 있는 추세이다.

 

이미지 업로드 = 리소스 절감 이 공식처럼 되어버렸다.

아마 IT 기술에 대해 잘 모르는 대표들도 컨테이너로 배포하라는 말은 어디서 듣고와서 입에 달고 살지 않을까 싶다.

 

Container 와 전혀 무관한 사진이다.

 

서버리스 컨테이너 활용의 확대 : 서버리스 컨테이너 기술은 더욱 진화하여, 애플리케이션의 작은 부분들을 빠르게 실행하고 관리하는 데에 더 큰 중요성을 갖게 될 것으로 예상된다고 한다. 마이크로 서비스 단위로 계속해서 쪼개지는 것이다. 사실 현재에도 잘 설계된 서비스들은 사용하는 양에 따라 리소스가 조정되고 매니징되고 컨테이너 별로 잘 나뉘어져 있다. 더 쪼갤 필요성이 없다는 것이다.

 

service 의 단위를 마냥 쪼개는 것이 효율적이지는 않을 것이다. 리소스는 절감되지만 사람은 살려달라고 소리를 지르게 되지 않을까. 그걸 모니터링 하는 건 결국 휴먼이니까. - 다만, AI가 적용된다면 이것 또한 새로운 이야기일 것이다. 그때는 Container 개념이 아니라 AWS의 Lambda 와 더 가까워지겠지..

 

 

 

 

컨테이너에 대한 리마인드,

끄적끄적 생각 끝. 

 

쿠버네티스는 조타수를 뜻하는 그리스어다.

 

 

 

 

Brief Intro

간단하게 쿠버네티스는, 컨테이너 런타임 활용에 대한 서비스를 지원하는 오케스트레이션 플랫폼이다.

 

컨테이너 기술이 새로운 국면을 맞이하게된 시점으로 돌아가보자.

 

당시에는 배포 가능한 애플리케이션 구성 요소의 수가 많아지고 있었고, 이에 따라 앱의 모든 구성 요소의 관리가 점점 어려워지는 바람에 구글은 골머리를 썩고 있었다.

하이퍼바이저가 적용된 베어메탈에서 여러 개의 앱을 띄운다고 생각해보자.

( 하이퍼 바이저는 physical server 즉 베어 메탈로 하여금 리소스를 분배하여 가상 머신을 만들고 실행 시킬수 있도록 해주는 프로세서라고 생각하면 된다.) 

 

첫 번째 방법으로는, 서비스마다 VM 을 띄우는 것 (모든 마이크로서비스가 한 개의 VM에 집약되어 관리되는 모놀리스 방식) , 두 번째 방법으로는 VM 이 아닌 리눅스 '컨테이너' 를 활용하여 리눅스 커널단에서 직접적인 배포 라는 두 가지 옵션이 있을 것이다.

 

전자의 경우 도커와 컨테이너가 유행하기 이전까지 전형적인 앱 배포 방식이었다. 배포해야 할 서비스의 수가 늘어날 수록 리소스 관리 측면에 있어서 어려움이 있을 수 밖에 없는 것은 당연한 일이었다.  이에 반해, 이동성과 리소스 효율성이 뛰어났던 컨테이너의 경우 최신 클라우드 네이티브 애플리케이션의 컴퓨팅 단위가 되었다. 

 

 

Details

왜? 라는 질문을 했다면... 좋은 자세다. 굿.

 

 

리눅스 컨테이너 - 컨테이너를 활용하였을 때 VM 을 통한 배포보다 리소스 효율성과 이동성이 뛰어난 이유는 무엇일까?

 

 

 

컨테이너 기술이 가상 머신 (VM)을 통한 애플리케이션 배포보다 우수한 이유는 크게 다섯 가지 측면에서 나타난다.

 

이동성 (Portability)

컨테이너는 응용 프로그램과 필요한 모든 종속성을 패키지로 묶어 이식성이 뛰어나다. 컨테이너는 호스트 시스템의 운영체제와 상관없이 동일한 환경에서 실행될 수 있으며, 개발 환경과 프로덕션 환경 간에 쉽게 이동할 수 있다. 컨테이너는 하나의 패키지다. 앱을 run 하기 위한 명령, meta-data가 모두 포함된 하나의 패키지 덩어리이기 때문에 어떠한 앱을 다른 워크 노드에서 띄우는데 문제가 전혀 없다. ( run app A on B node, -> run app B on C node (o) ) 

 

리소스 효율성 (Resource Efficiency)

가상 머신은 전체 운영체제를 가상화하고 별도의 커널을 사용하기 때문에 무겁고, 높은 오버헤드가 발생한다. 반면, 컨테이너는 호스트 시스템의 커널을 공유하므로 가벼우면서도 빠르게 시작되고 중지될 수 있다. 이로써 더 적은 메모리와 디스크 공간을 사용하며, 빠른 배포와 확장이 가능하다. (반대로 생각하면? 별도의 커널이나 OS설정이 필요한 애플리케이션의 경우 컨테이너를 활용할 수 없다)

 

시스템 관리 용이성 (Management Ease)

컨테이너는 이미지로서 애플리케이션 및 종속성을 패키징하므로, 관리 및 배포가 훨씬 간단하다. 이는 개발, 테스트, 그리고 프로덕션 환경에서 일관성 있는 운영을 가능케 한다.

 

자동화와 스케일링 (Automation and Scaling)

컨테이너 오케스트레이션 도구들 (예: Kubernetes, Docker Swarm)을 활용하면 컨테이너를 자동으로 배포하고 관리할 수 있다. 이는 애플리케이션의 자동 확장과 고가용성을 쉽게 구현할 수 있게 한다. ( 간단하게 말하면, 컨테이너와 관련된 여러 툴들이 이미 많이 있기 때문에 직접 VM 안에서 배포를 위해 이것저것 만지지 않아도 된다는 뜻이다)

 

개발자와 운영팀 간 협업 (DevOps Collaboration)

컨테이너는 애플리케이션과 인프라스트럭처를 분리함으로써 개발자와 운영팀 간의 협업을 강화한다. 개발자는 애플리케이션을 개발하고 패키징하고, 운영팀은 컨테이너를 관리하고 배포하는 데 중점을 둘 수 있다.

 

다른 모종의 이유들도 많겠지만, 위의 큼지막한 다섯 가지 이유만으로도 컨테이너 기술은 현대의 애플리케이션 배포 관리에서 매우 인기 있는 선택지가 되었다 정도 알고 있으면 좋을 것 같다.

 

Linux / Kubernetes 와 관련된 디테일은 차차 공부하며 정리하도록 하고, 내일은 Container와 뗄레야 뗄 수 없는 Docker 에 대해서 잠깐 정리하고 지나가고자 한다. 

 

 

에이전트 풀이란 뭘까? 

 

에이전트 풀은 마이크로소프트의 Azure DevOps에서 사용되는 공간이다.

이해하기 쉽게 설명하면, 이 공간에는 작업을 수행하는 작은 개체들이 있고 이 작은 개체들을 '에이전트'라고 부른다.

 

에이전트 풀은 누군가 자체적으로 만들어야 하는 것이 아니라 마이크로소프트에서 미리 만들어 놓은 공간이다. 이곳에는 다양한 종류의 작업을 할 수 있는 여러 기능이 준비되어 있다. 

 

그런데 가끔은 마이크로소프트에서 만들어 놓은 에이전트가 아니라, 우리가 직접 만든 커스텀 에이전트를 사용하고 싶을 때가 있을 것이다. 이때 에이전트 풀을 만들고, 그 안에 커스터마이징 한 에이전트를 넣어둘 수 있다. 이렇게 만든 풀을 '자체 호스팅 에이전트 풀'이라고 부르고, 그 안에 들어가 있는 개체를 '자체 호스팅 에이전트'라고 부른다.

 

 

에이전트 풀이 왜 필요할까?

 

당신이 레고 블록으로 무언가를 만든다고 상상해봐라. 에이전트 풀은 그 레고 블록을 담아두는 상자이다. 상자 안에는 여러 종류의 블록이 있어서 필요할 때마다 쉽게 가져와서 사용할 수 있다. 때로는 커스터마이징 된 블록도 상자에 담아두고 싶을 때가 있을 것이다. 에이전트 풀을 사용하면 그런 작업을 할 수 있게 한다.

 

말을 반복해서 다시 한번 요약해보면, 에이전트 풀은 작업을 처리하는 개체들을 담아두는 특별한 공간이다. 에이전트 풀을 사용하면 작업을 효율적으로 처리할 있고, 필요할 때마다 필요한 개체만을 사용할 있다.

 

에이전트 풀에는 2 type 이 있는데 무료로 사용할 수 있는 Microsoft 호스팅 풀이 있으며(일부 제한이 존재하기는 함), 또는 자체 호스팅된 에이전트를 만들어 자체 호스팅 풀에 연결할 수 있다.

 

  • Azure Pipelines: 기본 Microsoft 호스팅 풀로서 다양한 Ubuntu, MacOS 및 Windows Server 에이전트를 사용한다.
  • Default: 자체 호스팅된 에이전트를 연결 방식을 의미한다.

 

그래서 에이전트가 뭘 하는데?

 

1. 작업 실행 

에이전트의 주된 역할은 빌드 또는 릴리스 파이프라인에서 정의된 작업을 실행하는 것이다. 코드를 컴파일하거나 테스트를 실행하고 응용 프로그램을 배포하는 등의 개별 단계나 동작을 의미한다.

 

2. 환경 설정

에이전트는 작업에 필요한 런타임 환경을 설정한다. 이는 종속성을 설치하고 설정을 구성하며 파이프라인에서 정의된 특정 작업을 실행하기 위한 환경을 준비하는 것을 의미한다.


3. 아티팩트 검색 및 게시

에이전트는 빌드 프로세스에서 필요한 소스 코드 및 기타 종속성을 검색한다. 성공적인 빌드 후, 에이전트는 아티팩트(컴파일된 이진 파일, 패키지)를 Azure DevOps에 게시하여 이후의 작업이나 단계에서 사용할 수 있도록 한다.


4. 테스트 실행

빌드 파이프라인의 맥락에서, 에이전트는 주로 코드의 품질을 보장하기 위해 테스트를 실행한다. 이는 단위 테스트, 통합 테스트 또는 프로젝트에서 정의된 기타 테스트를 포함하는 의미이다.


5. 배포

릴리스 파이프라인에서 에이전트는 응용 프로그램이나 서비스를 다양한 환경(스테이징, 프로덕션 등)에 배포하는 데 중요한 역할을 한다. 에이전트는 배포 작업을 실행하고 구성을 관리하며 응용 프로그램이 올바르게 배포되도록 보장한다.


6. Azure DevOps 서비스와의 통신

에이전트는 지시를 얻고 진행 상황을 보고하며 업데이트를 받기 위해 Azure DevOps 서비스와 통신한다. 에이전트는 안전하고 신뢰성 있는 상호 작용을 위해 안전한 연결을 사용하며 개인 액세스 토큰(PAT)을 사용하여 인증한다.


7. 병렬 실행

에이전트는 병렬 실행을 지원하여 여러 작업이 동시에 실행될 수 있도록 한다. 이는 대규모 프로젝트에서 특히 효율성을 높이는 데 도움이 된다.

 

8. 로그 및 보고

에이전트는 작업 및 작업 실행 중에 로그를 생성한다. 이 로그는 각 단계에 대한 자세한 정보를 제공하며 문제 해결이나 파이프라인의 진행 상황을 이해하는 데 도움이 된다. 


요약하면, 에이전트는 Azure DevOps 파이프라인에서 정의된 지시를 따라 수행하는 다재다능한 작업자로 볼 수 있다. 환경 설정, 작업 실행, 테스트 실행, 응용 프로그램 배포 및 Azure DevOps 서비스와의 통신 등을 담당하여 원활하고 자동화된 DevOps 프로세스를 수행해준다.

Azure portal ... 가만두지 않을테다.

 

inbound IP 는 대상에 집어넣으면 안된다.

 

소스에다가 카테고리 IP address 로 바꾸고 해당 IP 넣어줘야한다.

 

대상에다가 넣고 삽질하다가 원래 안되는줄알고 집어 던질 뻔했다. nginx 로 가서 detour way 찾았고, allow IP list 작성 후 deny ALL other ip address 해버렸다. nginx 문구 나오면서 403 나오는게 너무 분해서 계속 찾기 시작했다. 한참 돌아본 후 대상이 아닌 소스 카테고리에 변경해줘야 하는 것을 알았다. 

 

번역에 문제가 참 많다. UI / UX 는 바라지도 않으니 제발 번역이라도 잘 해놨으면.. 하는 생각이 들었다.

덕분에 mongoDB / backend 사이에 proxy 잡아줘야 하는 작업을 못했다... 한글 버전을 쓰고 있는 나의 잘못이다.

 

빨리 스테이징 셋업이 필요하다.

결국 오늘 한 일 FE / BE port IP inbound 걸고 DB 용 vm 에 inbound 걸어둔거 끝..

 

유럽 클라 서버 아이피도 뚫어놔야한다 까먹지 말자. 

 

Docker 걷어내고 ACI 집에 넣는 작업 먼저 하려고한다. 따로 Azure pipeline이라는 기능이 있어 애플리케이션 레벨 빌드 테스트부터 전부 셋업해두려고 한다. 

 

사실 ACI 같은 경우, 개발 풀 자체가 전무후무 해보이기도 해서 왜 쓰는지 잘 모르겠지만.. 같은 Azure Platform에서 관리할 수 있다는 점 때문에 되도록 깊이 들여다보려 한다.

 

오늘 다 하고 잘거다.

죽어도 마무리 하고 잔다.

 

proxy setup 끝 

Backend Source 수정 필요 -> proxy 서버로 Request 날아가도록.. 프록시는 안전상 설정해두긴 했지만 포탈 credential이 통째로 날아가지 않는 이상 굳이 필요한 작업인가 싶기도 하다. 앞으로의 기능도 Load balancing 정도 일 듯 해서. 

 

Azure Pipeline 필요성이 크지 않다면 jenkins로 파이프라인 잡으려 한다.

 

'Configuration' 카테고리의 다른 글

실무 개발 환경 / 배포 시 환경 설정  (0) 2022.12.11

3. Backend 배포하기

 

배포에는 두 가지 라이브러리를 사용할 예정이다. 

App containerize 에는 docker, 그리고 node process management 에는 PM2.

 

구조적으로 보면 VM 내에 backend 와 frontend 두개의 레퍼지토리가 있고, 이 위에 도커가 존재하며 back container / front container 각각을 컨테이너로 분리한다. pm2 는 back container 내에 프로세스 매니징 툴로 이식 된다.

 

 

 

(1) PM2 node process manager 적용

 

 

PM2 를 쓰는 이유? 가장 보편화되고 안정적인 node process manager이기 때문에

 

 

 

npm 으로 pm2 를 먼저 설치한 후 ecosystem.config.js 파일 내에 module config 를 작성해준다. 온라인에 찾으면 많은 예시들이 있을 것이다. 어려울 부분이 없으니 차근차근 작성한 후 local 에서 node를 pm2 로 실행시켜보자.

 

pm2 start ecosystem.config.js 
pm2 status 
pm2 restart 0 / 1 / 2 ...
pm2 logs 0 / 1 / 2 ...

 

 

 PM2 status 를 확인해보면 두 개의 클러스터가 돌고 있는 것을 확인할 수 있다.

클러스터를 두 개로 한 이유는, 한개의 클러스터가 모종의 이유로 멈춰버렸을 시 pm2 가 두 번째의 클러스터를 돌리도록 하기 위함이다. 

 

서버의 부하가 심할 일도 없고, 어떠한 이유로도 멈출 가능성은 많지 않지만 prod 에 적용될 몇 가지 테스트를 진행하기 위해  클러스터를 두가지로 분리해주었다. 나중에 부하 테스트로 첫 번째 cluster를 강제로 멈춰볼 생각이다. 

 

 

하나의 node application 을 두개의 클러스터로 run 시켰다

 

 

 

(2) Docker - containerize

 

 

Server / Source managing 이 끝났으니 backend app 을 컨테이너화 시켜야 한다. 

VM 에 docker 설치를 진행한 후, nest-app root directory 에 Dockerfile을 생성해준다. Dockerfile은 도커 명령어를 실행시키기 위한 package.json 에 가깝다고 보면 좋을 것 같다. 

 

docker-compose.yml 파일로 config 를 푸시하는 과정도 있는데 그 과정은 따로 정리하기로 하고 일단 컨테이너화부터 시켜보자.

 

지금은 당장 docker-compose.yml이 필요하지 않다. 

pm2 를 사용하여 node process를 관리하고 있으므로 

 

Dockerfile 도 아래와 같이 작성해주면 된다.

 

FROM node:18
RUN mkdir -p /var/app
WORKDIR /var/app
COPY . .
RUN npm install -g pm2
RUN npm install --force
RUN npm run build
EXPOSE 4040
CMD ["pm2-runtime", "start", "ecosystem/development/ecosystem.config.js", "--env"]

 

 

일반적으로 document에서 제시하는 Dockerfile format 과 다른점은 pm2-runtime 을 cmd로 사용하고 있다는 점이고, 이를 위해 npm install -g -pm2 를 먼저 실행시켰다.

package.json 에 pm2 가 잘 들어가 있는 것을 확인하였는데, npm install 시에 왜 제대로 설치되지 않는 것인지 이유를 잘 모르겠다. 꼭 -g 명령어로 전역 설정을 해주어야 제대로 돌아가더라. 해당 내용도 왜그런지 찾아봐야겠다.

 

무튼간에 WorkDir /var/app으로 맞춰두었고, 나 같은 경우 ecosystem.config.js 파일을 root directory 에서 관리하는 것이 아니라 환경에 따라 세 가지로 분류하여 관리하였기 때문에,  CMD 내에 정확한 ecosystem.config.js 위치를 적어주었다.

 

 

{"originWidth":1870,"originHeight":316,"style":"alignCenter","caption":"ecosystem/development

 

 

Dockerfile 작성이 끝나면 container 를 생성해주자. 

 

 

// docker container 생성. -t 는 태그. tag 는 optional이니까 굳이 안넣어도 되긴하다. 
sudo docker build . -t your-app-name:tag

// docker container run 명령어. 
// -d 는 detached : container를 background에서 실행시키고, 터미널은 다른 커맨드 실행을 위하여 해당 컨테이너에서 분리.
// -p 는 port : host port는 앞에 오고, container port는 뒤에 온다.  
sudo docker container run -d -p 4040:4040 your-app-name

sudo docker ps
sudo docker stop CONTAINER_ID
sudo docker images
sudo docker rm CONTAINER_ID (컨테이너 삭제 - stop 이후 사용)
sudo docker rmi IMAGES_ID --force (이미지 삭제 - container stop 되어야 삭제 가능)\

// pm2 process monitoring
sudo docker exec -it {컨테이너이름} pm2 list

// 실행중인 pm2 로그 확인
sudo docker exec -it {컨테이너이름} pm2 log {pm2 list 중 하나. ex) nest-app}

 

 

최상단에 위치한 명령어 부터 실행시켜보며 container 가 생성되었는지와 running status, 그리고 pm2 를 통한 container 내의 node process monitoring 까지 진행해본후 디버깅 과정을 마무리하면 백엔드 배포는 끝났다고 보면 된다. 

 

 

 

 

 

'Deployment > Guide' 카테고리의 다른 글

Deployment 2 - DNS / NGINX  (0) 2023.10.30
Deployment 1 - VM  (0) 2023.10.30

2. DNS 설정하기

 

Deployment 1 에서 생성한 vm에서 application을 배포하였다고 가정하자.

VM에서 돌고 있는 Frontend / Backend - local server 인 localhost:3000 / localhost:4040로 어떻게 외부 요청을 받아 넘겨줄까?

Azure Portal의 리소스 그룹 -> 네트워크 설정에서 확인할 수 있는 Public IP 로 요청을 날리면 된다. Public IP + port 로 날리면 되는 것이다. 다만 Public IP와 port 정보를 외부에 공개하는 것은 보안상 문제가 되기에 DNS 관리를 통하여 이 주소를 매핑해주는 것이 좋다.

 

그래서 할일은 -> DNS 호스팅을 통하여 URL을 매핑하고 nginx 를 통해 vm과 인증을 거쳐 연동시키는 과정이다.

좀 복잡하니 잘 보면 좋겠다. 

 

(1) VM access -> Nginx 설치 -> Certbot SSL 설치 -> DNS 설정

 

 

 

 

// 1. ssl 설치

sudo apt-get update

sudo apt-get install certbot -y => certbot 설치


// 2. access token 발급을 위한 여러 단계를 거친다. yes 로 넘어가다가 token을 받는 시점에 잠깐 스톱 & DNS 호스팅 플랫폼에 세팅을 한 후 다음 스테이지 yes 로 넘겨야 한다. 

sudo certbot certonly --manual

마지막에 _acme-challenge 값 나오면 DNS 호스팅 플랫폼에 세팅

 

 

2. 번에서 token 을 받는 시점에 DNS 호스트 설정 해주고, ( 해당 첨부 화면처럼 ) 그 다음 스탭으로 yes 눌러 넘어간다.

 

 

 

// 3. nginx 설치

sudo apt-get install nginx -y => Nginx 설치

cd /etc/nginx/sites-available => Nginx config 설정 위한 폴더로 이동

sudo vi default  => Nginx config 설정 위한 폴더로 이동

 

 

nginx 를 설치하고 나면 cd /etc/nginx 경로로 들어간 후 sites-available 이라는 폴더가 생성되었는지 확인한다. 

해당 폴더 안에 있는 default 파일을 통하여 nginx 설정을 업데이트 해주면 된다.

 

 

 

 

sudo vi default 라는 명령어를 입력하면 아래와 같은 화면이 보이게 되는데 server { listen 80 default ~~ } 에 해당하는 첫 번째 객체 부분 다음에 동일한 포멧이지만 조금은 다른 내용으로 설정을 추가해주면 된다. 수정 할 때 Insert 기능으로 전환하기 위해 i 누르는 것 잊지 말자.

 

 

i 를 누르면 밑에 Insert 라고 나온다.

 

// default 입력 되어 있던 부분.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _; # Catch all server_name.

    location / {
        try_files $uri $uri/ =404;
    }

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

// port 443 으로 추가 입력한 부분.
// YOUR_DOMAIN 으로 표시해둔 부분은 ssl 진행하는 시점에서 certbot이 터미널에서 물어 보았던 your domain 그대로 입력하면 된다. 

server {
    listen 443 ssl;
    server_name ${YOUR_DOMAIN};

    root /var/www/html;

    ssl_certificate /etc/letsencrypt/live/${YOUR_DOMAIN}/fullchain.pem; # Managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/${YOUR_DOMAIN}/privkey.pem; # Managed by Certbot

    # https websocket
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;

    location / {
        proxy_pass http://localhost:3000;
    }

    location /apis {
        proxy_pass http://localhost:4040;
    }
}

 

 

 

이 정도 입력하였다.

 

입력한 후에는 esc 누르고 :wq! (write and quit) 입력 후 enter. 

 

주목해야 할 부분은 내가 입력해둔 server 443의 location / { proxy_pass http://localhost:3000} 과

location /apis { proxy_pass http://localhost:4040} 파트다.

 

{YOUR_DOMAIN}으로 들어온 요청은 localhost:3000 으로 연결 될 것이고, {YOUR_DOMAIN}뒤에 /apis 라는 prefix 가 붙은 요청들은 VM 에서 돌고 있는 localhost:4040 으로 request가 pass 된다는 의미이다. 

 

예를 들어, DNS 에서 example.com을 당신의 도메인으로 설정해두었다면, localhost:3000 (Frontend) 에 대한 요청은 example.com 으로 맵핑되고 localhost:4040/apis (backend) 에 대한 요청은 example.com/apis 로 맵핑된다고 이해하면 좋겠다. 

 

 

 

 

DNS / Nginx 설정 끝.

'Deployment > Guide' 카테고리의 다른 글

Deployment 3 - Backend (Nest.js)  (0) 2023.10.30
Deployment 1 - VM  (0) 2023.10.30

- 배포 환경 : Azure Portal

- DNS : Gabia

- Backend Server : Nest.js, Pm2 (process manager), Docker (App Isolator), ACI (Container Hub)

- Database : MongoDB 

- Frontend : Next.js 

 

1. VM 생성하기

 

 

앱을 배포하기 위해서 자체 서버를 돌리지 않는 이상, 당연히 VM이 필요하다.

마이크로소프트가 제공하는 에저의 클라우딩 서비스를 공부하는 중이기도 하고, 마침 회사에서도 B2B 솔루션을 메인잡으로 하고 있기에 Azure Portal 을 이용하여 VM을 생성하였다. 개인 소영업과 스타트업의 경우에는 AWS를 더많이 사용하는 추세인 듯 하다. 반대로 90%의 Industry Giant들은 MS가 제공하는 애저를 사용한다.

 

 

(1) Azure Portal -> Resource 만들기 -> 가상머신 만들기 

 

 

 

VM 에 필요한 리소스와 가용성, Cloud server location 등은 필요에 따라 맞춰주면 된다. 이미지의 경우 테스트를 위해 Ubuntu Server 중 가장 저렴한 것으로 설정했다.

 

 

아래는 가상머신 만들기의 기본 사항 탭이다. 그 중 관리자 계정 파트는 나중에 VM 에 접근 할 Auth를 설정하는 곳이라고 보면된다.

나와 같은 경우는 인증 형식을 암호로 체크하였다. 직관적이고 익숙한게 좋아서..

 

 

 

 

사용자 이름에는 본인이 사용하고 싶은 이름, 암호에는 본인이 사용하고 싶은 암호를 넣으면 된다. 

이 부분은 나중에 vm 접근 시에 당신이 만든 VM의 "ssh"+ "publicIP" + "-l" + "yourID" 순으로 터미널에 입력된다. 

그 이후에 터미널에서 묻는 query 에 설정한 password 를 입력하면 vm 으로 접근이 된다. 

 

방금 설명한 내용은 아래 참고하면 된다.

 

password 입력시에 안보인다고 쫄지 마시고, 끝까지 잘 입력 후 enter 누르시길.

 

 

(2) 디스크 설정 -> 네트워킹 설정 -> 관리 -> 모니터링 -> 고급

 

나머지는 건드릴 만한 내용이 솔직히 없다. 네트워킹과 같은 경우 인바운드 포트를 눌러보면 HTTP, HTTPS 가 나오는데 이 둘에도 체크를 해주자. 태그 탭에 이르면, VM 에 붙이고 싶은 이름과 값을 입력해주면 된다. 결론적으로 의무적으로 건드릴 부분은 기본사항 / 네트워킹 / 태그 / 검토 + 만들기 정도이다. (나머지는 필요에 의해서.)

 

 

왠만하면 부하 분산 옵션에 Load Balancer 도 체크해주자. 알아서 부하 분산을 체크하고 모니터링 해주는 Azure 자체 서비스다.

 

 

 

VM 생성이 잘 되었고 access 에도 문제가 없다면 docker 를 통한 app containerize 차례다.

아니다 그 이전에 nginx 로 DNS 먼저 잡아보자

'Deployment > Guide' 카테고리의 다른 글

Deployment 3 - Backend (Nest.js)  (0) 2023.10.30
Deployment 2 - DNS / NGINX  (0) 2023.10.30

react, next 개발 시, 개발 환경과 배포 환경에 대한 기본 설정에 대한 정리.

 

node.js 에서 개발을 시작. 

 

첫번째, package.json 파일에 기본 설정을 하게 된다.

이때 package.json이란 현재 프로젝트에 관한 정보와 패키지 매니저 (npm, yarn)을 통해 설치한 모듈들의 의존성을 관리하는 파일을 말한다. Json 포멧으로 관리한다.

 

의존성 모듈을 설치하게 되면 dependencies 라는 배열 내에 해당 모듈과 이름이 추가된다. 내가 추가하지 않아도 패키지 매니저를 통해 모듈을 설치하면 자동으로 package.json을 수정해주니 딱히 건드릴 일은 없다.

 

두번째, 개발을 진행하다보면 개발환경과 배포환경을 다르게 해야 하는 경우가 생긴다.

예를 들면, DB를 mysql로 진행한다고 하였을때, 현재 운영하는 DB와 개발 시 동작이 가능한지를 판단하는 DB는 다르게 만들어야 하기 때문에 DB의 id/pw가 다르게 설정을 하여 시작 시 필요한 DB를 사용할 수 있게 만드는 것이 좋다. 정리하면 개발환경과 운영 환경에서의 변수 값을 다르게 설정해야 할 경우 아래의 방식을 이용하면된다.

 

개발 환경과 배포 환경을 따로 설정

환경변수 선언(.env)을 통해 한다. .env의 종류는 여러가지가 있는데, .env.local, .env.development, .env.test, .env.production이 있다. 

 

0. 기본 개념 ( 환경 변수) 

결론만 정리하면 개발용, 테스트용, 릴리즈용 환경변수를 위한 env 파일을 각각 따로 생성하여 관리하여야 하며, env 파일은 말그대로 환경변수를 저장하고, package.json 에서 npm 또는 yarn명령어를 다루게 된다.

 

기본적으로 node.js 는 production와 Development, Test로 구분하여 사용한다. Build시 또는 run시에 실행 명령어에 따라 자동으로 NODE_ENV값이 정해진다.

 

// production 배포 env실행
npm run build

// development 개발 env 실행
npm start

// test 개발 env실행
npm run test

실행 OS에 따라 환경변수를 설정하는 방법이 다르기 때문에, 환경 변수 설정 시 undefined가 나오는 경우가 있다. 따라서 아래의 명령어를 실행하여 cross-env 모듈을 사용하여 환경변수를 설정하는 것이 좋다.

 

npm i cross-env

설치 후에 아래와 같이 package.json 에서 사용이 가능하다. 

이후에 package.json 에서 scripts 내에 명령어를 지정해줌으로써 사용이 가능하다.

// 사용법 'cross-env 환경변수1=값 환경변수=2값 실행 명령어

"scripts" : {
	"local":"cross-env REACT_APP_API_URL=localhost react-scripts-start",
    "build":"cross-env REACT_APP_API_URL=999.99.99.99 react-scripts start"
}

0.1 .env.local (로컬 개발 시)

.env.local 파일은 .env를 덮어쓰는 파일로, test 환경외의 모든 환경에서 로딩된다.

 

02. .env.development

.env.development 파일은 개발환경 시 아래의 명령어를 치면 사용된다. 만약, .env.development.local이 있다면, .env.development을 덮어쓴다.

 

npm start 시 env 파일도 실행되는 우선순위가 있다. 우선 순위는 아래와 같다. 

.env.development.local > .env.development > .env.local > .env

 

0.3 .env.production (서버 배포 시)

.env.production 파일은 배포 환경 시 사용되며, 아래의 명령어를 치면 자동으로 사용된다. 만약, env.production.local 이 있다면, .env.production을 덮어쓴다.

 

npm run build 시 env 파일도 실행되는 우선순위가 있다. 우선 순위는 아래와 같으며 오른쪽을 먼저 실행한다.

.env.production .local > .env.production > .env.local > .env

 

0.4 .env.test

.env.test 파일은 테스트 환경 시 사용한다. 만약, .env.test.local 이 있다면, .env.test을 덮어쓴다.

npm run test $ yarn test

 

npm run test시 .env 파일도 실행되는 우선순위가 있다. 우선순위는 아래와 같다.

.env.test.local > .env.test> .env.local > .env

오른쪽이 우선실행된다.

 

'Configuration' 카테고리의 다른 글

Memo - 막 적는 메모.  (0) 2023.11.05

프로젝트를 진행하다 Rust tauri 로 작업을 하게 되었다.

몇 가지 개념 정리를 해보려 한다.

 

나의 영어가 갈수록 구려지고 있으므로 억지로라도 영어를 사용하겠다...

 

Rust란 무엇인가?

Rust is  an open-sourcce system programming language which can provide more effective and safe way to build up the software. You can also use it for a simple repetitive job or an interface.

 

Rust 모듈 시스템

Rust provides clients with a set of the functions which help them to manage and construct the code structure. This program is normally consisted with the Crate, Module, and etc.

 

- Crate : Compilation Unit of Rust. This is the smallest unit compiled by Rust. 

- Module : Rust module is like an constructor which can help programmers to in a crate unit.

- Path : You can simply name the code by using path. For example, path can be a definition for vector, code function and module etc. You can also manage the private info in the path by using module. s

 

Rust 표준 라이브러리 및 타사 크레이트

 

Rust Cargo 도구 및 종속성 관리자

 

Rust 는 언제 사용하는가

 

 

 

 

Build가 뭔지 중요성을 알고 있지 못했다. 

 

그냥 막연하게 - 프로젝트를 서버에 올리기 위한 'deploy' 작업에 앞서 거쳐야 하는 export 과정으로만 이해하고 있었다.  

멍청하게도 개발자로 막 취업을 한 이 시점까지 모르고 있다.

 

빌드란 소스 코드 파일을 컴퓨터에서 실행할 수 있는 독립적 형태로 변환하는 과정을 말한다. 예를 들어 JSP 기반의 프로젝트를 진행한다면, 개발자가 작성한 Java 프로젝트를 진행한다면 개발자가 작성한 A.java와 여러 html과 같은 정적 파일 등에 해당하는 resources가 필요하다. 

 

이때 빌드는 소스코드를 컴파일해서 .class로 변환하고 resource를 .class에서 참조할 수 있는 적절한 위치로 옮기고 META-INF 와 MANIFEST.MF들을 하나로 압축하는 과정을 의미한다.

 

컴파일은 빌드의 부분 집합이라고 생각하면 된다.  이러한 빌드 과정을 도와주는 도구를 Build Tool이라고 하며

컴파일 된 코드를 실제 실행할 수 있는 상태로 만드는 일을 Build라는 개념으로 생각하면 된다.

 

빌드 툴의 종류에는 우리가 프로젝트 할 때마다 사용 했었을 Maven, Gradle등이 해당된다.

 

Build = Compile + 그 외 작업

Run = Build + 실행 

 

 

Ref: https://velog.io/@leede418/CS-Compile-Link-Build-%EB%9E%80

 

+ Recent posts