[N331] TIL 및 회고

Sea Panda·2022년 12월 26일
0

부트캠프 TIL

목록 보기
33/46

0. 학습목표

Level 1.

  • Docker가 필요한 이유를 설명할 수 있다.
  • Docker image에 대해 설명할 수 있으며, Whalesay예제를 재현할 수 있다.
  • Docker Container에 파일을 복사하는 예제를 재현할 수 있다.
  • Docker Hub, Docker container, Docker Image 사이의 관계를 알고 설명할 수 있다.

Level 2.

  • Docker Container가 Linux Container기술에서 시작했다는 것을 알고, LXC의 세 종류의 구획화에 대해 설명할 수 있다.
  • Docker Image 이름과 Docker Container 실행 명령어의 구성을 각각 설명할 수 있으며 Docker Container를 실행할 수 있다.
  • Docker Container의 터미널을 활용하여 Container 내의 폴더 구조를 파악할 수 있으며, 로컬 환경과 파일을 주고 받을 수 있다.
  • 포트에 대해서 설명할 수 있으며, Container에서 로컬로 포트 포워딩을 할 수 있다.

Level 3.

  • Docker Docs에서 필요한 명령어와 옵션을 찾아서 실행할 수 있다.
  • Yaml문법을 이해하고, Docker-Compose를 활용하여 여러 개의 Container를 다룰 수 있다.

Level 4.

  • Dockerfile 에 사용되는 문법을 이해하고, 원하는 Docker Image 를 제작 후 배포할 수 있다.
  • Docker network 를 활용하여 여려 개의 Container 를 연결하고 활용할 수 있다.
  • Docker 와 Linux Container 사이의 관계를 설명할 수 있다.
  • Kubernetes 와 컨테이너 표준 사이의 관계를 설명할 수 있다.
  • 가상 머신에 대해서 이해하고, Docker 와 가상 머신을 비교하여 설명할 수 있다.

1. 주요개념

Docker(도커)?

“Docker takes away repetitive, mundane configuration tasks and is used throughout the development lifecycle for fast, easy and portable application development.”

일반적으로 Server(서버)를 관리한다는 것은 복잡하고 어려우며 고급 개발자들의 섬세한 작업이 필요한 영역이다.

개발을 하면서 시간이 흐르다보면 서버 환경이 계속 바뀐다. CentOS에 익숙해지면 Ubuntu를 써야할 일이 생긴다거나 하는 일이 생긴다.(둘 다 Linux운영체제의 여러 버전) 게다가 최근 DevOps의 등장으로 개발주기가 짧아지면서 배포는 더 자주 이루어지고 마이크로 서비스 아키텍쳐가 유행하면서 프로그램은 더 잘게 쪼개어져 관리는 더 복잡해진다.

그리고 리소스 격리성에 대해서 이해하기 위해 IP와 Port Number에 대해 잠깐 이야기 해보겠다. IP주소는 인터넷상에 있는 컴퓨터의 고유 주소로, 인터넷상의 한 컴퓨터에서 다른 컴퓨터로 데이터를 주고받을 수 있게 해준다. Port number는 IP주소와 함께 쓰여 해당하는 프로토콜에 의해 사용된다. 비유하자면, 우리가 물건을 어떤 사람의 방까지 전달해준다고 하자. IP 주소는 단지 집 주소까지, Port Number는 방 주소까지라고 생각하면 된다. 이제 본격적으로 서버 관리자들에게 다음과 같은 요구가 들어온다고 가정해보자.

  • 웹서버 1은 IP는 A로 하고 포트 번호는 A-1로 하고, 방화벽 규칙은 a의 규칙을 이용하라.
  • 웹서버 2는 IP는 B로 하고 포트 번호는 B-1로 하고, 방화벽 규칙은 b의 규칙을 이용하라.

이런 두가지 요구에 대해서 서버가 하나빡에 없어서 IP주소를 구분하기 위해 브릿지 설정(뭔지 모르겠다...)을 변경해야 하고, 방화벽 규칙 a와 b가 서로 충돌이 일어날 것이다.

이러한 문제를 해결하고자, 하나의 컴퓨터에서 여러 개의 컴퓨터를 이용하는 것처럼 하기 위해서 "리소스 격리성"을 이용한다. 그리고 이런 리소스 격리성을 제공하는 기술로 VM( virtual machine)과 바로 이번에 배우는 Docker가 있다. 두 방법 모두 격리성을 제공하기 때문에 각 애플리케이션마다 다른 컴퓨터에서 실행되는 것처럼 IP, Port 등을 다르게 설정할 수 있다.

