Docker의 기능, CLI

Docker 핵심 키워드

컨테이너

애플리케이션이 의존성, 네트워크 환경, 파일 시스템에 구애받지 않고, 도커라는 기술 위에 실행될 수 있도록 만든 애플리케이션 상자


이미지

실행되는 모든 컨테이너는 이미지로부터 생성 됨.

이미지는 애플리케이션 및 애플리케이션 및 애플리케이션 구성을 함께 담은 템플릿으로, 이를 사용해서 컨테이너 생성.

이미지를 이용해 여러 개의 컨테이너를 생성 → 애플리케이션 수평 확장이 가능.

이미지는 기본 이미지(base image)로부터 변경 사항을 추가/커밋하여 다른 이미지를 만들 수 있다.

⇒ [ex] node.js로 작성된 애플리케이션을 이미지로 만들고 싶은 경우에 node.js 이미지를 기본 이미지로 삼고 내가 만든 애플리케이션을 추가하여 이미지화.


레지스트리

이미지는 레지스트리에 저장됨. 대표적인 이미지 레지스트리는 Docker Hub, Amazon ECR. 도커 CLI에서 이미지를 이용해 컨테이너 생성 시, 호스트 컴퓨터에 이미지가 존재하지 않으면 기본 레지스트리로부터 다운로드 받음.



Docker?

도커(Docker)는 리눅스 컨테이너(Linux Container) 기술을 기반으로 하는 오픈 소스 서비스. 도커를 통해

  • 애플리케이션 실행 환경을 코드로 작성할 수 있음
  • OS를 격리화하여 관리

Linux Container?

→ 가상 머신과 비슷해 보이지만 다른 기술임.



Docker 기능

C1 - 환경 표준화

대표적 운영체제(OS)로 Linux, Windows, MacOs 등. 엔지니어는 개발 애플리케이션이 어떤 환경에서 구동될지, 개발한 애플리케이션을 구동하는 운영체제에 따라 달리 변경해야할 부분이 발생. (예로 윈도우의 애플리케이션 경로는 백슬래시( \ )를 폴더로 표현, Mac과 Linux 경로는 슬래시( / )를 폴더로 표현함)


C2 - 수작업으로 일치시키는 환경 구성

모든 개발자와 사용자가 동일한 OS 환경에서 애플리케이션을 구동한다면, 애플리케이션 환경 구성이 빨라질 수는 있으나 각 로컬 컴퓨터마다 환경 변수 설정이 다르게 설정되는 등의 경우가 있음. 로컬 PC에 설정된 값이 모두 동일할 수 없기 때문에 애플리케이션을 설치할 때 컴퓨터의 환경을 고려하여 변경할 부분이 있다. 방화벽 설정, 사용자 권한 설정, Port 설정 등…

→ 개발과 실행 환경에 대한 환경 설정이 코드로 정해져 있다면 ?


C3 - 리소스 격리성

*[ ex.

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

서버 관리자에게 입력된 요구사항일 때, 포트 번호로 프로세스(프로그램 실행)를 식별한다. 그러나, 서버가 하나밖에 없어 IP 주소를 구분하기 위해 브릿지 설정을 변경, 방화벽 규칙 a와 b가 서로 충돌이 일어나고 있음. ]

실제로는 하나의 컴퓨터로 여러 대의 컴퓨터를 이용하는 것처럼 사용하는 방법을 “리소스 격리성” 이라고 한다. 리소스 격리성을 제공하는 기술로 가상 머신(virtual machine), 도커가 있다.

⇒ OS와 환경을 일치시키기 위해 가상 머신을 이용. VirtualBox, VMware와 같은 가상 머신은 개발 환경이나 사용 환경을 이미지로 저장하고, Host OS 위에 게스트 OS를 올리는 방식이다.

⇒ 가상 머신과 도커는 격리성을 제공하여, 각 애플리케이션마다 다른 컴퓨터에서 실행되는 것처럼 IP와 Port 등을 다르게 설정할 수 있다.


