상세 컨텐츠

본문 제목

🐳 Docker 시작해보기 :: #1 기본개념 🖥️

프로그래밍/서버관련

by 진:D 2019.10.16 22:35

본문

 

현재 웹 프론트엔드 개발을 하고 있고, 이 전에는 여러 플랫폼을 얕게 개발을 진행했었습니다. 그러다보니 특정 분야를 깊게 알고 있는 것보다는 전체적인 흐름과 큰 그림을 보는 것이 익숙해지기도 했죠.

 

이로 인해 저 스스로 어떤 프로그램이 필요하거나 서비스가 필요할 경우 제가 사용할 정도는 스스로 만들게 되는 상황도 생기게 되었습니다. (이게 장점인지, 단점인지..)

 

무언가를 만들게 되면 자연스럽게 서버환경을 세팅하고, 배포하는게 익숙해지면서 AWS의 EC2에 들어가서 작업하는게 크게 불편하다라는 것을 못느꼈습니다.

또한 이게 반복적인 작업이다보니, 제가 이미 경험한 환경대로 세팅하게 되었고, 회사업무가 아닌 개인적으로 작업할 때는 트래픽을 크게 신경 안써도 되니 스케일링 관련도 걱정할 일이 없었습니다.

 

그런데 지금 현재. 이렇게 혼자 다하게 되고, 오히려 이 상황이 익숙한 상황 때문인지 저 스스로 혼란이 찾아오게 되었고, 지금은 그 혼란에 벗어나 어떠한 혼란을 겪었는지, 그리고 저와 같이 혼란을 겪고 있을지도 모르는 분을 위해 포스팅을 남겨봅니다.

 

Docker? 도커?

네. 도커에 관한 이야기를 해보려고 합니다. 오히려 저 같은 사람에게는 도커가 정말 필요한 사람일지도 모릅니다. 그런데 안쓰고 있었고, 굳이 사용해야할까? 라는 생각을 갖고 있었습니다.

 

아, 먼저 도커에 관한 설명부터 해드릴게요.

 

  • 도커(Docker)는 리눅스의 응용 프로그램들을 소프트웨어 컨테이너 안에 배치시키는 일을 자동화하는 오픈 소스 프로젝트입니다. 도커 웹 페이지의 기능을 인용하면 다음과 같습니다.
  • 도커 컨테이너는 일종의 소프트웨어를 소프트웨어의 실행에 필요한 모든 것을 포함하는 완전한 파일 시스템 안에 감싸게 됩니다. 여기에는 코드, 런타임, 시스템 도구, 시스템 라이브러리 등 서버에 설치되는 무엇이든 아우르며, 이는 실행 중인 환경에 관계 없이 언제나 동일하게 실행될 것을 보증합니다.

라고 위키백과에서 가져왔는데 더 간략하게 설명드리게 되면 한번 세팅해놓으면 언제 어디에서든지 서버가 다른 것으로 바뀌더라도 같은 서버환경을 유지하여 컨테이너에 담아 서비스를 운영할 수 있도록 해주는 소프트웨어 입니다.

 

혹시나 환경설치하다가 충돌나서 처음에는 잘 동작하다가 두번째 서버를 다시 만드니 안되는 상황들. 그러한 경우를 전혀 고민할 필요가 없다는 것입니다.

 

Docker를 통한 개발 → 배포/업데이트 흐름

자, nodejs로 일반적인 서버를 개발하고, SPA형식의 웹사이트를 만들어서 HTTP를 통해 접속하게 하려고 한다면 어떻게할까요? 거기에 중간중간 소스코드도 수정하면서 반영을 해야한다라고 했을 때 말이죠.

 

가장 간단하게 생각해볼 수 있는 것은 Linux로 된 서버PC를 준비합니다. 저는 AWS를 사용하니 EC2를 이용하여 서버 인스턴스를 생성합니다. 그리고 웹서버를 운영하기 위해 nginx (or apache) 를 설치합니다. nodejs를 돌릴 것이니 node도 설치해야겠죠? 열심히 설치를 합니다.

 

그 다음은 git을 통해 node 프로그램을 clone받고, 배포를 합니다. 그냥 백그라운드로 돌리기에는 관리하기가 힘드니 노드 프로세스를 관리할 수 있는 프로그램을 설치합니다. 보통 forever나 pm2를 이용하는데 저는 개인적으로 pm2를 좋아해서 pm2를 사용합니다.

그리고 node프로그램을 pm2에 올리고 nginx를 통해 외부에서 접속한 트래픽을 node프로그램으로 전송할 수 있도록 추가적인 설정을 합니다.

 

