본문 바로가기

카테고리 없음

9-12:도커:

728x90

+full,para 등 가상머신 작동원리(10강), 9강,

가상화

- 하드웨어에 종속된 컴퓨터 리소스를 추상화함

NIC : Network Interface Card의 약자

NIC(CPU, Memory, Disk 같은) 하드웨어 자원들을 추상화한다.

 

운영체제에서 제공하는 가상화

- 각각의 프로그램이 각자의 CPU, 큰 Virtual Memory를 가지고 이있는 것처럼 착각하도록 가상화를 제공

프로세스단위 - cpu 스케줄링통해 순서대로 진행된다. -> 하나 코어 밖에 없는 애도 여러개 인냥 time sharing할 수 있다.

 

virtual memory: paging을 통해 on demand로 운영체제가 할당을 해준다.

swapping을 통해서 디스크에다가 swap out을 해서 페이지 저장했다가, 필요할 때 다시 이 페이지를 읽어오는, -> 많은 메모리가 있는 것으로 착각하게 만듦.

 

운영 체제 위, 혹은 아래에 하나의 추상화 계층을 더할 수 있다. 

물리적인 리소스를 가상의 리소스로 만드는 것

aggregation - 사양이 부족한 서버를 여러 대 합쳐서 하나처럼 사용

sharing - 하나의 강력한 서버를 여러 대처럼 나눠 사용하는 것

emulation - 특정한 벤더의 서버였는데 상관없는 다른 서버로 만들 수 있음 (Intel -> mac os 처럼 가상화)

Isolation - 새로운 별도의 자원을 만들어 내는 것. 하나의 서버 내에서 나눠서 사용하는데 각자 따로 움직일 수 있음

 

 

scale-up : 서버의 스팩을 업그레이드 (CPU, memory 등 중 문제인 부분을 추가적으로 스팩을 업그레이드 하는 것)

하지만 이 부분은 물리적인 한계가 존재함, 어느 수준 이상으로 scale-up x, 파워와 열의 한계 때문 -> core를 늘리는 방식으로 변화 중

 

scale-out: 서버의 개수를 늘리는 방법, 서버의 자원들을 하나로 통합하여 사용. 분한 컴퓨팅에서 많이 이뤄지는 방식

모든 문제를 해결하지 못할 수도 있다. 실제 실행되는 작업들을 결국 하나의 서버 위에서 실행된다. 그렇기 때문에 병렬화가 굉장히 중요하다.

병렬화가 불가는한 것을 이 scale-out이 불가능 하다.

 

인터페이스와 가상머신

중요 인터페이스

API: 소스코드 - 응용, 라이브러리 사이 인터페이스

ABI: 바이너리 ex. system call, 어플리케이션, 운영체제 사이 인터페이스

Hardware-Software Interface

 - intruction set architecture (ISA), 하드웨어, 소프트웨어 사이 인터페이스

 - 하드웨어에서 지원하는 명령어 셋

 

가상머신, VM

host 머신(물리적 서버) 위에서 guest 인터페이스들을 에뮬레이션

- language view

api

ex. java

- process view

abi

ex. runtime

- operating system view

isa

ex. virtual machine monitor (VMM)

 


컨테이너

virtual machine의 문제점과 이를 해결하기 위해 나온 container

vm vs. container

그리고 이 container 관련 기술 소개

 

docker 소개

 

가상 머신 사용 문제점

- 성능 문제, 성능 오버헤드

 

가상 머신 종류

우선 베어 메탈이 있고, 얘는 하드웨어, host os, libs, application 층으로 존재

그리고 이 베어메탈 사이에  host os 를 빼고 하이퍼 바이저와 게스트 os를 추가한 것이 type 1 인 bare metal hypervisor 이다.

그리고 type 2 인 hosted hypervisor은 host os 위에 하이퍼 바이저와 게스트 Os 를 추가한 것이다. 

그래서 정리해보면

 

베어 메탈: 하드웨어 -> host os -> bins -> application

type 1(베어메탈 하이퍼바이저): 하드웨어 -> 하이퍼바이저 -> 게스트 os -> bins -> application

type 2(hosted hypervisor): 하드웨어 -> host os -> 하이퍼바이저 -> 게스트 os -> bins -> application

 

