View
학습목표
- 가상머신(VMware)과 컨테이너(Linux Container)의 차이점을 이해하고 설명할 수 있다.
- Hypervisor 가상화와 Container 가상화의 차이점을 이해할 수 있다.
- 컨테이너 가상화 기술인 도커(Docker)를 사용함으로써 얻을 수 있는 장점을 설명할 수 있다.
- Docker의 구조
1. Docker client와 docker server(docker engine),
2. Docker image,
3. Docker registries(docker-hub),
4. Docker container 를 이해한다. - Dockerfile를 사용하여 docker-image를 빌드할 수 있다.
- docker-image를 docker-hub에 push 할 수 있다.
- docker-hub에 올려져 있는 docker-image를 pull 받을 수 있다.
- docker-image를 실행시켜 conatiner를 띄울수 있다. (application 배포)
- EC2 서버에 docker image를 이용하여 application을 배포 할 수 있다.
1. Docker란?
- 도커(Docker)는 가상화 기술이다. Docker 라는 회사가 container virtualization 을 개발하였고 그래서 docker가 container virtualization 기술의 또다른 이름으로 오해하시는 분들이 있는데 container virtualization은 docker 이전에 이미 개발되어 존재 하고 있었다. Docker는 가상화 컨테이너에 application 배포를 자동화 시켜주는 오픈소스 엔진이다.
가상화 : 내컴퓨터안에 또다른 컴퓨터가 있도록 해주는 기술, 효율적인 서버관리를 위해 가상화기술이 나오게됨.
- Docker는 container 가상화 실행 환경 위에 application 배포 엔진을 더함으로서 사용자의 코드를 어디서든 빠르고 가볍게 실행시킬수 있는 기술을 제공한다. 이는 요즘 널리 사용되는 MSA(Micro Service Architecture)와 CI/CD 와 아주 잘 조화되어서 많은 각광을 받게 된다. 실제로 docker는 한 컨데이너 당 하나의 application이나 프로세스를 실행하는 것을 권한다. MSA의 철학과 일맥상통 하는것이다.
- 가상머신 : vmware, virtualBox, KVM
Hypervisor가 Host OS의 자원을 분배하여 GuestOS에서 할당해줌.
- 단점 : 매번 무거운 OS를 설치하고 제거해주어야함. 이 단점을 보완하여 컨테이너 기술이 나오게됨.
- 리눅스 컨테이너 : Host OS 위에 파일시스템을 가지고 어플리케이션만 띄움.
프로세스(실행파일이 메모리에서 실행되는 것.)만 격리해서 띄움.
Docker, container 두 가지가 있다. 전세계적으로 Docker가 많이 쓰임. 차이점은 하이퍼바이저와 같은 지나친 간섭의 유무
2. Hypervisor 가상화 VS Container 가상화
2-1. Hypervisor 가상화
- Hypervisor는 물리적인 서버 에서 하나 혹은 그 이상의 독립적인 운영체제가 돌아가는 구조이다. 즉 물리적 서버의 OS 위에 여러 다른 독립적인 OS가 가상적(virtually)으로 돌아가는 구조이다. 각각의 OS는 서로에 대해서 알지 못하며 base OS (물리적 서버의 OS)도 알지 못한다. 하나의 물리적 서버에서 실행되고 있지만 가상적으로서 완전한 독립적 OS로 운영 되는 것이다. 이러한 가상화의 장점은 물리적 서버의 리소스를 더 효율적으로 사용할수 있다는 것에 있다. 한 서버에 하나의 OS만 운영을 하는 경우 해당 OS가 서버의 모든 리소스를 항상 full로 사용하기 어려우므로 서버 리소드들이(예를 들어 CPU) idle 상태로 낭비되어 지는 경우가 있을수 있다.
- 반면에 hypervisor 가상화를 사용하여 하나의 서버에 여러 OS를 실행시키면 CPU를 idle 상태로 두지않고 필요한 OS나 서비스에 할당이 되어질 수 있음으로 리소스를 훨씬 효율적으로 쓰게 되는것이다. 그럼으로 고급 사양의 좋은 서버에 여러 가상화 OS들을 운영하는 것이 저급이나 중급 사양의 여러 서버를 운영하는것보다 훨씬 효율적이라는 것이다. 단점은 기술적을 너무 무겁다(heavy-weight)는 것이다. 독립적인 OS를 실행시키는 것이기 때문에 booting 시간이 길 수 밖에 없으며 리소스를 많이 차지할수 밖에 없다.
2-2. Container 가상화
- Docker 같은 컨테이너 가상화 기술은 hypervisor 가상화와 틀리게 OS의 커널 위의 유저 공간(user space)에서 실행된다. 즉 완전히 독립적인 운영체제를 가상화 하는 것이 아니라 독립적인 user space를 가상화 한다고 생각하면 쉽다. 즉 하나의 호스트 서버에서 여러 독립적인 user space 인스탄스들을 가상적으로 실행할 수 있게 되는 것이다. 이러한 가상화 기술의 장점은 hypervisor 가상화 보다 훨씬 가볍기 때문에 빠르고 쉽게 독립적인 가상 환경을 실행시킬수 있다 (또한 hypervisor는 base OS와 가상화 OS 사이에 커널 시스템 호출을 연결 시켜주는 emulation layer가 필요한데 docker는 hypervisor 처럼 emulator가 필요없이 그냥 일반적인 시스템 API interface를 사용한다).
- 예를 들어 docker image만 있으면 어디서든 쉽고 빠르게 test 환경, sandbox 환경 및 production 배포를 할 수 있다. 그럼으로 최근에 널리 퍼져있는 MSA(Micro Service Architecture)와 CI/CD에 아주 잘 어울리는 가상화 기술로서 각광을 받고 있다. 단점은 독립적인 OS가 아닌 user space 가상화를 하는 형태이다 보니 운영체제가 전혀 틀린 호스트에서는 실행을 시킬수가 없다. 예를 들어 Windows 를 linux 호스트에서 실행시킬수 없다.
- (하지만 사실 개발자라면 windows는 어차피 대부분 사용 안할테니 크게 상관없다). 그리고 완전히 독립적인 운영체제 가상화가 아니다 보니 보안적인 측면에서 hypervisor 보다 약할수 밖에 없다.
3. Docker 구조
컨테이너 가상화기술이자 회사명이다.
최근에 오픈소스 컨테이너 가상화 기술도 성장하고 있기 때문에 이름하나로만 기억해서는 안된다!
3-1. Docker client 와 server
1) 도커 클라이언트
2) 도커 서버(도커 데몬) : 백/윈도우는 뒤에 떠있다.
- Docker는 클라이언트 와 서버 구조로 이루어저 있다. 클라이언트가 서버에 명령을 전달하고 서버가 실행시키는 구조이다. docker binrary 커맨드가 docker 클라이언트 이고 dockerd 가 docker daemon 혹은 docker engine이다. Docker engine과 interact하기 위한 Restful API도 제공된다. 클라이언트와 서버는 동일한 호스트 안에서 운영 될수도 있으며 서로 다른 호스트에서 운영 될수도 있다.
3-2. Docker 이미지
- Docker의 life cycle에서 docker 이미지는 “build”의 부분에 해당된다. Docker container에서 실행시키고 싶은 application을 docker 이미지로 빌드해서 실행시키게 된다.
- 컨테이너를 어떤 서버로 실행할 것인지 선택하는 것, 내가 앱을 실행시킨 환경과 같은 환경을 이미지로 만들 수 있음. Dockerfile이라는 설계도를 가지고 이미지를 만듦. 버전 꼭 명시하기
3-3. Docker registries
- Docker registires는 docker 이미지를 저장하는 repository라고 보면 된다. Source code를 github에 저장하여 관리하듯 docker 이미지는 dockerhub 같은 docker registries에 저장한다고 생각하면 된다. Github가 마찬가지로 public registry 가 있고 private registry가 있다.
카세트 플레이어가 도커 데몬(서버)라고하면, 이미지는 카세트 테이프이다. 그 결과물은 컨테이너
도커만 설치되어있다면, 언제든지, 이미지를 실행시켜 컨테이너를 얻을 수 있다.
3-4. Docker containers
- Docker container에서 docker 이미지가 실행된다. 즉 docker 이미지를 실행시키는 가상화 공간 이다. Docker container는 하나 혹은 그 이상의 프로세스를 실행 시킬수 있다 (하지만 하나의 프로세스만 실행시키는 것을 권장).
컨테이너는 영원하지 않고, 프로세서가 동작하고 작업이 동료되면, 컨테이너도 종료됨.
3-5. Docker Compose And Swarm
- Docker에서는 여러 docker container들로 이루어진 stack이나 cluster를 관리 하는 서비스도 제공하는데 바로 docker compose 와 docker swarm이다.
- Docker compose는 복수의 docker container들을 모아서 종합적인 application stack을 정의 하고 운영할수 있도록 해주는 서비스이다. Compose 파일을 사용하여 전체적인 application 서비스를 설정한후, application을 이루고 있는 각각의 컨테이너들 (예를 들어, web 서버 컨테이너, api 서버 컨테이너 등등)을 따로 실행시킬 필요 없이 한번에 생성하고 실행할 수 있도록 해준다. Docker swarm은 docker containers 들로 이러우진 cluster를 관리할수 있도록 해주는 서비스이다. 즉 docker container를 위한 clustering tool 이다.
4. 그 외 Docker의 특징들
- Docker는 modern한 리눅스 커널이 설치되어 있는 x64 호스트에서는 다 실행 가능하다 하지만 커널 버젼 3.10 이상에서 실행되는 것이 overhead가 적기 때문에 권장된다. 최근에는 docker를 Windows 나 Mac에서도 사용 가능하다. 하지만 Windows 및 Mac에서 docker를 직접 실행시키면 내부적으로 가상머신이 실행되어 그 안에서 docker가 실행되기 때문에 개발용 및 테스트 용으로는 괜찮지만 production 용도로는 적합하지 않다.
- Docker 컨테이너는 독립된 root 파일 시스템이기도 하다 그러므로 파일 시스템 분리가 이루어져 있다. 또한 docker 컨테이너는 호스트와 분리된 프로세스 환경을 가지고 있으므로 독립적인 프로세스를 실행할수 있다. 파일 시스템과 프로세스 환경과 마찬가지로 네트워크 또한 분리 되어 있어서 독립적인 가상 네트워크 인터페이스 와 IP 주소를 가질 수 있다.
- Resource isolation and grouping - 커널의 cgroups 기능을 통해서 docker container마다 독립적인 CPU와 메모리 가 할당 될수 있다. Docker 파일 시스템은 copy-on-write 을 사용하여서 효율적이며 빠른 디스크 IO를 실행한다. Docker의 copy-on-write은 중요한 특징중 하나이므로 다음에 더 자세히 설명하겠다.
- Docker 컨테이너에서 STDOUT, STDERR, STDIN을 통해서 생성되는 로그들은 전부 수집되어서 분석하거나 trouble-shooting을 가능하게 해준다. 그뿐만 아니라, 실행되고 있는 docker container의 shell에 접속해서 interact할 수도 있다.
Docker 주요 명령어
docker ps --help
docker ps --help
containers 조회
docker container ls
Running containers 조회
docker ps -a
컨테이너 실행
docker run -d -p 8080:80 docker101tutorial
여러포트에서 컨테이너 실행
docker run -d -p 3000:80 -p 8080:80 docker101tutorial
컨테이너 종료
docker stop containerID or name
컨테이너 삭제
docker rm containerID
모든 컨테이너 아이디만 조회
docker ps -aq
모든 컨테이너 아이디 삭제
docker rm $(docker ps -aq)
실행중인 컨테이너 강제 삭제
docker rm -f $(docker ps -aq)
컨테이너 원하는 이름으로 run 하기
docker run --name 원하는이름 -d -p 3000:80 image이름
docker format 변경하기
방법 1
docker ps --format="ID\t{{.ID}}\nNAME\t{{.Names}}\nIMAGE\t{{.Image}}\nPORTS\t{{.Ports}}\nCOMMAND\t{{.Command}}\nCREATED\t{{.CreatedAt}}\nSTATUS\t{{.Status}}\n"
방법 2
$ export FORMAT="ID\t{{.ID}}\nNAME\t{{.Names}}\nIMAGE\t{{.Image}}\nPORTS\t{{.Ports}}\nCOMMAND\t{{.Command}}\nCREATED\t{{.CreatedAt}}\nSTATUS\t{{.Status}}\n"
$ docker ps --format=$FORMAT
local의 파일을 가져와 컨테이너 위에서 run 시키기
#해당 파일이 있는 directory에 접속
docker run --name sebsite -v $(pwd):/user/share/nginx.html:ro -d -p 8080:80 nginx(ImageName)
#pwd는 파일의 경로
ro는 readonly의 읽기전용이므로 ro를 제거하면 읽고 쓸 수 있다.
container에 접속
docker exec -it contaiceID또는 name bash