가상화와 가상머신

가상화

가상화는 단일한 물리 하드웨어 시스템에서 여러 시뮬레이션 환경이나 전용 리소스를 생성할 수 있는 기술

하이퍼바이저라고 불리는 소프트웨어가 하드웨어에 직접 연결되며, 1개의 시스템을 가상머신VM이라는 별도의 고유하고 독립된환경으로 분할할 수 있음

하이퍼바이저라는 소프트웨어가 물리 리소스를 필요로 하는 가상 환경으로부터 물리 리소스를 분리합니다.

하이퍼바이저가 설치된 물리 하드웨어를 호스트라고 하며, 그 리소스를 사용하는 여러 VM을 게스트라고함

APP과 종속성을 분리해 체계화 할 때, 기존의 VMware, VirtualBox 와 같은 OS가상화 방식에서 벗어나, CPU의 가상화기술 (HVM) 을 이용한 KVM (Kernel-based Virtual Machine) 과 반가상화 (Paravitualization) 방식의 Xen이 등장함. 게스트 OS가 필요하긴 하지만, 전체 OS를 가상화하는 방식이 아니었기에 성능이 향상.

리눅스에서는 이러한 방식을 개선하기위해 프로세스를 격리하는 리눅스컨테이너 방식이 등장

도커는 리눅스컨테이너에 여러 기능을 추가하여, APP을 컨테이너로서 좀더 쉽게 사용할 수 있도록 만들어진 오픈소스 프로젝트.

기존의 VMWare, Virtual_Machine가상 머신은 운영체제 인스턴스 하나를 구획화(Compartmentalizing)가 필요한 애플리케이션 각각에 할당하는 방식으로 '분리(Isolation)'를 제공한다. 거의 완전하게 분리시킬 수 있는 방법이지만, 상당한 비용이 수반된다. 각 운영 인스턴스가 앱 자체에 더 효과적으로 할당할 수 있는 메모리와 프로세싱 파워를 소비하기 때문이다.

리눅스 컨테이너를 이해하기 위한 출발점은 cgroups(control groups) 및 네임스페이스(namespaces)이다. 컨테이너와 호스트에서 실행되는 다른 프로세스 사이에 벽을 만드는 리눅스 커널 기능들이다. IBM이 최초 개발한 리눅스 네임스페이스는 시스템 리소스들을 묶어, 프로세스에 전용 할당하는 방식으로 제공한다.

구글이 최초 개발한 리눅스 cgroups는 분리와 CPU, 메모리 등 프로세스 그룹의 시스템 리소스 사용량을 관리한다. 예를 들어, 과학용 컴퓨팅 애플리케이션 같이 많은 CPU 사이클과 메모리를 소비하는 애플리케이션을 운영하는 경우, 애플리케이션을 cgroup에 집어넣어 CPU와 메모리 사용량을 제한할 수 있다.

네임스페이스는 프로세스 하나의 리소스 분리를 처리하고, cgroups는 프로세스 그룹의 리소스를 관리한다. cgroups와 네임스페이스가 결합되면서 리눅스 컨테이너(Linux Containers, LXC)라는 컨테이너 기술이 탄생했다.

가상화종류

호스트 가상화

PC , Server에 OS를 설치하고, 그 위에 가상머신을 설치하여, Host OS 위에서 Guest OS 를 운영하는 방식
각 가상환경마다 가상머신을 생성하고, Guest OS를 설치하게됨
예시로 VirtualBox, VMWare, Parallels 등이 있습니다.
장점으로는 가상의 하드웨어를 운영하는것으로, 호스트운영체제에 큰 제약사항이 없습니다
단점으로는 OS위에 OS가 얹히는 방식이라, 오버헤드가 큽니다.

하이퍼바이저 가상화