👉 Docker(좌측), Virtual Machine(우측)

  • 도커는 Virtual Machine만큼 견고한 격리성을 제공하지 않는다.
  • 도커는 리눅스의 컨테이너를 이용한 기술로, OS 위에 다른 OS를 실행하는 것이 아니기 때문에 Virtual Machine보다 좋은 성능을 낼 수 없다.

👉 Virtual Machine(가상머신)이란?
Docker가 등장하기 전, 프로그래머들은 OS(Operation System)를 가상화하여 사용하는 방식을 사용했다. 구체적인 예를 들어 OS의 가상화가 무엇인지 설명해보겠다.

A는 지금까지 Windows가 설치 된 개노트북에서 개발을 해 왔다. 그런데 A는 이번에 눈여겨보고 있던 최신 애플 노트북을 새로 사게 되었다. 지금까지 Windows에 사용한 프로그램들을 다시 MAC컴퓨터에서 다시 설치하려고 한다.

여기서 문제가 발생한다. Windows에서 설치한 프로그램들이 IOS와 호환되지 않는 것들이 매우 많다는 것이다. 이미 설정해둔 설정값이나 자료들 역시 새로운 노트북에서 다시 설정하기 매우 힘이 드는 작업이다.

이러한 문제를 해결하기 위해 새로 구매한 Mac컴퓨터 안에 원래 사용하고 있던 Windows환경을 설치하기로 했다. 이것이 바로 OS의 가상화이다.

위 그림은 또 다른 OS를 설치하는 과정을 그림으로 나타낸 것이다.

  • Window내에서 VMware를 설치한다.
  • VMware를 사용하여 hypervisor를 설치한다.
  • hypervisor를 통해 Guest OS로 접근한다.
  • Guset OS 안에서 개발을 진행한다.

    우리는 원래 사용하는 OS를 Host OS,즉 주인 운영체제라고 부른다. 그리고 설치한 새로운 OS를 Guest OS, 즉 손님 운영체제라고 부른다. 컴푸터를 2대를 따로 사는 것 대신에, 하나의 하드웨어에서 2개의 운영체제를 가지고 있는 것이다.

    짧게 정리하자면, 하나의 하드웨어 안에서 또 다른 OS를 만드는 것을 Virtual Machine(가상머신)이라고 한다.

    이런 가상머신은 하나의 하드웨어에서 두 가지의 OS를 사용할 수 있다는 장점 덕분에 많은 인기를 누렸다. 하지만 단점도 존재했다. 가상머신은 하나의 하드웨어가 또 다른 OS를 유지하기 위해서 엄청나게 많은 자원(Resource)이 사용된다. 또, 하드웨어를 나눠써야 하는 점 때문에 효율성이 떨어지고 실행 속도도 느리다는 단점이 있다.

👉 Docker의 장점

  • 인프라를 편하게 가져올 수 있다.
    인프라를 이미지로 만들었기 때문에 저장된 이미지들만 관리한다.
    중앙 보관소에 있는 이미지를 가져와서 체계적인 관리와 테스트를 할 수 있다.
  • 용량이 가볍고 빠르다.
    OS와 컨테이너 환경을 분리하여 가볍고 어디서든 실행 가능하게 만들어 준다.
  • 쉽게 삭제하고 복수할 수 있다.
    이미지를 사용하여 개발환경을 동시에 여러개 만들 수 있고 수정/배포가 간단하므로 테스트가 매우 쉽다.

Docker를 짧게 정의하자면, 애플리케이션 실행 환경을 코드로 작성할 수 있고 OS를 격리화하여 관리하는 기술,또는 그런 기술을 제공하는 컨테이너 기반의 오픈소스 가상화 플랫폼을 의미한다. 그리고 이 Docker는 Linux Container라는 기술에서 시작되었다.

따라서 이번 섹션에서는 Docker의 사용방법을 상세히 다루기 이전에 Linux Container기술에 대해서 학습한 후, Docker의 사용 방법등에 대해서 다룬다.

Linux Container

리눅스 기반의 기술 중에 하나로 필요한 라이브러리와 어플리케이션을 모아서 마치 별도의 서버처럼 구성한 것을 말한다. 컨테이너를 이루는 네트워크 설정, 환경 변수 등의 시스템 자원은 각 컨테이너가 독립적으로 소유하고 있다.