도커와 가상 머신의 차이?

  • 도커는 가상 머신만큼 견고한 격리성을 제공하지 않음.
  • 도커는 리눅스의 컨테이너(Linux Container)를 이용한 기술이라 OS 위에 타 OS를 실행하는 가상 머신보다 좋은 성능을 낼 수 있음.
  • 애플리케이션에 대한 환경 격리성을 중심으로 한 VM과 다르게 도커는 Container의 관점에서 개발자와 사용자 커뮤니키를 중심으로 혜택을 제공함.

Docker Container Lifecycle 도식화

→ 도커 컨테이너의 독립적인 특징 기반 Lifecycle. 컨테이너의 생성, 실행, 종료의 과정.



Docker CLI(Command Line Interface)

Docker Image 및 Container를 다루기 위한 Docker Command Line 명령어.

docker container run

  • 사용법 : Docker CLI, Docker-Compose CLI, API Reference
  • 환경 및 빌드 파일 구성 : DockerFile, Docker-Compose File

도커(Docker Command Line Interface)

*Docker docs : docker container run

터미널에서 명령을 실행합니다.

  • docker image pull
  • docker image ls
  • docker image rm
  • docker container run
  • docker container ls
  • docker container rm

1
2
3
4
5
6
7
8
9
10
11
12
# 레지스트리에서 이미지 혹은 레퍼지토리를 가져온다 (pull)
docker {image} pull

# 이미지 리스트 출력, 용량 확인
docker image ls

## 받아온 이미지 실행 (이미지 -> 컨테이너)
# 컨테이너_이름을 이름으로 갖는 컨테이너 실행
docker contianer run --name 컨테이너_이름 docker/whalesay: latest cowsay

# docker/whalesay 이미지 삭제
docker image rm docker/whalesay

docker container run 사용

docker container run

  • docker container run [OPTIONS] IMAGE [COMMAND] [ARG…]
    • {container} run
      • 컨테이너를 실행
    • [OPTIONS]
      • —name : 컨테이너의 이름 할당
    • [COMMAND]
      • 초기 컨테이너 실행시 수행되는 명령어
      • cowsay : 컨테이너 실행시 cowsay 명령어 호출
    • [ARG…]
      • boo : COMMAND인 cowsay에 넘겨질 파라미터

1
2
3
4
5
6
# 모든 컨테이너의 리스트 출력
docker container ps -a

# 컨테이너_이름이라는 이름의 컨테이너를 삭제
docker container rm 컨테이너_이름
docker rmi
  • {container} ps : 컨테이너 리스트 출력
    • -a : 실행되는 컨테이너와 종료된 컨테이너를 포함한 모든 컨테이너 출력
  • {container} rm : 컨테이너 지칭해서 삭제
    • NAMES / CONTAINER ID : ps 명령을 통해 확인하여 명시 후 삭제


1
2
3
4
5
6
## danielkraic 라는 사람이 올린 이미지 asciiquarium 를 실행
# danielkraic/asciiquarium 이미지 실행

docker container run -it --rm danielkraic/asciiquarium: latest

## container 종료 = ctrl + c
  • -it
    • -i, -t 를 동시에 사용한 옵션
    • 사용자컨테이너 간에 **인터렉션(**interaction)이 필요할 때 사용
    • 예제의 출력 화면을 지속적으로 보기 위해 사용
    • python 명령이 필요하거나 추가로 다른 입력 받을 때 이 옵션 지정
  • -p 옵션 (run -p)
    • 포트 포워딩 : 컨테이너 실행 시 포트 연결 옵션
    • 로컬 호스트의 포트와 컨테이너포트를 연결하는 옵션
    • 818포트가 로컬호스트의 포트, 80번은 컨테이너의 포트
  • -d 옵션
    • detch 옵션
    • 컨테이너를 백그라운드에서 실행하게 해줌
      • interactive 옵션으로 실행 → 명령의 결과가 콘솔에 표시
      • 백그라운드 모드로 실행 → 컨테이너의 ID가 콘솔에 표시
    • docker container logs : 백그라운드 프로세스 실행 확인
      • -t 옵션으로 타입스탬프 표현 가능
    • docker attach 컨테이너ID(컨테이너 이름)
      • 현재 호스트 OS 쉘의 표준 입출력을 실행 중인지 확인
  • -v 옵션
    • 볼륨 옵션
    • 호스트의 로컬 파일시스템컨테이너 파일시스템에 연결
    • docker run -v <host파일경로>:<container파일경로> <이미지>


