많은 소프트웨어 기업에서는 Docker
를 사용하며, Docker는 차세대를 위한 기술이며, 서버개발자는 필수로 배워야하는 자격요건에 Docker는 항상 있다. Docker가 가상화 기술
이라는 건 알았지만, 대체 도커가 뭘까?
이번 포스팅에서는 Docker의 개념에 대해 알아보고 도커 이용해 웹 컨테이너를 만들어봅시다
Docker란 무엇인가? 데이터 또는 프로그램을 격리시키는 기능을 제공하는 소프트웨어이다.
Docker는 주로 서버에서 사용하는 것이 주 용도이다.
도커는 다양한 프로그램과 데이터를 각각 독립된 환경
에 격리하는 기능을 제공한다. 도커에서의 핵심은 프로그램 격리(isolation)
이라고 한다.
당신은 유지보수를 해본적이 있던가? 회사에 입사하여 유지보수를 시작하면 당신은 프로그램이 얼마나 빠르게 업그레이드되는지 알것이다. 그리고 현재 프로젝트는 얼마나 구닥다리인지도 알것이다.
나는 유지보수를 하면서
nodeJS
지옥을 맛보았다. 내가본 nodeJS는 업데이트 속도가 매우빠르고 호환성이 좋지 않다.. 그래서 버전을 잘못 설치하면 프로그램이 돌아가지 않는다. 근데 또 nodeJS 프로그램은 한 개 밖에 못깔지 아주 미치는 꼴을 보게될것이다.이때 내가 도커를 알았다면 얼마나 좋았을까?
이런 환경에서 도커 컨테이너로 환경을 구성하면 된다. docker container 내부의 프로그램은 다른 외부/컨테이너에 영향을 미치지 않기 때문에 환경마다 다른 프로그램을 설치할 수 있다.
💡 용어 정리
Docker Engine
컨테이너를 생성하고 구동컨테이너
각각 독립된 환경이미지
컨테이너를 만들기 위해서는 이미지(snapshot)일반적으로 Docker는 리눅스
환경 위에서 동작한다.
윈도우나 macOS에서는 VMWare
/VirtualBox
등 가상환경 위에서 리눅스 OS
를 설치하고 그 위에 도커를 실행하거나
'윈도우 또는 macOS용 도커 데스크톱
'처럼 도커를 실행하는 데 필요한 리눅스 운영체제를 포함한 패키지를 설치해 사용한다.
컨테이너는 외부와 완전히 분리돼 있으므로 컨테이너 속에 운영체제의 주변 부분이 따로 들어있다.
일반적인 컴퓨터: 하드웨어
⇔ 운영체제(커널)
⇔ 운영체제 주변부분
⇔ 소프트웨어
도커: 하드웨어
⇔ 운영체제(커널)
⇔ 도커 엔진
⇔ 컨테이너
+ 운영체제 주변부분
⇔ 소프트웨어
도커 허브란? 공식적으로 운영되는 도커 레지스트리
(도커 이미지를 배포하는 서비스)를 의미한다.
도커 허브
에는 공개된 컨테이너 이미지가 모여있다. 누구든지 이미지를 등록하고 공개할 수 있다. (아이디만 있다면) ex) 리눅스 배포판
안전한 도커 이미지를 선택하기 위해서는 공식 이미지
를 사용하거나 커스텀 이미지
를 직접 만들어 사용한다.
자, Docker의 개념에 대해 정리해보면 docker
의 핵심은 Docker Engine
이고, Docker Engine은 Container
를 관리한다. 그리고 Container는 각각 독립된 환경
을 의미한다.
Docker Engine은 Container를 관리하기 위해 명령어(Command)
를 제공한다.
그리고 그 명령어는 docker로 시작한다.
$ docker 커맨드 (옵션) 대상 (인자)
도커 커맨드는 상위 커맨드
와 하위 커맨드
가 있다. 상위 커맨드는 때때로 생략 가능하다.
우선 시작에 앞서, 가장 기본적인 명령어를 쳐보자.
명령어 중에 가장 기본은 version을 확인하는 것 아니겠는가? 아래 명령어를 입력해보자.
$ docker version
이제부터 도커의 명령어들을 알아보자
컨테이너
조작 관련 커맨드이다. 컨테이너를 실행하거나 종료하고, 컨테이너 목록을 확인하는 등 컨테이너를 다루기 위해 사용하는 커맨드이다.
컨테이너
는 각각의 독립된 환경
을 의미한다.
하위 커맨드 | 내용 | 생략 가능 여부 | 주요옵션 |
---|---|---|---|
start | 컨테이너 실행 | O | -i |
stop | 컨테이너 정지 | O | X |
create | 도커 이미지로부터 컨테이너를 생성 | O | --name 컨테이너명 -e -p 포트 -v 볼륨명 |
run | 도커 이미지를 내려받고(docker image pull) 컨테이너를 생성해(docker create) 컨테이너를 실행(docker start)하는 삼합체이다. | O | [create 옵션] --net -d -i -t |
rm | 정지 상태의 컨테이너를 삭제 | O | -f -v |
exec | 실행 중인 컨테이너 속에서 프로그램을 실행 | O | -i -t |
ls | 컨테이너 목록 실행 | *1 | -a |
cp | 도커 컨테이너와 도커 호스트 간에 파일을 복사 | O | X |
commit | 도커 컨테이너를 이미지로 변환 | O | X |
*1
생략형은 docker ps
🤞 docker start
: 도커 컨테이너 시작
$ docker start [컨테이너명]
🤞 docker stop
: 도커 컨테이너 정지
$ docker stop [컨테이너명]
🤞 docker create
: 도커 이미지로 컨테이너를 생성
$ docker create --name [컨테이너명] -e [환경변수 목록] -p [호스트포트:포트] -v 볼륨명 or [호스트경로:경로]
🤞 docker run
: 도커 레지스트리나 로컬에서 도커 이미지를 받아와서(docker pull
) 컨테이너를 생성(docker create
)하고 실행(docker start
)
$ docker run --name [컨테이너명] -e [환경변수 목록]
-p [호스트포트:포트] -v [볼륨명 | 호스트경로:경로] --net=[네트워크명] -d -it
--restart [no|on-failure|unless-stopped|always] [이미지명]
# 예시
$ docker run --name web -p 80:80 -d httpd
🤞 docker rm
: 컨테이너를 삭제한다.
$ docker rm -f -v [컨테이너명]
$ docker rm -f web
🤞 docker exec
: 컨테이너에 접속
$ docker exec [컨테이너명]
$ docker exec --it web bash
🤞 docker cp
: 호스트와 컨테이너간 파일을 주고 받는다.
$ docker cp [호스트 파일경로] [컨테이너명]:[컨테이너 내부 경로]
$ docker cp index.html web:/usr/local/apache2/htdocs/
🤞 docker commit
: 현재 컨테이너를 이미지로 저장한다.
$ docker commit [컨테이너명] [이미지명:태그명]
$ docker commit web web:0.0.1
도커 이미지
를 내려받거나 검색하는 등 이미지와 관련된 기능을 실행하는 커맨드다.
도커의 이미지
는 컨테이너를 구성하는 뼈대(bone)
이다. 일반적으로 OS를 설치할 때 OS 이미지 파일(iso)
이 필요한 것과 유사하다고 볼수 있다.
하위 커맨드 | 내용 | 생략 가능 여부 | 주요옵션 |
---|---|---|---|
pull | 도커 허브 등의 리포지토리에서 이미지를 내려받음 | O | X |
rm | 도커 이미지 삭제 | *2 | X |
ls | 내려 받은 이미지의 목록을 출력 | *3 | X |
build | Dockerfile로 부터 도커 이미지 생성 | O | -t |
*2
생략형은 docker rmi
*3
생략형은 docker images
🤞 docker pull
$ docker image pull [이미지명: 태그명]
$ docker pull [이미지명:태그명]
$ docker pull httpd
$ docker pull ubuntu:18.04
🤞 docker image rm
, docker rmi
$ docker image rm [이미지명: 태그명]
$ docker rmi [이미지명:태그명]
$ docker rmi httpd
🤞 docker image ls
, docker images
$ docker image ls
$ docker images
🤞 docker build
⇒ Dockerfile
이 있는 폴더의 상위폴더에서 이 명령을 수행한다. Dockerfile
이 있는 폴더의 내용은 빌드시 컨테이너에 같이 포함된다.
$ docker image build [Dockerfile이 있는 폴더]
$ docker build [Dockerfile이 있는 폴더]
$ docker build ./docker_folder
볼륨 생성, 목록 확인, 삭제 등 볼륨과 관련된 기능을 실행하는 커맨드다.
볼륨
이란, 컨테이너에 마운트
가능한 스토리지
를 의미한다. 여기서의 볼륨 명령어는 도커 엔진
이 관리하는 논리적 영역의 스토리지이다.
실제, 컨테이너를 생성할때는 -v
옵션을 통해 볼륨에 마운트할 수 있는데, 이때 이 볼륨에는 도커 엔진이 관리하는 영역의 볼륨
이나 실제 호스트 경로
를 마운트할 수 있다.
Topic. Volume을 지정하는 이유
볼륨을 지정하는 이유는 컨테이너는 쉽게
생성
되고폐기
되기 때문에, 데이터를 안전하게 관리하기 위해서 사용된다.
docker rm
명령어 사용하여 컨테이너 폐기시, 옵션-v
를 넣지 않으면 볼륨은 사라지지 않는다.
하위 커맨드 | 내용 | 생략 가능 여부 | 주요옵션 |
---|---|---|---|
create | 볼륨 생성 | X | --name |
inspect | 볼륨의 상세 정보를 출력 | X | X |
ls | 볼륨 모두 출력 | X | -a |
prune | 현재 마운트되지않은 볼륨 모두 삭제 | X | X |
rm | 지정한 볼륨 삭제 | X | X |
🤞 docker volume create [볼륨명]
: 볼륨을 생성한다.
$ docker volume create web_vol
🤞 docker volume ls
: 볼륨 목록을 출력한다
$ docker volume ls
# 실행 결과
DRIVER VOLUME NAME
local web_vol
🤞 docker volume inspect [볼륨명]
: 볼륨의 상세정보를 확인한다.
$ docker volume inspect web_vol
# 실행 결과
[
{
"CreatedAt": "2023-02-07T09:26:07+09:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/web_vol/_data",
"Name": "web_vol",
"Options": {},
"Scope": "local"
}
]
🤞 docker volume rm [볼륨명]
: 지정한 볼륨을 삭제한다.
$ docker volume rm web_vol
web_vol
$ docker volume ls
DRIVER VOLUME NAME
🤞 docker volume prune
: 컨테이너
에 마운트
되지 않은 볼륨을 모두 삭제
한다.
$ docker volume prune
# 실행 결과
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
web_vol
Total reclaimed space: 0B
도커 네트워크
의 생성, 삭제 컨테이너의 네트워크 접속 및 접속 해제 등 도커 네트워크와 관련된 기능을 실행하는 커맨드다.
관리할 수 있는 영역(create, rm, ls 등)의 도커 네트워크
은 도커 엔진
이 관리하는 일종의 컨테이너의 묶음, 즉 논리적 네트워크
이라고 할 수 있겠다.
하위 커맨드 | 내용 | 생략 가능 여부 | 주요옵션 |
---|---|---|---|
connect | 컨테이너를 도커 네트워크에 연결 | X | X |
disconnect | 컨테이너의 도커 네트워크 연결을 해제 | X | X |
create | 도커 네트워크 생성 | X | X |
inspect | 도커 네트워크의 상세 정보를 출력 | X | X |
ls | 도커 네트워크 목록 출력 | X | X |
prune | 현재 컨테이너가 접속하지 않은 네트워크 모두 삭제 | X | X |
rm | 지정한 도커 네트워크 삭제 | X | X |
🤞 docker network ls
: 네트워크 목록을 검색한다.
$ docker network ls
# 실행 결과
NETWORK ID NAME DRIVER SCOPE
a398b520e819 bridge bridge local
1ba123abbb61 host host local
eed17555d205 none null local
🤞 docker network create [네트워크명]
: 네트워크 추가.
⇒ docker network
를 생성하면 bridge 형태
로 네트워크(컨테이너 간 결합)에 연결된다.
$ docker network create program_net
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
a398b520e819 bridge bridge local
1ba123abbb61 host host local
eed17555d205 none null local
067141e89138 program_net bridge local
🤞 docker network rm [네트워크명]
: 네트워크 삭제.
$ docker network rm program_net
🤞 docker network inspect [네트워크명]
: 네트워크 상세정보 출력.
$ docker network inspect program_net
# 실행 결과
[
{
"Name": "program_net",
"Id": "814675051bc831da182d443aa9c4b9b4786e585d8ff555eb9d353c50db703810",
"Created": "2023-02-07T11:34:51.37797693+09:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
🤞 docker network prune
: 사용하지 않는 네트워크 모두 삭제.
$ docker network prune
# 실행 결과
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Networks:
program_net
Docker는 기본적으로 3개
의 네트워크
를 지원합니다 .
이 모드 는 컨테이너 에 대한 IP를 구성 하지 않으며 다른 컨테이너뿐만 아니라 외부 네트워크에 대한 액세스 권한도 없습니다 . 루프백 주소가 있으며 배치 작업을 실행하는 데 사용할 수 있습니다.
$ docker run -it --network=none ubuntu:14.04 /bin/bash
$ ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
$ docker inspect 66308c6686be | grep -i ipaddr
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "",
이 모드에서 컨테이너는 호스트
의 네트워크 스택
을 공유
하고 호스트의 모든 인터페이스를 컨테이너에서 사용할 수 있습니다 . 컨테이너와 호스트는 호스트명
및 IP 구성
등이 일치합니다.
호스트 및 없음 모드에서는 직접 구성되지 않지만 기본 브리지 네트워크
를 구성하고 고유한 사용자 정의 브리지 네트워크를 만들 수 있습니다.
호스트 시스템의 다른 인터페이스와 컨테이너 간 연결을 가능하게 하는 Docker 기본 네트워킹 모드 입니다.
브리지 모드에서는 다른 컨테이너에 대한 액세스가 가능합니다.
상위 커맨드 없이 단독으로 쓰이는 특수한 커맨드이다. 주로 도커 허브와 관련된 명령어이다.
단독 커맨드 | 내용 | 주요옵션 |
---|---|---|
login | 도커 레지스트리에 로그인 | -u -p |
logout | 도커 레지스트리에 로그아웃 | x |
search | 도커 레지스트리 검색 | x |
version | 도커 엔진 및 명령행 도구의 버전을 출력 | x |
linux에서 Docker 설정은 (Windows/macOS랑 달리) 매우 매우 간단하다. Install command를 통해 도커를 설치하기만 하면 된다.
# Docker 설치
$ sudo apt install docker.io
# 권한 부여 (sudo 없이 도커 명령어 가능)
$ chmod 666 /var/run/docker.sock
웹 서버 container 만들기를 실습한다. 나는 이 실습을 통해 도커를 한방에 이해했다.
http://localhost:3000 으로 동작하는 간단한 Container 를 만든다
# docker container 생성 및 실행
$ docker run [--name container_이름] [-d] [-p 호스트_포트:포트] {컨테이너_이미지명}
$ docker run --name web -d -p 3000:80 httpd
# 현재 실행 중인 Container 목록 확인
$ docker ps [-a]
# 결과
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f4c242bde74 httpd "httpd-foreground" 11 minutes ago Up 11 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp web
이제 해당 브라우저에서 3000번으로 접속한다.
이번 포스팅에서는 도커의 개념과 명령어, 간단한 실습을 해보았습니다. 다음 포스팅에서는 도커 컨테이너 관리에 대해 포스팅 해보겠습니다.
덧붙여, 도커를 공부하면서 여러가지 생각이 들었습니다.
그림과 실습으로 배우는 도커 & 쿠버네티스
이 책은 정말 최고의 자습서이다.러닝커브
가 낮은거 같다. (정말 내 기준일수도?)나는 이렇다. (내기준)
git 커맨드
서버
에 대한 이해가 있다 (실제 서비스되는 웹 서버
를 구성해본 적이 있다)