1. 프로세스의 구획화

  • 특정 컨테이너에서 작동하는 프로세스는 기본적으로 그 컨테이너 안에서만 액세스 할 수 있다.
  • 컨테이너 안에서 실행되는 프로세스는 다른 컨테이너의 프로세스에게 영향을 줄 수 없다.

2. 네트워크의 구획화

  • 기본으로 컨테이너 하나에 IP주소가 할당되어 있다.

3. 파일시스템의 구획화

  • 컨테이너 안에서 사용되는 파일 시스템은 구획화되어 있다. 그렇기 때문에 해당 컨테이너에서의 명령이나 파일 등의 액세스를 제한할 수 있다.

가상머신과 얼핏보면 동일해 보이지만 비슷할 뿐 가상머신(가상화)와는 다른 기술이다.

  • Container아키텍쳐

  • VM아키텍쳐

  • 두 개의 차이 정리

조금 더 상세히 설명하자면 기존 가상화 방식은 주로 OS를 가상화 했다. 위의 예시에서 등장한 VMware같은 VM은 호스트 OS위에 게스트 OS 전체를 가상화하여 사용하는 방식이다. 이 방식은 비교적 사용법이 간단하지만 무겁고 느려서 운영환경에선 사용할 수 없다.(Docker 컨테이너는 보통 MB단위 크기지만, VM은 GB크기를 가진다고 한다.) 이런 상황을 개선하기 위해서 반가상화 방식의 Xen이 등장한다.

하지만 전가상화든 반가상화든 추가적인 OS를 설치하여 가상화하는 방법은 어쨋든 성능 문제가 있었고 이를 개선하기 위해 프로세스를 격리하는 방식이 등장한다. 그리고 이런 프로세스를 격리하는 방식을 리눅스에서 리눅스 컨테이너라고 한다. 단순히 프로세스를 격리시키기 때문에 가볍고 빠르게 동작하게 되는 것이다. CPU나 메모리는 딱 프로세스가 필요한 만큼만 추가로 사용하고 성능적으로도 거의 손실이 없다.

Docker Container

리눅스 컨테이너는 리눅스에서 프로세스를 격리하는 방식이라고 했다. Docker Conatainer는 Docker에서 이런 프로세스를 격리하는 방식이다.

도커는 Container라는 물체를 운반한다. 컨테이너는 인프라를 비롯한 프로그램을 어떤 환경에서나 실행 가능 할 수 있도록 해주는 개체를 의미한다.

프로그램을 만들기 위해서는 다양한 인프로가 필요한데, 도커는 이 인프라들을 각각의 장소에서 하나씩 가져오는 것이 아니라, Container라는 보관함에 담아서 한 장소에서 가져오는 것이다.

예를 들자면 쿠팡이나 지마켓과 같은 쇼핑몰 웹사이트를 만들기 위해서는 FE,BE, DB 등과 같은 구성요소들이 필요하다. 이때, 구성요소들을 모두 Docker Container형태로 가져오면, 각기 다른 장소에서 설치하는 시간을 줄일 수 있다.

Docker 사용하기

도커를 이용하는 데 있어서 명령어, 옵션 등 사용법은 Docker Docs에서 확인할 수 있다. Docker CLI뿐만 아니라 사용법과 환경을 구성하는 방법에 대해서 설명되어 있다.

Docker Image

본격적으로 도커를 사용하기 앞서 Docker Image라는 개념을 이해해야 한다. Image는 컨테이너와 함께 도커를 사용하는데 있어서 가장 중요한 개념이다.

이미지는 컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있는 것으로 상태 값을 가지지 않고 변하지 않는다.(Immutable). 컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장된다. 같은 이미지에서 여러개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있다.

말 그대로 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 더 이상 의존성 파일을 컴파일 하고 이것저것 설치할 필요가 없다. 이제 새로운 서버가 추가되면 미리 만들어 둔 이미지를 다운받고 컨테이너를 생성만 하면 된다. 한 서버에 여러 개의 컨테이너를 실행할 수 있고, 수십, 수백, 수천 대의 서버도 문제없다.

도커 이미지는 Docker Hub에 등록하거나 Docker Registry 저장소를 직접 만들어 관리할 수 있다.

Docker Image 예제

docker/whalesay라는 이미지를 통해 예제를 실습해보겠다.