위와 같이 레이어들을 거칠 수록 성능이 떨어질 수밖에 없다. 추가적으로 해야할 일들이 생기기 때문에 오버헤드가 발생할 수 밖에 없다.

운영체제 위에서 바로 실행 시키는 것과 달리 항상 하이퍼 바이저를 갔다가 다시 왔다 갔다를 해야한다. 그래서 성능적으로 오버헤드가 필연적으로 발생할 수 있다.

- 자원 낭비

게스트 Os를 추가적으로 실행시키는 것은 각각 하드웨어 자원을 필요로 한다. 

그래서 가상머신을 만들어 사용해보면 해당 자원들을 설정하는데, 이때 많은 양의 자원들을 사용하게 되면 결국엔 게스트os를 실행시키기 위한 최소한의 메모리를 필요로 하는데, 다 돌리기 위해서는 자원낭비가 심하다.

운영체제에 필요한 메모리, 라이브러리 공유 등을 생각해보면, 따로 따로 존재하기 때문에 자원낭비가 생긴다.

- 이미지 크기

가상머신 내용이 저장되는 이미지 파일이 생성된다. 가상머신 이미지를 저장되는 모든 데이터 등은 이 파일안에 저장된다. 그러나 이 이미지의 사이즈는 굉장히 크다. 왜나면 Os를 따로 저장하는 디스크를 포함하여 이미지를 만들고 그런식으로 이뤄지때문에 이미지의 크기는 클 수 밖에 없다. 그렇기 때문에 vm migration이 느릴 수 밖에 없다. 이런 거대한 이미지 사이즈도 문제가 된다. 이것은 네트워크를 통해서 복사를 해야하니 이러한 문제가 있다.

- 시작시간 느림

재부팅을 하는데 걸리는 시간

가상머신 사용하면 생성후 실행하면 부팅을 해야한다. cpu memory 등이 다가상화 되어 있는 하드웨어 가상화를 했기 때문에. 이를 부팅을해서 가상의하드웨어를 사용할 수 있도록 세팅이되어야 한다.

마이그레이션 시에도 옮긴후 다시 실행을 시켜야만 위에 응용프로그램들을 실행할 수 있다.

 

이런 부분들을 해결하기 위해 나온 것이 container 이다.

- 운영체제 수준의 가상화

- 빠른 속도

- 높은 효율성

- 높은 이식성

베어메탈과 비교해보면 호스트 오에스를 가지고 그 위에서 레이어를 만들어서 그 위에서 어플레케이션, 라이브러리들을 실행시키는데 이는 

기존에 있는 type1과 type2에 비해 얇다..?

 

- 운영체제 수준의 가상화

os 커널에서 제공하는 기능을 제공하는데, os 기능을 사용해서 기능들을 격리(isolation)을 시킨다.

커널차원 기능을 제공해서 여러개 운영체제 제공하는 것처럼 어플리케이션에 제공한다. 그래서 게스트 os를 따로 필요로 하지 않는다.

각각의 게스트os가 올라가고 그 위에 라이브러리와 어플리케이션이 올라가는 vm버전은 완전히 독립적이어서 분리된다.

그러나 컨테이너 같은 경우 호스트 os가 기능을 제공하고 이 기능들을 활용해서 컨테이너 메니져가 분리되서 실행될 수 있게 기능을 제공한다.

 

- 빠른 속도

레이어가 짧다. 기본적으로 컨테이너가 vm보다 빠르다.

하드웨어 가상화(하이퍼바져)가 필요 없어서 오버헤드가 발생하지 않음

사이에 있는 레이어가 라이트 웨이트하다.

불필요한 것들 거둬내고 필요한 것만 남겨두었다.

그래서그냥 베어메탈에서 실행하는 것과 성능 차이가 거의 없다.

 

- 높은 효율성

게스트 Os를 위해 추가적인 자원이 필요한 vm과 다르게 따로 자원이 필요 없고 예약할 필요가 없다.

가상머신에 메모리 할당을 예약해서 사용해야하는 vm과 다르게 이를 따로 예약하지 않고 사용할 수 있다.

메모리 자체도 추가적으로 많이 필요한 vm과 다르게 컨테이너는 결국에 추가적으로 필요한 메모리는 없다고 봐도 된다.

컨테이너는 일반 프로세스를 실행하는 것과 크게 차이가 없다.