exec : 명령어 실행

컨테이너에 명령어를 전달하여 실행시킴

1
2
3
4
5
6
7
8
# docker exec <컨테이너명> <명령어>
docker exec monad_apache pwd

# docker exec -it <컨테이너명> /bin/sh (본쉘)
# docker exec -it <컨테이너명> /bin/bash (bash쉘)
docker exec -it monad_apache /bin/bash

## 실행 후 monad_apache의 bash쉘에 지속적으로 명령어를 전달


docker container cp

docker container cp

1
docker container cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-


이미지 파일 생성하는 방식

docker contianer commit

container를 이미지 파일로 만들기

docker container commit

1
docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Dockerfile

docker image 빌드를 위한 파일

→ 문법으로 RUN, CMD, ENTRYPOINT

Dockerfile reference

1
2
3
4
5
6
7
## "."을 명령어에 꼭 포함해야 함
docker build .
# Dockerfile로 도커 이미지 파일을 생성한다

docker build --tag my_pacman:2.0 .
## --tag 는 name:tag 형식으로 이미지를 생성할 수 있음
# 지정한 경로에 있는 Dockerfile을 찾아서 빌드한다


도커 이용하기

→ 도커 이미지가 실행되면 도커 컨테이너가 됨



docker / whalesay 이미지 사용 예제

docker/whalesay는 레지스트리 계정, 레포지토리 이름, 태그 3가지 정보로 구성.

  • 레지스트리(Registry)
    • Docker Hub : https://hub.docker.com/
    • 도커 이미지를 관리하는 공간
    • 다른 것을 지정하지 않는다면, 도커 허브를 기본 레지스트리로 설정
    • 레지스트리는 Docker Hub, Private Docker Hub, 회사 내부용 레지스트리 등으로 구분
  • 레포지토리(Repository)
    • 레지스트리 내에 도커 이미지가 저장되는 공간
    • 이미지 이름이 사용되기도 함
    • GitHub의 레포지토리와 유사
  • 태그(Tag)
    • 같은 이미지라도 버전 별로 안의 내용이 조금씩 다를 수 있음
    • 해당 이미지를 설명하는 버전 정보를 주로 입력
    • 다른 것을 지정하지 않는다면 latest 태그를 붙인 이미지를 가져옴

*docker/whalesay:latest

→ Docker Hub 라는 레지스트리에서

→ docker 라는 유저가 등록한 whalesay 이미지 혹은 레포지토리에서

→ latest 태그를 가진 이미지


> Docker Hub : docker/whalesay

1
2
# docker/whalesay의 최신 이미지 받아오기
docker image pull docker/whalesay:latest



Copy, Dockerfile - Docker 컨테이너에 파일 복사

사용할 파일이 하나의 이미지에 구성되지 않았을 때,

: 게임 서버, 웹 서버사용할 도구도커 이미지에 모두 구성되어 있지 않는 경우

웹 서버도커 컨테이너로 실행

웹 서버구성하는 파일직접 만들거나 가져온 파일 구성

위 같은 경우의 장점

  • 서버에 문제가 생기는 것을 호스트와 별개로 파악 가능
  • 문제가 생긴 서버를 끄고, 공장 초기화 하듯 도커 이미지로 서버 재구동 가능