그 다음은 EC2에 SSL작업하는 겸 ELB도 세팅하고, Route53까지 또로로로록 (TMI)

작업이 많은 것 같은데, 이게 한 번 익숙해지면 세팅하는데 솔직히 오래 안걸립니다. 실수도 거의 없죠.

 

중간에 코드 업데이트를 한다고 하면 소스코드를 git pull 을 통해 최신 소스코드로 갱신하고 pm2 재시작으로 통해 서버프로그램을 재가동합니다.

 

자, 크게 어렵지 않죠?

 

그런데 이 상황에서 Docker를 쓴다라고 했을 때, 무의식적으로 기존방식과 비교를 하게 되고 "이 부분은 어떻게 되는거지? 그럼 이부분은? 이래도 되나?" 가 떠오르게 됩니다.

 

제가 의문을 가졌던 부분을 예를 들어 설명드리겠습니다.

 

  1. Dockerfile 이란걸 만들었는데, docker build, docker run 하고 나니 서버가 돌아가네? Dockerfile을 그냥 서버에 올려서 위 명령어를 서버에서 입력하는건가?
    Dockerfile은 환경설정으로 보면 되지 않을까? 라고 생각됩니다. 실제 배포할 수 있는 Image를 만들기 위해 Dockerfile에 Image를 어떻게 만들지 명령어들을 미리 작성해놓습니다.
    위에서 하나하나 설치했던 그런작업들이죠 (그런데 여기에서 좋은 점이 예를 들어 node설치까지는 Docker Image로 만들어져 있는게 있어서 그 위에서 파일들만 복사하는 명령어정도만 작성하면 된다는게 큰 장점입니다)

  2. 왜 다 예제들이 DockerHub 땡겨쓰는 예제만 있지? Public말고, Private으로는 안되나?
    DockerHub는 일종의 GitHub같은 곳이라고 생각하면 되는데, 배포가능한 (실제 어느정도 사용/운영할 수 있는) 저장소라고 보시면 될 것 같습니다.
    Private같은 경우는 직접 파일(Image)로 들고 있거나 배포할 때는 Image파일을 서버 저장공간에 올려둘 수 있는 방법이 있습니다. 혹은 AWS ECR이라는 곳에 비공개로 도커 Image파일들을 저장해놓을 수 있습니다.

  3. Docker는 pm2같은 프로세스 매니징은 어떻게 하는거지? 어라? Docker로 그냥 하는거라고?
    Docker를 설치하면 Docker자체가 프로세스들을 관리해줍니다. docker ps 로 실제 운영되는 컨테이너를 확인할 수 있고, docker container list 를 통해 docker container 목록들을 확인할 수 있습니다.
    여기에서 Docker Container에 들어가 로그들을 구경할 수 있으며 일반적으로 개발목적이 아니라 운영을 한다고 하면 daemon으로 실행할 수 있습니다.

  4. 소스변경시 업데이트는 어떻게 하지? Docker 안에 들어가서 git pull이라도 해야하나?
    소스변경시 기존 만들었던 Image에 들어가서 git pull or 소스코드 복사. 이런걸 하는게 아니라 Docker Image를 새로 만듭니다. 이런 작업들을 개발하고 있는 로컬에서 작업하거나 CI같은 서비스들 Jenkins, Travis, 요즘은 Github Actions등을 통해 자동으로 Image를 만들 수 있도록 합니다.
    그런다음 기존 Image를 운영에서 정지시키고, 새로운 Image를 실행하는 것이죠. 이게 업데이트 입니다.

  5. 4번 이해하고 나서, 업데이트하려면 Docker를 멈춰야하네? 이러면 의외로 서비스가 멈춰있는 시간이 긴거 아닌가? 뭐야 git pull && pm2 restart service-name 이게 더 빠른거 아닌가?
    네. 운영에서 정지시키니, 정지되는 동안 서비스 멈춥니다. 새로운 Container Image가 붙기 전까지요. 이게 맞다고 하더라구요. 이 부분 머리속으로 이해가 안되었습니다.
    기존 예전 방식보다는 뭔가 무중단으로 되고, 이래야하는거 아닌가? 라고 생각했었는데, Docker가 바라는 방향은 무중단 이런 것 보다는 운영 환경의 통일이 목적이였던 것이였습니다.
    만약 무중단으로 하기 위해서는 여러가지 방법들이 있습니다. Container들 앞에 로드밸런서를 두어 업데이트(종료 후 시작)하는 동안 다른 Container들이 일을 할 수 있도록 하여 교대로 교체하는 방식이 있거나, 이를 완전 자동화하고 관리할 수 있도록 하는 쿠버네티스라는 신기한 친구들이 있습니다. (이런쪽이 거의 끝판왕인가봐요)

  6. 개발환경에서 Docker 프로그램이 설치되고 GUI로 뭔가 있는데, 이게 도커인가? 도커 접속 프로그램인가? 도커 뭐하는 프로그램이지?
    이 것도 머리로 이해가 안되서 충격이였습니다. 뭔가 가상화를 하고, 서버환경을 세팅하고 여러가지 의존성 모듈들도 관리되고 하다보니 당연히 명령어를 통해 설치되고 bash같은 환경에서 관리할 줄 알았습니다. 혹은 뒤에서 서비스만 돌고 있을 줄... 그런데 윈도우, 맥 환경에서 GUI로 설치되면 실제로 뒤에서 도커 서비스가 돌아가고 있었습니다.
    이거 자체가 이미 서버컴퓨터로 바뀌어버린거죠. 대신 리눅스같은 GUI환경이 없을 때는 커맨드라인으로 설치를 하고, docker build, run 같은 명령어로 관리를 하는고죠. 그래서 도커 사이트에서 뭔가 GUI같은 프로그램을 설치했다면 이미 실제 서버를 운영할 수 있는 도커가 준비되었다고 스스로 받아들이시면 될 것 같습니다.

  7. Docker 명령어 왜 이렇게 어렵지? (사람들은 이거 다 외우나..?)
    사실 리눅스 명령어가 더 어려울 수 있을 것 같네요. 도움말도 친절하지 않으니.. 터미널에서 docker -help 를 치면 명령어가 아주 잘 설명되어 출력됩니다. 그리고 의외로 몇 개 사용안하니, 너무 걱정마시고 일단 Docker를 많이 사용해보세요.
    그리고 Dockerfile. 이 것도 자주 사용하는 것만 사용하게 되고, 잘 모르는게 있다면 Docker 공식 홈페이지를 방문해서 문서를 본다면 하나씩 해결해나갈 수 있고, 이게 어렵다면 미리 시도해본 블로그 글 들을 찾는 것을 추천드립니다.

 