그래서 자원의 효율적인 차원에서봐도 vm보다 컨테이너가 효율적이다.

 

- 높은 이식성

컨테이너는 라이브러리와 의존 바이너라 파일들이 이미지에 다 포함이 된다. 어플리케이션에 필요한 라이블러리들을 한번에 이미지로 만들어서 제공한다. 이렇게 만들어 놓으면 다른 서버에서 돌려도 똑같이 돌아간다. 다만 문제가 되는 것은 운영체제 커널에서 제공하는 기능을 사용해서 이와 같이 컨테이너 기능을 제공하는데 결국에는 호스트 Os에서 제공하는 기능들이 어떻게 호환이 잘되냐 이것이 중요하다.

그래서 호환되는 런타임 환경을 지원하는 os 커널 환경에서만 실행가능하다.

운영체제 커널이 업데이트 되면서 API가 바뀌었다면 안돌아 갈 수도 있다는 것이다.

가상머신과 차이는 윈도우 컨테이너랑 리눅스 컨테이너는 호환이 되지 않는다.

운영체제의 기능에 의존을 하기 때문에

 

vm vs. container

vm과 컨테이너 비교

컨테이너 형 가상화(Docker)

- 가상머신: os를 호스트 os와 모두 공유를 하기 때문에 따로 컨테이너에 Os를 설치하거나 할 필요가 없다.

- 부팅시간 : os설치가 따로 필요 없기 때문에 바로 시작할 수 있음, 호스트 os위에서 실행하는 것이기 때문에

- 네트워크: 호스트 쪽에서 작성된 docker 전용 NIC 과 통신

- 자원: Persistant volume이라고 해서 저장하고 싶다면 이를 따로 만들어서 외부의 저장공간을 두고 이와 연결시켜줄 수 있어야 한다. 도커는 cpu와 memory 자원만을 조절할 수 있다.

- 오버헤드: 호스트 os 입장에서는 이 컨테이너는 프로세스와 다를게 없다. 컨텍스트 스위칭 같은 것도 필요 없다.

 

하이퍼 바이져 형 가상화 (type1)

- 가상머신: 게스트 os가 필요하기 때문에 vm을 만들고 그 위에 따로 os를 설치해주어야 함

- 부팅시간: os부터 전부다 셋팅을 해주어야 하기 때문에 시간이 오래 걸린다.

- 네트워크: 각각 별도의 가상의 NIC(network interface card)를 사용

- 자원: cpu memory disk 등 다 설정 가능 

- 오버헤드: 하드웨어 위에 하이퍼바이져가 올라가고 그 위에 게스트 Os가 올라가는 구조: type2에 비해서는 오버헤드가 적다

 

호스트 형 가상화 (type2)

- 가상머신 : 게스트 os가 필요하기 때문에 vm을 만들고 그 위에 따로 os 를 설치해 주어야 함(얘는 host os도 필요)

- 네트워크 : 각각 별도 가상의 NIC(network interface card)사용

- 자원: cpu memory disk 등 다 설정 가능

- 오버헤드: 하드웨어, 호스트 os, 하이퍼바이져, 게스트 os 로 레이어가 가장 많아 오버헤드가 가장 높다.

 


컨테이너 관련 기술 소개

세가기 기술을 합쳐서 만들어 진 얘, chroot, 

chroot: 기본 root 디렉토리 변경

namespace: namespace별로 독립적인 공간을 제공

- mnt (파일시스템 마운트):

- pid (프로세스)

- net (네트워크)

- ipc (systemV IPC)

- uts (hostname)

- user (UID)

cgroup (control group)

 


도커

- 2013 등장한 컨테이너 기반 가상화 도구

- go 언어로 개발

- container 관련 기술의 사실상 표준

- docker engine + docker hub

- 애플리케이션 배포의 초점

기존 컨테이너들 다른 환경에서 동작 시키는데 중점

환경 차이로 인한 문제 방지

- snowflake servers: 모든 눈성이 모양이 다르듯, 서버들도 제각기 다른 상태

-코드로 관리하는 인프라

    - 서버를 어떻게 구성할것인지 어떤 라이브러리와 도구를 설치할지를 코드로 정의

    - 항상 같은 결과를 보장하지는 않음