Host OS 없이 하드웨어에 하이퍼바이저를 설치하여 사용하는 방식으로
Xen, MS Hyper-V, KVM등이 있고 아마존의 EC2가 Xen을 기반으로 구축되어 있습니다.
호스트OS없이 하드웨어를 직접 제어하기에 효율적으로 리소스를 사용할 수 있습니다.
하지만, 자체적으로 머신에 대한 관리기능이 없기에 관리를 위한 컴퓨터나 콘솔이 필요합니다.
하이퍼바이저에는 [전,반]가상화방식이 있는데, 전가상화는 하드웨어를 완전히 가상화하는방식으로,

전가상화 방식은 하이퍼바이저에서 어떤 OS든 각 OS들의 명령어를 번역해주고, 각 OS들에 자원까지 할당하는 역할까지 하기에 Guest OS 운영체제의 별다른 수정이 필요없지만, 약간 성능이 떨어집니다.

반가상화방식은 전가상화의 성능저하를 막기위해 Hyper Call이라는 인터페이스로 각 OS에 각기다른 번역기를 통해 작동합니다. 전가상화에 비해 성능이 좋지만, 각 Guest OS의 커널을 수정해줘야한다는 단점이있습니다.

컨테이너 가상화

호스트OS위에 컨테이너 관리 소프트웨어를 설치하여, 논리적으로 컨테이너를 나누어 사용
다른 가상화방식들보다 오버헤드가 적어 가볍고 빠르다는 장점이 있습니다.
호스트 운영체제의 커널을 공유하면서 격리된 컴퓨팅 자원을 제공하는 가상화기술입니다
하드웨어를 가상화하는 가상머신과 달리 커널을 공유하는 방식이기에, 실행속도가 빠르고 성능상의 손실이 거의 없습니다.
컨테이너로 실행된 프로세스는 커널을 공유하지만, 리눅스 namespaces, cgroup, chroot등의 커널기능을 활용해 격리되어 실행됩니다.
이러한 격리기술 덕분에 호스트머신에게는 프로세스로 인식되지만, 컨테이너 관점에서는 마치 독립적인 가상머신처럼 보이게 됩니다

CGROUPS

Control Group의 약자로 다수의 프로세스가 포함되어있는 프로세스그룹 단위로 자원사용(CPU,I/O,Memory,Network 등)을 재한하고 격리시키는 리눅스 커널 기능

namespace

프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능

chroot

가상 루트 디렉터리
보안 등을 위해 새로운 가상의 루트디렉토리를 생성하여 원격 서비스로 접속할 경우 이 디렉토리의 상위로 이동이 불가능하게 하는 명령어
파일을 격리시켜 독립공간을 생성

리눅스 컨테이너 장점

  • 운영체제 수준의 가상화: 컨테이너는 운영체제 수준의 가상화 기술입니다. 별도의 하드웨어 에뮬레이션 없이 리눅스 커널을 공유해 컨테이너를 실행하며, 게스트OS 관리가 필요하지 않습니다.
  • 빠른 속도와 효율성: 하드웨어 에뮬레이션이 없기 때문에 컨테이너는 아주 빠르게 실행됩니다. 프로세스 격리를 위해 아주 약간의 오버헤드가 있지만 일반적인 프로세스를 실행하는 것과 거의 차이가 없습니다. 또한 하나의 머신에서 프로세스만큼 많이 실행하는 것이 가능합니다.
  • 높은 이식성portability: 모든 컨테이너는 호스트의 환경이 아닌 독자적인 실행 환경을 가지고 있습니다. 이 환경은 파일들로 구성되며, 이미지 형식으로 공유될 수 있습니다. 리눅스 커널을 사용하고 같은 컨테이너 런타임을 사용할 경우 컨테이너의 실행 환경을 공유하고 손쉽게 재현할 수 있습니다.
  • 상태를 가지지 않음stateless: 컨테이너가 실행되는 환경은 독립적이기 때문에, 다른 컨테이너에게 영향을 주지 않습니다. 도커와 같이 이미지 기반으로 컨테이너를 실행하는 경우 특정 실행 환경을 쉽게 재사용할 수 있습니다.
  •  