로컬에 있는 파일과 도커 이미지를 연결하는 방법

= CP(Copy), Docker Volume 기능 이용

  • CP(Copy) : 호스트와 컨테이너 사이에 파일을 복사(Copy)
  • Volume : 호스트와 컨테이너 사이에 공간을 마운트(Mount)
    • 마운트 : 저장 공간을 다른 장치에서 접근할 수 있도록 경로를 허용 → 마치 하나의 저장 공간을 이용하는 것처럼 보이게 하는 작업
    • 볼륨 :


httpd 웹 서버

httpd(http daemone) 도커 이미지

Apache HTTP Server를 실행할 수 있는 오픈소스 웹 서버 소프트웨어

/usr/local/apache2/htdocs/ 경로에 웹 서버 관련 파일 저장되어 있으면 해당 파일 기반으로 웹 서버가 실행되도록 함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# httpd 실행
docker container run --name 컨테이너_이름 -p 818:80 httpd

## 로컬호스트 818번 포트와 컨테이너 80번 포트 연결
## 127.0.0.1:818/localhost:818 접속, 웹 서버 작동 확인
## 새로운 터미널 창

# 로컬호스트 파일을 컨테이너에 전달
# 현재 폴더의 파일을 뒤 경로에 복사한다
docker container cp ./ 컨테이너_이름:/usr/local/apache2/htdocs/

## 컨테이너 실행 문제 원인 찾기
# 컨테이너 내부 터미널로 접속
docker exec -it 컨테이너_이름 bash
  • run -p 옵션 [포트포워딩]
    • 로컬 호스트의 포트컨테이너의 포트연결하는 옵션
    • 818포트가 로컬호스트의 포트, 80번은 컨테이너의 포트
  • httpd 는 일정 시간 연결 기록이 없으면, 서버 가동이 중지되므로, 실행 중인 도커 컨테이너가 중지되면 재실행
  • -d 옵션
    • 컨테이너를 백그라운드에서 실행하게 해줌


Docker 이미지 만들기

Docker Contianer를 이미지 파일로 변환시켜둘 때의 장점

  • 이전에 작업한 내용을 다시 수행하지 않아도 됨
  • 배포 및 관리가 유용

→ 이미지를 만드는 방식 두 가지


1. 구동한 Docker Container를 이미지로 만드는 방법

1
2
3
4
5
6
7
8
9
10
## docker container commit 명령어 이용
# 구동한 Docker Container를 commit 함
docker container commit 컨테이너_이름 my_pacman:1.0

# my_pacman:1.0 확인
docker images

## 생성된 이미지를 포트에서 웹 서버로 구동
# 900 포트에서 웹 서버로 이미지를 구동
docker run --name my_web2 -p 900:80 my_pacman:1.0

2. Docker Image 빌드를 위한 파일인 Dockerfile로 만드는 방법

  • Dockerfile 을 만들고, Dockerfile 대로 이미지를 build 하는 방법
  • Dockerfile은 이미지 파일의 설명서
  • Dockerfile로 이미지 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## COPY 구문
## 현재 경로에 있는 파일을 생성할 이미지 경로에 복사하는 명령의 소스 코드
# 베이스 이미지를 http:2.4로 사용한다
FROM http:2.4
# 호스트의 현재 경로에 있는 파일을 생성할 이미지에 복사한다
COPY ./ /usr/local/apache2/htdocs/

## docker build는 Dockerfile로 도커 이미지 파일 생성
# --tag는 name:tag 형식으로 이미지를 생성 가능
# 지정한 경로에 있는 Dockerfile을 찾아서 빌드한다
docker build --tag my_pacman:2.0 .

# 생성된 이미지를 이용해 901 포트에 웹 서버 구동
docker run --name my_web3 -p 901:80 my_pacman:2.0

## 로컬호스트 901 포트로 웹 서버 작동 확인