- 불변 인프라

    어떤 시점의 서버 상태를 이미지로 저장

docker = dockerfile + docker image

같은 아키텍처, os를 사용하는 상황에서

 


도커 소개

- 왜 도커를 써야하나

- 도커 이미지와 컨테이너

도커 실습

- 도커 설치하기

- 도커 사용해보기

- 도커 이미지 만들기

 

편리한 서버 세팅과 배포

불변의 인프라 - 한번 설정한 환경은 변경하지 않는다.

웹서비스를 운영한다면 웹페이지 소스를 깔고 수정할 건데, 이후 수정은 코드일 뿐이지 환경을 변경하지는 않는다. 도커같은 경우 서비스 이미지해서 배포, 소스코드만 변경할 수 있게

각각의 버전업일어날 때마다 이미지 새로 생성, 운영체제 환경 변화하지 않고

 

버전관리 시스템, 이미지의 버전관리 제공 이미지를 예전 상태로 돌린다던지..

docker hub에서는 도커의 이미지를 공유한다.

오픈소스처럼 이미지 제공, 유명한 오픈소스 프로젝트들 이미지를 도커허브에서 구할 수 있다.

남들이 구축해놓은 빌드안을 가져와 사용할 수 있다.

 

API 제공하여 자동화 가능

서버운영에 유용

 

도커이미지와 컨테이너

이미지는 서비스 운영에 필요한 서버프로그램, 소스코드, 컴파일된 실행 파일을 묶은 상태

저장소에 올리고 받는 것은 이미지 (push/pull)

컨테이너는 이미지를 실행한 상태

이미지로 여러 개의 컨테이너를 만들 수 있음

운영체제로 치면 이미지는 실행파일 컨테이너는 프로세스로 생각할 수 있음

도커이미지는 베이스 이미지에서 바뀐 부분만 이미지로 생성한다.

컨테이너로 실행할 때는  베이스 이미지와 바뀐 부분을 합쳐서 실행한다.

 

하나의 이미지를 가지고 여러개의 컨테이너를 만들 수 있다.

 

docker hub에서 이미지를 공유할 때는 바뀐 부분만 주고 받는다.

이렇게 하면 네트워크 적게 들고, 저장공간도 적게 든다. 장점

 

베이스 이미지로 해서 계속해서 레이어링, 게층화가 되니, 서로 의존관계가 되고 그 이미지를 기준으로 계속 파생된다.

 

컨테이너는 이미지를 실행을 한 결과

컨테이너는 생애 주기를 갖는다.

 

실행중, 정지, 파기

 

실행중은 동작중인 얘가 있으면 실행중이라고 한다.

도커 파일이라는 것을 통해서 어떤 어플리케이션이 실행중인지 정할 수 있다.

 

정지상태는 두가지가 있다.

한가지는 사용자가 명시적으로 컨테이너를 정지할 수 있다.

어플리케이션이 종료가 될 때 정상적이든, 오류든 정지가 된다면

정지상태로 만든 컨테이너는 디스크에 그대로 저장되어 있다.

다시실행중인 상태로 바꿀 수 있다.

하지만 이런 애들 모아두면 저장공간을 많이 차지하니까

사용자가 명시적으로 삭제할수 있다.

 

이렇게 삭제하면 컨테이너가 파기된다.

 

실질 적으로 그러므로 가질 수 있는 상태는 실행중, 정지 두가지 상태이다.

 


도커 설치

도커 자동설치 명령어를 사용해서 스크립트를 실행시킬 수 있다.

 

$ sudo wget -qO- https://get.docker.com/ | sh

$ sudo systemctl start docker

$ sudo systemctl enable docker

$ sudo systemctl stop docker

 

sudo를 계속 입력하는게 불편하다면,

현재 계정을 docker 그룹에 포함하면 된다.

docker 그룹은 root 권한과 동일하므로 꼭 필요한 계정만 포함하면 된다.

$ sudo usermod -aG docker $USER

a는 새로 추가 G는 그룹 $USER 는 현재 사용중인 유저 이름

$ sudo systemctl restart docker

 

search 명령으로 이미지 검색하기

$ docker search <이미지 이름>

레포지토리 이름이 따로 없고 바로 프로젝트 이름이 있는 애들은 오피셜한 이미지이다.

 