유니온 파일 시스템 Union File System

UFS에서는 기존 레이어(하위 레이어) 위에 새로운 레이어(상위 레이어)가 쌓일 경우, 하위 레이어는 읽기 전용 상태가 된다. 또한, 상위 레이어에서 하위 레이어에 쓰기 작업을 수행할 경우, 하위 레이어를 복사하여 사용(CoW)하기 때문에 상위 레이어에서는 하위 레이어에 아무런 영향을 주지 않는다.

도커에서는 레이어가 크게 컨테이너 레이어(상위)와 이미지 레이어(하위)로 구분된다. UFS 특성에 따라서 컨테이너가 파일 시스템에 쓰기 작업을 수행할 경우, 실질적으로는 하위 레이어의 복사본에 해당 작업을 수행하기 때문에 서로 다른 컨테이너가 하위 레이어를 공유하고 있어도 서로 독립적인 파일 시스템 운용이 가능해진다.



https://loopstudy.tistory.com/20
https://loopstudy.tistory.com/22?category=1004771
https://velog.io/@koo8624/Docker-유니온-파일-시스템-Union-File-System
https://www.redhat.com/ko/topics/containers/what-is-docker

'Python > Docker' 카테고리의 다른 글

docker-compose  (0) 2021.03.10
Docker  (0) 2021.03.09

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.

여러 도커 Application을 정의하고 실행하는 툴로, YAML파일을 통해 각각의 서비스를 설정할수있다.

version: "3.9"  # optional since v1.27.0
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

(공식문서 Docker-compose 예시)

도커 엔진 1.13.1 버전 이상, 도커컴포즈 버전 1.6.0 이상에서 사용할 수 있는 기능으로,
컨테이너 실행에 필요한 옵션을 docker-compose.yml 이라는 파일에 담아서 일괄적으로 실행시켜준다

version

첫 줄에는 version 을 명시해준다.

version : '3'

3으로 시작하는 최신버전을 사용한다는 뜻

버전 3부터는 links: 를 통하여 연결해줄 필요가 없다

services

실행하려는 컨테이너들을 정의한다.
서비스의 이름을 지정해주고, 그 안에 이제 도커이미지명, 환경변수 등등 다양한 것들을 입력해 넣어서 구성해준다.

서비스 이름 (지정)

사용하려는 컨테이너를 지정하는 이름과같다

services: #서비스부터 어떤 컨테이너를 이용할 것인지 작성
  postgresql: #db이라는 서비스를 이용할것인데 

postgre 서비스 이름을 postgresql로 지정하였다

image

사용하려는 이미지

services: #서비스부터 어떤 컨테이너를 이용할 것인지 작성
  postgresql: #db이라는 서비스를 이용할것인데 
    image: postgres:12 #그 서비스의 이미지는 이것과 같고

postgresql에서 사용할 도커 이미지를 적는다.

postgres (docker.com) 설명 사진 (hub.docker.com)

volumes

volumes:
      - ./servers.json:/pgadmin4/servers.json

docker run 으로 db컨테이너 실행시 --volume 옵션으로 연결하던 로컨의 데이터와 같다.
위 과정을 통해 프로젝트 루트 아래의 pgadmin4 에 servers.json 을 저장하였다

environment

services:
  postgresql:
    environment:
      POSTGRES_DB : Chinook
      POSTGRES_USER: postgres_admin
      POSTGRES_PASSWORD: password

Chinook이라는 Database로, User와 비밀번호를 지정하였다.

restart

restart 공식문서
재실행 여부를 설정한다.