Docker Image의 이름은 레지스트리 계정, 레포지토리 이름, 태그 세 가지 정보로 구성되어 있다.

  • 레지스트리(Registry)

    • 도커 이미지가 관리되는 공간을 의미한다.
    • 특별히 다른 것을 지정하지 않는다면 도커 허브(Docker Hub)를 기본 레지스트리로 설정한다.
      -레지스트리는 Docker Hub, Private Docker Hub, 회사 내부용 레지스트리 등으로 나뉠 수 있다.
  • 레포지토리(Repository)

    • 레지스트리 내에 도커 이미지가 저장되는 공간이다.
    • 이미지 이름이 사용되기도 한다.
    • Github의 레포지토리와 비슷한 개념이다.
  • 태크(Tag)

    • 같은 이미지라고 할지라도 버전 별로 안의 내용이 조금 다를 수 있다.
    • 해당 이미지를 설명하는 버전 정보를 주로 입력한다.
    • 특별히 다른 것을 지정하지 않는다면 latest태그를 붙인 이미지를 가져온다.

자 그럼 다시 docker/whalesay라는 문장을 다시 읽어보면 다음과 같은 뜻을 가진 것을 알 수 있다.

👉 Docker Hub라는 레지스트리에서 docker라는 계정이 등록한 whalesay레포지토리에서 lastest태크를 가진 이미지

👆 실제 docker/whalesay

이제 실제 이미지를 가져와서 실행까지 진행해보자.

먼저 다음 명령어를 통해서 레지스트리에서 이미지 혹은 레포지토리를 가져온다. 이 과정을 Pull이라고 한다.

$ docker image pull docker/whalesay:latest

docker image pull만 아니라 docker pull을 사용하여 검색해도 많은 정보를 찾을 수 있다고 한다.

다음 명령어로는 이미지 리스트를 출력해 볼 수 있다.

$ docker image ls

받아온 이미지를 실행시켜 보자.(이미지 -> 컨테이너)

$ docker container run --name myName docker/whalesay:latest cowsay boo

각각의 명령에 대해서 간단히 정리하면 다음과 같다.

  • {container} run
    • 컨테이너를 실행한다.
  • option:
    • --name: 컨테이너의 이름을 할당한다.
  • COMMAND:
    • cowsay: 컨테이너에서 cowsay를 호출한다.
  • ARG..:
    • boo: COMMAND인 cowsay에 넘겨질 파라미터이다.

다음 명령어를 이용하면 종료된 컨테이너를 포함하여 모든 컨테이너를 볼 수 있다.

$ docker container ps -a
  • {container} ps: 컨테이너의 리스트를 출력한다.
  • -a: Default로는 실행되는 컨테이너지만 종료된 컨테이너를 포함하여 모든 컨테이너를 출력한다.

그리고 만일 컨테이너를 삭제하고 싶다면 다음과 같은 명령어로 삭제할 수 있다.

$ docker container rm myName
  • {container} rm: 컨테이너를 지칭해서 삭제한다. 컨테이너를 명시할 때는 ps명령을 통해 확인할 수 있는 NAMES 혹은 CONTAINER ID를 사용한다.

이미지는 다음과 같이 지우면 된다.

$ docker image rm docker/whalesay

위와 같이 각 과정을 따로 진행할 수 있지만 이미지를 받아오고, 컨테이너로 실행하고, 컨테이너와 관련된 리소스를 지우는 작업을 한 번에 실행할 수도 있다.

$ docker container run --name my_name --rm docker/whalesay cowsay boo
  • {container} run: 컨테이너를 실행한다. 이미지가 없다면 이미지를 받아온 뒤(pull) 실행한다.
  • --rm: 컨테이너를 일회성으로 실행한다. 컨테이너가 종료될 때 컨테이너와 관련된 리소스를 모두 제거한다.
    이미지까지 완벽하게 제거하려면
$ docker image rm docker/whalesay

까지 실행하면 된다.

도커는 같은 기능을 수행하더라도 여러 명령으로 실행될 수 있다. 아직 docker 측에서 특정 구문만 이용하라는 말이 없다. 그래서 웹서핑을 하면서 같은 기능을 하더라도 다른 docker 구문으로 구성되어 있는 경우를 잘 파악할 수 있어야 한다.

하나의 예시로 image rmrmi는 같은 기능을 수행한다.




참고자료
1. 초보자를 위한 도커 안내서
2. 코드스테이츠 N331 Lecture Note

0개의 댓글