Pull 명령어로 이미지 받기

$ docker pull <이미지이름>:<태그>

 

$ docker image ls

$ docker images

 

run 명령으로 컨테이너 생성하기

$ docker container run <옵션> <이미지 이름> <실행할 파일>

 

-i (interactive>, -t(pseudo-tty) 

--name 컨테이너에 이름 지정

 

exit, ctrl+d를 통해 빠져나올 수 있다.

이렇게 나오면 종료 상태이므로 컨테이너가 정지상태이다.

 

정지상태를 확인하는 명령어는

$ docker container ls -a

 

컨테이너 실행

$ docker start hello(Container_ID)

 

$ docker run (Image_ID)

 

run은 컨테이너를 생성할 때 이미지를 가지고 (생성에 가까운 명령어) 생성+실행

run을 여러번 실행하면 그에 맞게 여러개의 컨테이너 생성됨

start는 기존에 실행되었던 컨테이너를 실행시킴

 

시작한 컨테이너에 접속하기

$ docker container attach hello

 

이 컨테이널 종료하지 않고 그냥 밖으로 나오고 싶다면

ctrl+d , ctrl+q 를 차례대로 입력한다

 

$ docker container exec hello echo "hello world"

$ docker container exec <컨테이너 이름> <명령> <매개변수>

외부에서 컨테이너 안의 명령 실행하기

컨테이너가 실행되고 있는 상태에서만 사용할 수 있으며 정지된 상태에서는 사용할 수 없음

컨테이너에 안에 echo 명령을 실행하고 매개변수로 'hello world" 를 지정했기 때문에 hello world가 출력

 

컨테이너 삭제

$ docker rm hello

$ docker container rm <컨테이너 이름>

 

이미지 삭제

$ docker image rm ubuntu:lastest

$ docker rmi <이미지 이름>:<태그>

태그가 없을 경우 이미지 이름에 해당하는 모든 이미지를 삭제한다.

 

도커이미지생성 - dockerfile 작성하기

 

build 명령으로 이미지 생성

$ docker image build --tag hello:0.1 .

$ docker build <옵션> <dockerfile 경로>

 

--tag 옵션으로 이미지 이름과 태그를 설정할 수 있음

이미지 이름으로만 설치하면 태크는 알아서 lastest로 설정됨

 

build 명령으로 이미지 생성하기

docker build <옵션> <dockerfile 경로>

앞에 생성한 이미지를 실행해보기

$ docker run --name hello-nginx -d -p 80:80 -v /root/data:/data hello:0.1

-d: 컨테이너를 백그라운드로 실행

-p: 80:80 옵션은 호스트의 80번 포트와 컨테이너의 80번 포트를 연결하고 외부에 노출

-v /root/data:/data: 옵션은 호스트의 /root/data 디렉토리를 컨테이너의 /data 디렉토리에 연결

 

도커파일 만들 때 사용되는 인스트럭션

FROM

FROM docker.io/centos:latest

베이스 이미지 지정

지정된 이미지를 다운받는 과정이 있다.

 

RUN

도커 이미지를 빌드할 때 컨테이너 안에서 실행할 명령어를 정의

RUN ["yum", "update"]

RUN ["systemtcl", "start", "httpd"]

RUN yum update

RUN systemctl start httpd

 

COPY 

 

파일을 카피한다

호스트에서 컨테이너로

컨테이너에서 호스트로 복사할 수 있다.

COPY ["src", "~~"]

 

CMD

커네이너를 실행할 때 사용하는 컨테이너

 

ENTRYPOINT

CMD와 비슷

조금 다른 점이 있다면 

run을 실행할 때 오버라이드가 불가능

 

LABEL

이미지에 대한메타정보를 입력할 수 있음

 

EXPOSE

도커이미지걍 다큐멘테이션임

실제 컨테이너 동작과는 관련 없음

-p로 설정하는 부분을 다큐멘테이션해주는 부분

 

WORKDIR
작업디렉토리 변경

 


인터페이스와 가상머신에 대한 설명으로 옳지 않은 것을 모두 고르시오

1) 가상 머신은 결국 host 서버 위에서 guest 인터페이스들을 에뮬레이션하는 방식으로 구현된다.

-> 가상 머신은 Host 서버 위에서 guest 인터페이스들을 에뮬레이션 하는 방식임

