[docker] 도커 기본 및 명령어
도커란?
컨테이너를 사용하여 응용프로그램을 더 쉽게 만들고 배포하고 실행할 수 있도록 설계된 도구이며, 컨테이너 기반의 오픈소스 가상화 플랫폼이며 생태계이다
📍 서버에서의 컨테이너 개념
컨테이너 안에 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해줍준다. 일반 컨테이너의 개념에서 물건을 손쉽게 운송 해주는 것 처럼 프로그램을 손쉽게 이동 배포 관리를 할 수 있게 해준다.
AWS, Azure, Google cloud 등 어디에서든 실행 가능하게 해준다.
컨테이너 이미지는 코드, 런타임, 시스템 도구, 시스템 라이브러리 및 일정과 같은 으용 프로그램을 실행하는 데 필요한 모든 것을 포함하는 가볍고 독립적이며 실행 가능한 소프트웨어 패키지이다
컨테이너 이미지는 런타임에 컨테이너가 되고 도커 컨테이너의 경우 도커 엔진에서 실행될 때 이미지가 컨테이너가 된다.
리눅스와 윈도우 기반 애플리케이션 모두에서 사용할 수 있는 컨테이너화된 소프트웨어는 인프라에 관계없이 항상 동일하게 실행된다.
컨테이너는 소프트웨어를 환경으로부터 격리시키고 개발과 스테이징의 차이에도 불구하고 균일하게 작동하도록 보장한다
도커 이미지는 프로그램을 실행하는데 필요한 설정이나 종속성을 갖고 있으며
도커 이미지를 이용해서 컨테이너를 생성하며, 도커 컨테이너를 이용하여 프로그램을 실행한다.
📍 하이퍼 바이저 기반의 가상화 출현
- 가상화 기술 나오기 전: 한대의 서버를 하나의 용도로만 사용/남는 서버 공간은 그대로 방치하면서 하나의 서버에 하나의 운영체제, 하나의 프로그램만을 운영 -> 안정적 but 비효율적
- 하이퍼 바이저 기반의 가상화 출현: 논리적으로 공간을 분할하여 VM이라는 독립적인 가상 환경의 서버 이용 가능. 하이퍼 바이저는 호스트 시스템에서 다수의 게스트 OS를 구동할 수 있게 하는 소프트웨어, 그리고 하드웨어를 가상화하면서 하드웨어와 각각의 VM을 모니터링하는 중간 관리자
하이퍼 바이저
1. 네이티브 하이퍼 바이저
하이퍼 바이저가 하드웨어를 직접 제어하기에 자원 효율적으로 사용 가능하며, 별도의 호스트 OS가 없으므로 오버헤드가 적다.
하지만 여러 하드웨어 드라이버를 세팅해야 하므로 설치 어렵다.
2. 호스트형 하이퍼 바이저
일반적인 소프트웨어처럼 호스트 OS 위에서 실행되며, 하드웨어 자원을 VM 내부의 게스트 OS에 에뮬레이트 하는 방식으로 오버헤드가 크다. 하지만 게스트 OS 종류에 대한 제약이 없고 구현이 다소 쉽다. (일반적으로 많이 이용하는 방법)
하이퍼바이저에 의해 구동되는 VM은 각 VM마다 독립된 가상 하드웨어 자원을 할당받는다.
논리적으로 분리 되어 있어서 한 VM에 오류가 발생해도 다른 VM으로 퍼지지 않는다는 장점
공통점-> 도커 컨테이너와 가상머신은 기본 하드웨어에서 격리된 환경 내에 애플리케이션을 배치하는 방법
차이점-> 가장 큰 차이점은 격리된 환경을 얼마나 격리를 시키는지의 차이
VM과 비교했을 때 컨테이너는 하이퍼바이저와 게스트 OS가 필요하지 않으므로 더 가볍다. 어플리케이션을 실행할 때는 컨테이너 방식에서는 호스트 OS 위에 어플리케이션의 실행 패키지인 이미지를 배포하기만 하면 되는데 VM은 어플리케이션을 실행 하기 위해서 VM을 띄우고 자원을 할당한 다음, 게스트 OS를 부팅하여 어플리케이션을 실행
리눅스에서 쓰이는 Cgroup(control groups), 네임스페이스(namespaces)
- C Group: CPU, 메모리, Network Bandwith, HD i/o 등 프로세스 그룹의 시스템 리소스 사용량을 관리 -> 어떤 어플이 사용량이 너무 많다면 그 어플리케이션 같은 것을 C group에 집어 넣어서 CPU와 메모리 사용 제한 가능
- 네임스페이스: 하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술. 별개의 독립된 공간을 사용하는 것처럼 격리된 환경을 제공하는 경량 프로세스 가상화 기술
이미지 설명
1. CONTAINER ID: 컨테이너의 고유한 아이디 해쉬값. 실제로는 더욱 길지만 일부분만 표출
2. IMAGE: 컨테이너 생성시 사용한 도커 이미지
3. COMMAND: 컨테이너 시작시 실행될 명령어
4. CREATED: 컨테이너가 생성된 시간
5. STATUS: 컨테이너의 상태. 실행중은 Up, 종료는 Exited, 일시정지 Pause
6. PORTS: 컨테이너가 개방한 포트와 호스트에 연결한 포트 특별한 설정을 하지 않은 경우 출력되지 않는다.
7. NAMES: 컨테이너 고유한 이름. 컨테이너 생성시 --name 옵션으로 이름을 설정하지 않으면 도커 엔진이 임의로 형용사와 명사를 조합해 설정. id와 마찬가지로 중복이 안되고 docker rename 명령어로 이름을 변경할 수 있다.
docker rename original-name changed-name
모든 컨테이너 나열 docker ps -a
📍도커 생명주기
생성(create) -> 시작(start) -> 실행(running) -> 중지(stopped) -> 삭제(deleted)
docker create <이미지>
docker start <시작할 컨테이너 아이디/이름>
docker stop <중지할 컨테이너 아이디/이름>
docker rm <삭제할 컨테이너 아이디/이름>
- docker run <이미지 이름>으로 컨테이너 생성 실행했는데, 이걸 docker create과 docker run으로 쪼갤 수 있음
- docker stop과 docker kill로 중지할 수 있음
📍 stop과 kill
공통점은 둘다 실행중인 컨테이너를 중지시킴
하지만 stop은 자비롭게 그동안 하던 작업들을 (메시지를 보내고 있었다면 보내고 있던 메시지) 완료하고 컨테이너를 중지시키고,
kill은 stop과 달리 어떠한 것도 기다리지 않고 바로 컨테이너를 중지시킨다
📍 rm
- 중지된 컨테이너를 삭제하고 싶다면? docker rm <아이디/이름> : 실행중인 컨테이너는 먼저 중지한 후에 삭제 가능
- 모든 컨테이너를 삭제하고 싶다면? docker rm 'docker ps -a -q'
- 이미지를 삭제하고 싶다면? docker rmi <이미지 id>
- 한번에 컨테이너, 이미지, 네트워크 모두 삭제하고 싶다면? docker system prune : 이것도 실행중인 컨테이너에는 영향을 주지 않음
📍 exec
docker run은 새로 컨테이너를 만들어서 실행
docker exec은 이미 실행중인 컨테이너에 명령어를 전달
컨테이너를 쉘 환경으로 접근해보기
1. 먼저 첫번째 터미널을 실행한 후, alpine 이미지를 이용해서 컨테이너를 실행
docker run alpine ping localhost
2. 그 후 exec을 이용하고 마지막 명령어 부분에 sh를 입력후 컨테이너 안에서 텉미널 환경을 구축
docker exec -it 컨테이너 아이디 sh
3. 그 안에서 여러가지 터미널에서 원래 할 수 있는 작동들을 해본다
ex)
ls: 컨테이너 디렉토리에 있는 내용(디렉토리, 파일) 확인
touch new-file: 파일 생성
export hello=hi echo $hello: 변수 생성 출력