Restarts all stopped and running services.
If you make changes to your docker-compose.yml configuration these changes are not reflected after running this command.
For example, changes to environment variables (which are added after a container is built, but before the container’s command is executed) are not updated after restarting.
If you are looking to configure a service’s restart policy, please refer to restart in Compose file v3 and restart in Compose v2. Note that if you are deploying a stack in swarm mode, you should use restart_policy, instead.

어떠한 구성을 변경했을 때 변경사항의 즉각적인 반영 여부를 나타내는 것 같다.


services: #서비스부터 어떤 컨테이너를 이용할 것인지 작성
  postgresql: #db이라는 서비스를 이용할것인데 
    restart: unless-stopped

윗 부분에서 이제 Postgre를 설정했으면, 이제 Admin부분을 만들어준다

  pgadmin:
    image: dpage/pgadmin4:4
    container_name : pgadmin
    ports:
      - 5050:80 #외부에서 5050으로 들어왔을 때 내부에서 80번을 보여주겠다
    environment:
      # PGADMIN_DEFAULT_HOST: postgres_admin
      PGADMIN_DEFAULT_EMAIL: user1@pgadmin.com
      PGADMIN_DEFAULT_PASSWORD: secret
    depends_on:
      - postgresql
    volumes:
      - ./servers.json:/pgadmin4/servers.json
    restart: unless-stopped  

image는 pgadmin4의 4번태그 이미지를 활용하며, 서비스이름은 pgadmin, container_name또한 동일하게 설정.
ports부분이 있는데, 이 부분을 이제 들어온곳과 연결할 곳을 입력해줘야한다. 여기서는 5050번 포트로 들어왔을때, 내부의 80번 포트와 연결한다는 것이다.
그리고 이후 pgadmin페이지 (localhost:5050)에서 로그인할 이메일,비밀번호를 설정하였다.
depends_on 부분이 있다.
이 부분은 앞서 작성한 postgresql이 실행되고 나서, pgadmin이 실행된다는 뜻이다


이제 실제로 compose만들고, up해서 연결해보자

version: '3.8'
services:
  db:
    container_name: pg_container # pgadmin에서 서버연결할 때 연결할 
    image: postgres
    restart: always
    environment:
      POSTGRES_DB: test_db
      POSTGRES_USER: root
      POSTGRES_PASSWORD: root
    ports:
      - "5432:5432"
  pgadmin:
    container_name: pgadmin4_container
    image: dpage/pgadmin4
    restart: always
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@admin.com
      PGADMIN_DEFAULT_PASSWORD: root
    ports:
      - "5050:80"
    depends_on: 
      - db

docker-composet up --force-recreate 명령어를 통해 up을 하면서, 혹시 이전에 저장했다가 테스트용으로 했던게 있어도, 새로 반영하도록한다. 

이제 pgadmin4 사이트에서

yml파일에 적어놓은, DEFAULT_EMAIL , DEFAULT_PASSWORD를 통하여 로그인한다 

로그인을 하면  browser페이지로 넘어가는데, 이곳에서 서버를 클릭해도 아직 연결되어있지않다, server - create

서버생성(연결) connection에 기존에 yml파일에서 세팅했던것들을 입력하여 연결!

서버연결에 성공하고나면, 내가 yml에서 만들었던 db의 POSTGRES_DB가 생성되어있다.

 

이후, db와 pgadmin을 띄우고난 뒤 DBeaver를 통해 연결해보자 

정말 간단하다! 그냥 연결하면서 POSTGRES 설정해주고, localhost의 5432포트와, 
Database이름은 내가 기존에 생성한 db로 하고, user와 password를 입력하면 연결완료!

참조 :
도커(Docker) 컴포즈를 활용하여 완벽한 개발 환경 구성하기 | 44BITS
docker-compose공식문서

'Python > Docker' 카테고리의 다른 글

[Docker] 도커를 알기위해 알아야하는 것들  (0) 2021.08.31
Docker  (0) 2021.03.09

드디어 만났다 도커!

너무도 많은 엔지니어들이 애용하고있는 도커다!