2) Java 는 guest ABI 에뮬레이션의 주요 예이다

-> Java는 API의 주요 예이다. ABI는 runtime이 있다.

3) Type-1 하이퍼바이저는 Type-2 하이퍼바이저에 비해서 성능적으로 유리하다

-> type-1이 type-2보다 레이어 층이 작으므로 type-1이 성능적으로 유리하다.

4) Full virtualization은 guest 운영체제의 수정을 필요로 한다.

-> full virtualization은 하드웨어 전체를 가상화하는 방식으로 OS의 제약없이 사용할 수 있다.

guest OS는 자신이 가상화 위에서 동작하고 있다는 것을 인식할 수 없다.

그러므로 full virtualization은 운영체제의 수정을 필요로 하지 않는다.

그리고 full 의 반대는 para로 이 종류에는 type-1과 Type-2가 있다.

5) type-2 하이퍼바이저는 type-1 하이퍼바이저에 비해서 사용 및 구성이 편리하다는 장점이 있다.

-> type-1이 type-2에 비해 레이어 층이 적어 효율성이 높다는 장점이 있지만, type-2는 사용하기 편리하다는 장점이 있다.

4. Docker를 사용하는 이유와 관련된 설명으로 옳지 않은 것은?

1) docker 를 활용하면, 클라우드 플랫폼의 자동확장 기능과 연동하여 서비스를 손쉽게 확장할 수 있다.

2) dockersms github처럼 docker 이미지를 공유하지 위한 docker hub를 제공한다.

3) docker는 이미지 버전관리를 제공한다

4) dokcer는 운영체제와 서비스 환경을 분리하여 가벼우며, 높은 이식성을 제공한다.

5) docker hub에서 이미지를 pull하기 위해서는 docker hub에 가입 및 로그인이 필요하다.

-> 이미지 pull하는데는 로그인이 따로 필요하지 않다.

 

10. 가상화로 얻을 수 있는 장점과 관련된 설명으로 옳지 않은 것은?

1) 다른 운영체제를 위해 만들어진 응용프로그램을 실행할 수 있다.

2) 보안적인 위험이 존재할지도 모르는 운영체제나 프로그램을 안전하게 기존 시스템으로부터 격리할 수 있다.

3) 낮은 성능의 물리서버들을 가지고 강력한 가상의 서버를 만들 수 있고, 이러한 성능 향상 접근 방식을 scale-up이라고 한다.

4) 하나의 물리서버에서 여러개의 작업을 수행할 때 작업간의 격리가 가능하다.

5) 하나의 물리서버 위에서 여러 가상머신을 운영하여 서버 활용율을 높일 수 있다.

-> scale-up이 아니라 scale-out이다

 

11. 가상머신의 동작 원리와 관련된 설명으로 옳지 않은 것을 모두 고르시오.

1) CPU는 일반적으로 protection domain(ring)을 제공하며, Dom0(ring0)이 그중에서 가장 높은 권한을 가진다

2) guest OS가 물리페이지라고 생각하는 것은 실세로는 하이퍼바이저의 가상페이지이다.

3) 실제 물리페이지 프레임의 할당/관리는 VMM이 직접 수행한다.

4) guest OS에서 메모리 접근시에는 항상 하이퍼바이저를 거쳐아 한다.

5) 하이퍼바이저는 guest OS위에서 어떤 작업이 수행되고 있는지 알 수 있다.

 

12. docker 명령어와 관련된 설명으로 옳지 않은 것을 모두 고르시오

1) 'docker container start' 명령은 docker 이미지로부터 컨테이너를 생성한 뒤 컨테이너를 시작한다.

2) 'docker image rm' 명령과 'docker rmi' 명령은 동일하다.

3) 'docker container exec' 는 해당 컨테이너가 정지 중인 상태에 있다면 실행 중인 상태로 변경한 뒤 컨테이너 안에서 명령을 실행한다.

4) 'docker image build' 에서 이미지 이름만 설정하면, 태그는 자동으로 latest 로 설정된다.

5) 'docker run -p 9000:80000'명령을 통해 컨테이너를 생성한다면, 외부에서 호스트 ip 주소와 8000번 포트를 통해 생성한 컨테이너의 9000번 포트 서비스에 접근할 수 있다.

반응형