==어려운 게 아니라 낯선 것..==
우리는 흔히 “서버에 배포한다”, “서버에 올린다”, “서버가 터졌다” 이런 말들을 많이 들어봤을 것임. 개발자가 아닌 IT 서비스를 사용하는 일반적인 사용자 입장에서도 친숙한 단어임. (ex. 수강신청, 카카오서버터진사건)
그러면 유저가 아닌 개발자에게 “서버”는 도대체 무엇일까? 사전적 의미의 Server는 무언가를 제공해주는 것(사람이나 물건)을 의미함.
무언가가 뭔데?
우리는 흔히 인터넷으로 특정한 웹사이트나, 자료를 받고 음원을 다운로드하고 등 리소스에 접근함. 하지만 정확히 말하자면 우리가 접근하는 대상은 웹사이트와 리소스 자체가 아니라 해당 웹사이트와 리소스를 응답해주는 컴퓨터 에 접속하는 것임.
우리가 추상적으로 서비스가 운영되고 제공되는 과정을 알아보자면, 서비스를 운영하기 위해서는 특정한 컴퓨터(물리적)를 가동시켜야 함. 그리고 해당 컴퓨터에서 무언가를 제공해줘야 함. 근데 첨부터 끝까지 다 만들고 제공해줄 수 없음. 그래서 그 무언가를 제공해주기 위한 특정 프로그램이 이미 만들어져 있음.
그리고 특정 프로그램을 실행시켜서 컴퓨터에 네트워크를 통해 접근하면 특정한 "리소스"를 응답해주도록 만듦. 이런 과정을 하고, 그리고 인터넷을 통해서 이 컴퓨터를 최종적으로 외부에서 접근 가능하도록 설정함. 이러한 동작을 하는 컴퓨터를 우리는 흔히 “서버"라고 부름. 이게 우리가 서버를 운영하는 개념!
근데 서버는 관념적인 게 아닌. 서버는 명백히 하드웨어임. 서버는 물리적인 실체가 있는 컴퓨터 임. 컴퓨터를 마우스, 키보드, 모니터 제외하고 본체만 생각해보면 핵심이 되는 CPU, GPU, RAM, Memory 등으로 이루어져있고 각기 사양을 가지고 있음.
우리가 흔히 “서버가 터졌다" 라고 말하는 것은 어떤 상황일까?!
서버 컴퓨터가 사용가능한 사양을 넘어서는 계산이 필요해진 경우 컴퓨터가 제대로 모든 계산들을 처리해내지 못하는 상황 또는 서버 컴퓨터에서 실행중이던 프로그램이 의도치 않게 종료되어서 더이상 운영이 안되는 상황, 인터넷을 통해서 서버 컴퓨터에 접근을 할 수 없는 상황등을 의미함
그렇다면 개발자에게 가장 중요한 문제인 이러한 서버를 안정적으로 운영하기 위해서는 어떻게 해야 할까? (안정적이라는 것은 사용자에게 요청이 오면 제대로 응답을 해줄 수 있는 상황을 계속해서 유지하는 것)
서버 컴퓨터를 운영하는 방법은 크게 두가지로 나뉨.
온 프레미스 방식이라는 것은, 서버를 운영하는 측에서 서버에 필요한 물리적인 공간, 컴퓨터, 제반 시설 등을 직접 구축해서 활용하는 방식을 의미함. 온 프레미스 방식은 직접 물리적인 서버를 구축하고 관리할 수 있는 전문 인력이 하드웨어를 구입해서 서버실을 구성하고 설계함
온 프레미스 방식은 서버를 운영하는 가장 기본적인 방식이지만
하지만 IT 굉장히 빠르게 급변하는 시장임. 급변하는 IT 업계에서 여기에 맞춰서 내가 유지 보수하기 어려움. 이 서버 사양을 탄력적으로 늘렸다 줄였다 하기 굉장히 힘듦. 그래서 많은 기업들이 현재 온 프레미스 방식을 벗어나서 클라우딩 컴퓨팅 기반의 환경으로 변경하고 있음. 이런 문제들로 인해서 클라우딩 컴퓨팅이 뜬 것.
다만 서버를 물리적인 부분까지 온전히 통제(직접 만지고 관리)할 수 있다는 장점으로 인해서 특정 환경에서는 여전히 온 프레미스 방식을 활용하기도 함.
그래서 클라우딩 컴퓨팅이 그냥 떴다.라고 생각하면 안 됨. 이런 이유들로 인해서 초창기 서버를 운영한 온 프레미스 방식에서 클라우딩 컴퓨팅으로 흐름이 옮겨왔다고 생각하기. 모든 것의 등장엔 다 이유가 있음!
클라우드 컴퓨팅은 컴퓨터를 인터넷을 이용한 클라우드 서비스를 통해서 사용하는 것을 의미함. 클라우드 컴퓨팅은 직접 물리적인 서버를 구매해서 관리할 필요 없이 클라우드 서비스 프로바이더를 통해서 원하는 사양을 원하는 시간만큼 대여해서 사용할 수 있음.
클라우드 서비스 프로바이더는 전세계에 걸쳐 서버를 운영할 수 있는 인프라를 구축 해두고 여기서 물리적인 컴퓨터를 관리하고 있으며 이를 가상화 기술을 통해서 원하는 만큼 분리해서 서비스의 사용자에게 제공할 수 있음.
그리고 클라우드 컴퓨팅의 사용자 입장에서는 물리적인 관리(전력, 화재 상황, 지진, 에어컨 시설)에 대한 필요성이 없어지며, 개별 기업에서 운영하는 것보다 이걸 전문으로 하는 업체에서 관리를 더 잘하니 훨씬 더 안정적인 환경을 제공받을 수 있기에 관리상에 이점이 있음.
또한, 클라우드 컴퓨팅을 사용할 경우 내가 필요한 사양을 필요한 시간만큼만 대여해서 사용 할 수 있기에 비용 측면에서 효율적이며 단순히 클릭 몇 번으로 컴퓨터의 사양 또는 갯수를 늘릴 수 있기 때문에 서비스의 확장 측면에서도 이점을 가지고 있음.
그럼 클라우드 컴퓨팅엔 어떤 종류가 있을까?
클라우드 컴퓨팅은 제공하는 서비스의 수준에 따라서 3개의 계층으로 구분지을 수 있음.
IaaS는 클라우드 컴퓨팅의 가장 기본적인 형태로서, 인프라를 구축하기 위해 필요한 컴퓨터를 대여해주는 것 을 의미함. 컴퓨터를 IaaS는 대여받은 컴퓨터의 대부분의 리소스에 접근해서 서비스를 구성하고 관리할 수 있으므로 가장 많은 제어권 을 가지고 있지만 반대로 가장 많은 부분을 사용자가 일일이 구성하고 관리해줘야 한다는 단점이 있음
대표적인 Iaas 예시
e.g., AWS EC2(=컴퓨터를빌려주는것)
PaaS는 IaaS에 더불어 소프트웨어를 개발하고 운영하기 위해 필요한 구성요소들을 플랫폼화해서 제공 해주는 서비스. PaaS를 사용하면 개발자들은 소프트웨어의 운영에 대한 관리를 PaaS에 위임할 수 있기 때문에 효율적인 개발이 가능함. 다만, 플랫폼의 형태로 제공된다는 점은 그 플랫폼에서 제공하는 기능만 쓸 수 있다는 것임.
그 점으로 인해 옮기기 힘들므로 이런 단점들도 있음.
대표적인 Paas 예시
e.g., AWS Elastic BeanStalk(얘가ec2에플랫폼기능얹어서제공해주는서비스), Heroku, Github Pages
지금까진 주로 개발자들이 많이 사용하는 단계였다면, 이제부터는 일반인이 많이 사용하는 단계임!
SaaS는 클라우드 서비스에 더불어, 고객이 이를 사용할 수 있는 소프트웨어가 함께 제공되는 형태를 의미함. 클라우드 서비스를 통해서 제공받기에 명시적으로 애플리케이션을 PC에 설치할 필요가 없으며, 서비스를 활용하기 위해 만들어진 소프트웨어가 제공되기에 이를 통해 편리하게 여러 기능 등을 제공받고 활용할 수 있는 형태. 내가 개발 하나도 몰라도 편하게 쓸 수 있음.
e.g., DropBox, iCloud, Netflix, Google Apps, Slack
AWS(Amazon Web Service)는 클라우드 컴퓨팅 서비스를 제공하는 프로바이더 중 하나로서, 현재 전 세계에서 가장 많이 사용되고 있는 클라우드 컴퓨팅 서비스임. AWS는 단순 컴퓨팅 자원을 제공해 주는 것뿐만 아니라 이를 편리하게 관리할 수 있는 서비스, 서버리스 서비스 등 수많은 서비스를 확장성, 안정성, 높은 보안 수준과 함께 제공해줌.
흔히 클라우드 컴퓨팅을 처음 배운다고 하면 aws 기준으로 배움.
AWS의 S3서비스는 Simple Storage Service의 약자로, Storage라는 표현 그대로 특정한 파일을 저장하고 인터넷상으로 접근할 수 있게 해주는 서비스임. 보통 서비스에 필요한 이미지나 파일등을 저장해두는 용도 로 사용하지만 정적인 파일들을 안정적이고 빠르게 제공할 수 있다는 점을 이용해서 정적 웹사이트 호스팅 (=배포한다)에도 사용할 수 있음.
➡ 단순히 파일을 올리고 받을 수 있는 저장소 느낌
Create React App을 이용해서 만든 리액트 프로젝트는 정적인 웹사이트라고 볼 수 있음. build 명령어를 실행하면 정적인 build 파일들이 생성되고 이를 브라우저에서 접근해서 실행하면 Client Side Rendering을 통해서 동작하는 특징을 이용해서 S3서비스를 통해서 배포를 할 수 있음.
얘도 규칙을 가진 정책을 설정하는 문법이 있음.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<bucket-name>/*"
}
]
}
==개발자는 사람을 믿으면 안 된다. 개발자는 뭐든지 자동화하거나 컴퓨터를 시켜야 함.==
➡ 자동화
항상 그냥 시작하지 않고 뭔지 알고 해야 함. 그리고 왜가 중요함. 왜 현재 각광받는지에 대해서 그리고 이걸 어떻게 사용하는지 알아보기
CI/CD는 흔히 한 단어처럼 쓰지만 사실 두 개로 나누어져 있음.
Continous Integration은 코드를 지속적으로 통합해나가는 것을 의미함. 일반적으로 코드의 통합은 GItHub의 PR이나 GitLab의 MR을 통해서 진행할 수 있기에 CI 과정에서 도대체 무엇을 하는 거지 의아할 수 있음.
여기서 말하는 코드의 통합은 단순히 코드와 코드를 합치는 것뿐만이 아니라 코드를 테스트하고 유효한지 검사하는 확인을 포함함. 코드를 통합할 때 가장 중요하고 걱정되는 부분은 “머지 후에 제대로 돌아갈까?” 임. 이런 걱정과 의문을 매번 사람이 다 확인하는 것이 아니라 CI 과정에서 테스트를 실행하고 코드가 유효한지 제대로 돌아가는지 검사하고 만약 문제가 발생했을 경우 즉각적으로 피드백을 통해서 유저가 사용하기 전에 개발자가 문제를 확인하고 수정할 수 있게 만들어줌.
일단 CI가 돌아가는지 확인했다면? 그다음엔 배포해야 함. 이 과정을 CD라고 부름
Continuous Deployment는 CI 과정을 통해서 성공적으로 통합된 코드들을 실제 사용자가 사용하고 있는 Production 환경에 배포하는 것을 의미함. CD는 Continous Deployment와 Delivery 두 의미로 모두 사용되는데, Continuous Delivery는 개발 환경의 배포까지 자동화된 것을 의미하며, Continous Deployment는 실제 사용자에게 제공되는 Production 환경까지의 배포를 자동화한 것을 의미함.
이것도 굉장히 복잡함.. 말로는 간단한 흐름이지만 실제로 돌려주는 프로그램을 구축하는 것은 어려움. 그래서 그런 개발, CI, CD, 완료 이런 일련의 과정 흐름을 거쳐가는 것을 파이프라인이라고 하는데 그걸 일일이 구축하는 것은 힘듦.
개발자가 좋은 것은? 남들이 만들어 놓은 거 가져다 쓰는 것! 그런 전용 플랫폼들이 있음.
CI/CD는 일련의 과정을 처리하는 CI/CD 파이프라인을 구축함으로서 자동화함. 개발자들은 이러한 파이프라인을 구축하고 모니터링 하기 위해서 이를 위한 CI/CD 전용 플랫폼을 사용하는데 CI/CD 플랫폼의 종류를 구분하자면 크게 설치형과 클라우드형으로 나눌 수 있음.
CI/CD 파이프라인 또한 일련의 과정을 수행하는 하나의 프로그램이므로 프로그램을 설계해두면 이를 실행할 컴퓨터가 필요함. 설치형은 파이프라인을 구축하는 개발자가 직접 특정 컴퓨터에 CI/CD 플랫폼을 설치해서 활용하는 방법임. 대표적인 설치형 CI/CD 플랫폼으로는 Jenkins가 있음.
반대로 클라우드형같은 경우에는 CI/CD 플랫폼을 운영할 컴퓨터를 개발자가 직접 관리할 필요 없이 서비스 제공자가 클라우드에서 모두 운영해주는 형태. 즉 클라우드형 CI/CD 플랫폼을 이용하면 별도의 컴퓨팅 자원에 대한 관리 없이 CI/CD 파이프라인의 구축에만 신경 쓸 수 있지만, 컴퓨터에 직접 접근할 수 없고 플랫폼에서 제공해주는 수준까지만 할 수 있기에 세부적인 조정이 불가능하다는 단점이 있음. 대표적인 클라우드형 CI/CD 플랫폼의 예시로는 Travis CI, GitHub Actions 등이 있음.
왜 이게 요즘 뜰까? 왜 이걸 많이 사용하고 왜 우리가 이걸 써야 할까 알아야 함. 우리가 편하려고! 이걸 이제 풀어서 설명.
현재에는 어느정도 규모가 있는 개발팀의 경우에는 CI/CD를 구축하는 것이 보편적임. 사실 CI/CD는 장점만 있는 것은 아님. 뭐든지 장단점이 있음. CI/CD를 구축하고 운영하기 위해서는 이를 구축하고 관리하기 위한 노력도 필요하며, CI/CD 플랫폼, 서버를 사용해야하기에 개발자가 직접 배포 과정을 진행하는 것 보다 비용도 많이 든다는 단점이 있음. 이런 점에도 불구하고 왜 어느정도 규모가 있는 개발팀은 다들 CI/CD를 구축하려고 할까? 그 이유는 효율임!
왜 효율이 좋을까?
소프트웨어는 하드웨어에 비해 상대적으로 변경하기가 쉬움. 그리고 기업에서는 항상 유저의 피드백을 통해서 프로덕트를 더 좋은 방향으로, 더 빨리, 더 자주 개선하고자 함.ㅍ이런 상황에서 개발자가 직접 수동으로 배포를 하는 과정에 리소스를 쏟기보다 프로덕트의 개발 및 개선 과정에 더 많은 리소스를 투입하는 것이 퀄리티나 현실적인 비용 측면에서 효율적이라고 판단하였음.
또한, 현재 IT업계에서 개발자의 몸값은 비쌈. 과거에는 하드웨어가 개발자의 몸값에 비해서 상대적으로 비쌌기에 하드웨어를 효율화하기 위해서 개발자들이 노력했다면 현대에는 기술의 발전으로 인해 하드웨어가 상대적으로 싸졌기에 비싼 인력인 개발자의 공수를 더 투입하는 것 보다 하드웨어의 사양을 증대시키거나, 필요한 PaaS 서비스들을 활용해서 개발자들이 핵심 가치를 창출하는 데 집중시키는 방향으로 산업이 발전하고 있음. CI/CD는 이러한 상황에 맞춰서 그 효율이 입증되어서 각광받고 있는 것이라고 할 수 있음.
➡ 깃헙에서 만든 클라우드형 CI/CD 플랫폼
GitHub Actions는 GitHub에서 제공하는 클라우드형 CI/CD 툴. GitHub에서 자체적으로 제공하기에 GitHub 레파지토리와의 연동이 쉽고, 별도의 구축 없이 내 레파지토리 안에서 CI/CD까지 함께 구축하고 관리할 수 있다는 이점으로 인해 현재 많은 인기를 얻고 있음.
➕ 퍼블릭 레포에서 특정 사용량까지 무료라 개인적으로 사용하기 좋음!
use
키워드와 함께 사용할 수 있으며 지금 어떤 브랜친데 마스터 브랜치로 체크아웃하고, 환경을 설정하는 등 복잡하지만 자주 사용되는 과정들을 미리 정의해두고 편리하게 활용할 수 있음.정적 웹사이트들은 S3를 통해서 호스팅 할 수 있음. 하지만 매번 CRA의 dependencies를 설치하고, build script를 실행하고, AWS에 로그인해서 S3 버킷에 들어간뒤에, 기존의 자료들을 삭제하고 새로운 파일들을 업로드하는 것은 꽤나 번거로운 일임. 이제 GitHub Actions를 통해서 아래의 과정을 자동화 시켜보기.
name: CI/CD // 말그대로이름
on: // 언제돌릴건지
push: // 푸시됐을때
branches: // 무슨브랜치에?
- master // 마스터브랜치에(피알도포함)
workflow_dispatch:
jobs: // 잡설정
deploy: // 잡의이름
runs-on: ubuntu-latest // 어디서돌릴건데?
steps:
- run: echo HelloWorld
- uses: actions/checkout@master
- run: npm ci
- run: npm run test
- run: npm run build
- name: deploy to s3
uses: jakejarvis/s3-sync-action@master
with:
args: --delete
env:
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: 'ap-northeast-2'
SOURCE_DIR: 'build'
항상 개발할 때는 모든 단계를 짧게 나누기
내가 CI/CD를 GitHub Actions를 통해서 마스터에 푸시 했을 때 돌아가는지가 보고 싶음. 그게 보통 확인이 돼야지 뭔가를 실행시킬 수 있음. 그러니까 일단 Hello World로 확인하는 것. 그래서 개발에서 헬로월드란 단어가 중요한 것임. 내가 이 모든 환경이 제대로 돌아가는지 확인하는 제일 간단한 방법. 그래서 내가 뭐든지 처음 할 때 찍는 것!
흔히 개발을 처음 하는 입장에서는 “개발"이라고 하면, 그리고 “프론트엔드 개발"이라고 하면 UI와 기능들을 코드로 개발하는 것이 업무의 전체라고 생각하기 쉽습니다. 하지만 개발자가 하는 개발 중에서 기능 개발은 전체 프로세스의 일부분일 뿐임.
현대 IT 팀에서 개발자는 기본적으로 제품의 기획 분석, 기능 개발, 배포 및 운영을 책임져야 하며, 나아가서 제품의 기획단에도 참여해서 개발적으로 어떻게 요구사항들을 풀어나갈 수 있는지, 유저의 피드백을 어떤 방식으로 수용하면 좋을지에 대한 의견도 내곤 함. 이러한 상황에서 기능 개발만이 나의 책임이라고 착각하면 안 됨.
물론, 프론트엔드 개발자는 상대적으로 백엔드, DevOps 개발자에 비해서 배포와 운영에 대한 부분보다는 FE 단의 개발에 업무의 비중이 집중되어 있지만 프론트엔드 개발자에게도 기본적으로 배포를 하고 운영할 수 있는 능력은 요구되며, 나아가 추후 내가 개발한 프로덕트에서 특정한 문제가 생겼을 때 배포가 어떤 개념인지, 어떤 식으로 이루어져있는지를 전혀 모른다면 원활하게 트러블 슈팅을 할 수 없게 됨.
이러한 이유로 프론트엔드 개발자도 배포에 대한 기본적인 지식은 반드시 가지고 있어야 함.