해보고나니?

알 것 같으면서도 뭔가 와닿지 않는 이 느낌.. 익숙해져야하는 단계가 필요해보였습니다.

다른 플랫폼이나 개발방식에서는 바뀌어가는 생태계에 나름 익숙하게 적응해갔는데 운영쪽은 아직은 보수적인 성향으로 인해 의심만 많아져가는 듯 합니다.

 

이게 기본적으로 리눅스에 서비스를 올리는 세팅들을 과거부터 해왔던 탓이지 않을까라 생각을 해봅니다.

 

클라우드가 없기 전부터 직접 세팅하는 일이 많았기에 생략되는 작업들이 있으면 스스로 머리속에서 혼란이 찾아오면서 진행하다가 막혀버립니다. 그래도 분명 좋기는 좋은 것 같습니다. 이 전에 직접 세팅하면서 엄청 많이 고생하기는 했었으니깐요 T_T

 

특히 아무것도 모르는 상태에서 시작하면 정말 좋은게 Docker이지 않을까라고 생각됩니다. 이러한 작업들을 그대로 머리속에 학습할 수 있기 때문이라고 생각됩니다.

 

거기에다가 과거에 스케일아웃을 꿈도 못꿨다면, 요즘은 기본장착 아이템같은 느낌이라 정말 세상이 좋아졌다라는 생각이 들기도 하고, 만약 이러한 시스템을 갑자기 사용하지 못하게 되면 이 세상에 큰 혼란이 올 수도 있겠다라는 걱정도 들었습니다.

 

다음 시간에는 가장 많이 사용하는 서버프로그램 구성으로 Docker파일을 구성해보면서 실습하는 과정을 블로그 포스팅에 정리해보려고 합니다.

 

두서없이 긴 글 읽어주셔서 감사드립니다. 제가 잘 이해하지 못해 시작시기를 늦췄던 내용들이 누군가에게 도움이 되었으면 좋겠습니다.

 

감사합니다.

 

제가 이해한대로 포스팅을 작성했지만 잘못 이해하고 있는 내용이 있을 수도 있습니다. 그런경우 댓글로 알려주시면 해당내용 정정하도록 하겠습니다 : )

관련글 더보기

댓글 영역