도커는 어플리케이션의 실행환경을 코드로 작성할 수 있고, OS와 격리시켜 관리할 수 있는 환경을 제공한다.
이게 얼마나 강력한것이냐?!!
Application들은 운영체제(Linux, Windows, MacOS 등) 에 따라, 각각의 환경을 구분하여 개발해야 한다. 왜냐면 각각 os마다 파일시스템, 텍스트의 문법 등 사소한것부터 큰것까지 무지하게 다르기 때문에, 이것들을 하나하나 다 맞춰주면서 개발을 해줘야 했다는 뜻이다. 얼마나 귀찮았을까..
그리고, 그렇게 개발할 때 환경변수도 맞춰줘야하고, 사용자권한, 폴더들, 방화벽, 포트 등등 수많은 설정이 있기에, 이것들을 다 하나하나 관리해줘야했다는 것을 의미하며 굉장히 번거로운 작업일수밖에 없었다.

도커 이전에는 가상머신을 이용했다고한다. 하나의 컴퓨터에 다른 컴퓨터를 통째로 만드는것이다.
맥에서 인터넷뱅킹을 위하여 페러렐즈를 통해 윈도우를 사용하던것과 같다.
그런데, 가상머신이 생각보다 성능 손실이 상당하다는 것이 큰 단점이었다.

리눅스 컨테이너

위의 가상머신의 성능문제를 해결하기 위해 생겨난 기술이 리눅스컨테이너이다.
컨테이너 안에 가상 공간을 만들어, 실행파일을 호스트 컴퓨터에서 직접 실행하는 것이다.
리눅스의 cgroup, namespaces가 제공하는 기술이다.
필요한 라이브러리와, 어플리케이션을 모다, 하나의 서버처럼 구성한 것으로, 컨테이너 내의 네트워크 설정, 환경변수 등 시스템 자원이 독립적으로 구성된다.

  1. 프로세스의 구획화
  • 특정 컨테이너에서 작동하는 프로세스는 기본적으로 그 컨테이너 안에서만 엑세스 가능
  • 컨테이너 안에서 실행되는 프로세스는 다른 컨테이너의 프로세스에 영향을 줄 수 없음
  1. 네트워크의 구획화
  • 하나의 컨테이너에 하나의 IP가 할당
  1. 파일 시스템의 구획화
  • 컨테이너 안에서 사용되는 파일시스템은 구획화되어있음
  • 해당 컨테이너의 명령이나 파일 등의 엑세스를 제한할 수 있음

왼쪽 : 도커                                 오른쪽 : 가상머신

도커

리눅스 컨테이너 기술을 활용, App 실행환경을 코드로 작성할 수 있고, OS와 격리화 하여 관리하는 기술.
환경표준화, 수작업으로 일치시키는 환경 구성,


도커 컨테이너를 만들 때, 환경변수를 넣어주는 부분에서 자꾸 에러가 났다. 여러 방법을 찾아보니, txt파일로 직접 만들어서
docker container run 이후 인자로 --env-file = [filename]를 통하여, txt파일 내의 환경변수를 자동 매핑시켜 실행할 수 있었다. 

vi env_list.txt
#---
S3S1N2_Name=장형준
github_username=jun1116 
#---입력 후 Esc, :wq 로 종료
##### Vi 에디터를 통하여 env_list.txt 에 환경변수를 작성
 
docker container run -it --name first --env-file=env_list.txt aibcontents/n312:1.0 bash
# --실행, 후 ls로 내부 파일 확인, python 명령어를 통해 해당 파이썬 파일 실행 

docker inspect를 통해 확인해보니, 내가 입력한 환경변수가 성공적으로 등록되었다

'Python > Docker' 카테고리의 다른 글

[Docker] 도커를 알기위해 알아야하는 것들  (0) 2021.08.31
docker-compose  (0) 2021.03.10

+ Recent posts