도커 이미지와 컨테이너
: 가장 기본 단위이자, 도커 엔진의 핵심 두가지.
- 이미지: 여러 계층으로 된 바이너리이며 읽기 전용으로 불변이다.
{저장소이름}/{이미지이름}/{태그}
형태
- 컨테이너: 이미지를 실행한 형태. 이미지의 종류에 따라 알맞은 설정과 파일을 갖는다.
도커 컨테이너
: 도커 이미지 위에 얇은 컨테이너 레이어를 생성하면서 인스턴스가 된다.
docker run
을 통해 컨테이너를 생성하고 실행한다.-i
(상호입출력),-t
(tty 활성화) 옵션을 주면 생성과 동시에 컨테이너 내부로 들어간다. (==attach
명령어)run
=create
+start
- 명령어 끝에 COMMAND를 입력할 수 있다. 이 경우 이미지에 내장된 커멘드를 덮어쓴다.
- 우분투 이미지에
echo ~~
커맨드를 주면, 내장 커맨드인/bin/bash
를 덮어쓰기 때문에 커맨드를 실행하고 컨테이너가 종료되는 모습을 볼 수 있다.
- 우분투 이미지에
-p
: 포트를 지정한다. 옵션을 통해 포트바인딩이 가능하다. 예를 들어,-p 80:8080
과 같은형태는 80의 호스트 포트와 컨테이너 내부의 8080포트를 바인딩한다.-d
:detached
모드로 컨테이너 실행 -> 이 경우 별도의 사용자 입력 없이 컨테이너 내의 프로그램이 포그라운드로 실행된다. 따라서, 별도의 포그라운드 프로그램이 없으면 컨테이너는 종료된다.- 우분투 컨테이너에서 exit으로 컨테이너를 나가면 포그라운드이던
/bin/bash
가 종료되므로 컨테이너가 종료되는 것. - mysql을 attached 모드로 실행하면 포그라운드로 동작하는 로그를 확인할 수 있다. 이 때
exit
으로 빠져나와도 포그라운드 프로그램이 존재하기 때문에 컨테이너는 유지된다.
- 우분투 컨테이너에서 exit으로 컨테이너를 나가면 포그라운드이던
--link
: 다른 서비스에 서비스명만으로 접근할 수 있다.
ps
,stop
,rm
등등 다양한 명령어와 옵션을 익혀야한다.- 도커의 철학: 한 컨테이너당 한 프로세스. 컴포넌트간 독립성을 유지할 수 있고, 버전관리와 모듈화가 용이해진다.
tty?
- 텔레타입 라이터: 과거의 전신기. 메시지 타이핑을 통한 입력장치로 사용되었는데, 이러한 유래로 현대에서도 일반적으로 Unix 체계에서의 터미널을 의미.
- 터미널에서
tty
를 입력하면 현재 커널과 연결된 가상 터미널장치를 확인 가능하다. 탭이나 화면을 분리해서tty
를 입력해보면 각각이 다른 터미널 장치와 연결되는 것을 볼 수 있다.
foreground, background
: 앞과 뒤에서 실행되는 프로세스들.
- 터미널에서
vi
를 실행하거나htop
을 통해 모니터링을 하다가ctrl + z
를 누르면 해당 프로세스들을 백그라운드로 보내고 포그라운드(터미널)로 돌아간다. - 이 때
fg
를 통해 다시 가장 최근의 백그라운드 프로세스를 포그라운드로 불러올 수 있고,jobs
를 통해 목록을 확인 할 수 있다.
도커 볼륨
: stateful한 컨테이너는 종료되면 내부의 변경 사항들 또한 유실되는데, 이 변경 사항들을 유지하기 위해 볼륨을 사용한다. 따라서 컨테이너는 stateless한 컨테이너가 된다.
- 호스트 볼륨 공유:
{호스트의 공유 디렉터리}:{컨테이너의 공유 디렉터리}
의 형태로 볼륨을 맵핑해준다.- e.g.
/home/wordpress_db:/var/lib/mysql
로 볼륨을 지정해주면 컨테이너 종료 후에도, 컨테이너의/var/lib/mysql
디렉터리 변경사항이 호스트의/home/wordpress_db
에 반영되어있다. - 마운트: 경로가 겹친다면 호스트의 디렉터리를 컨테이너의 디렉터리에 덮어씌운다.
- e.g.
- 볼륨 컨테이너:
--volumes-from
옵션을 설정하면 이미-v
옵션이 설정되어있는 다른 컨테이너의 볼륨을 공유받을 수 있다. - 도커 볼륨:
docker volume
명령을 사용해, 도커 엔진이 볼륨을 관리하도록 한다.{볼륨 이름}/{컨테이너의 공유 디렉터리}
형태로 볼륨을 맵핑해준다.- 호스트 머신의 특정 경로 (
/var/lib/docker/volumes
) 경로에서 확인 가능하다. 이 경로는 볼륨을 inspect해보면 알 수 있다.
- 호스트 머신의 특정 경로 (
도커 네트워크
- 외부에서 컨테이너와 통신하기 위해 도커 엔진은 컨테이너마다
veth
(virtual eth 네트워크 인터페이스),docker0
브릿지를 호스트에 생성한다. 이docker0
를 이용하거나 네트워크 드라이버를 이용하면 된다.- 컨테이너 내부에서
ifconfig
를 입력해보면eth0
(외부와 통신할 수 있는 네트워크 인터페이스),lo
네트워크 인터페이스를 확인할 수 있다. docker0
브리지 네트워크는172.17.0.x
IP 대역을 차례대로 할당한다.
- 컨테이너 내부에서
- 네트워크 드라이버: 브리지, 호스트, 논, 컨테이너
브리지
- 기본적으로 컨테이너 생성 시 자동으로 연결되는
docker0
브리지를 활용하도록 설정되어있다. docker network connect, disconnect
를 통해 컨테이너에 수동적으로 붙이고 뗄 수 있다.--net-alias
: 특정 호스트 이름에 여러 컨테이너를 붙인다. 이 때 RR 방식으로 각 컨테이너에 LB된다.--link
옵션과 비슷하다. 내장 DNS 서버를 통해 가능하다.
호스트
: 호스트의 네트워크환경 그대로 사용한다. 이 경우 컨테이너 내부의 애플리케이션을 별도 포트포워딩 없이 그대로 사용 가능하다.
논
: 외부와 연결이 단절된다.
컨테이너
--net container:{container_id}
옵션을 통해 다른 컨테이너 네트워크 환경을 그대로 공유한다.- 컨테이너 간 리눅스 네트워크 네임스페이스를 공유하도록 해 동일한 네트워크 환경을 갖게 되기 때문에 가능하다. k8s에서 파드 내 메인과 사이드카 컨테이너 간에도 리눅스 네임스페이스를 공유해, 별도 설정 없이 통신이 가능하다.
컨테이너 로깅
- 도커는 컨테이너의
stdOut
과stdErr
를 별도 호스트 머신에 메타데이터 파일로 저장한다.docker logs
로 확인 가능하다.- 컨테이너를 inspect해보면 LogPath를 확인 할 수 있다.
- 로그 수집을 위한 드라이버들이 존재한다.
- syslog: 로그를 보낼 서버에
rsyslog
컨테이너를 띄워 내부의 설정을 해둔 뒤, 클라이언트 호스트에서syslog
로 보내는 방법이 가능하다. - fluentd: JSON 포맷을 지원하며, AWS S3, HDFS, Mongodb 등 다양한 저장소에 저장할 수 있는 오픈소스 도구이다.
- conf로 fluentd 설정을 해야한다. match를 통해 태그별로 설정을 다르게 가져갈 수 있다.
- syslog: 로그를 보낼 서버에
자원 할당 제한
- 컨테이너를
inspect
해보면 Quota 등 리소스를 확인할 수 있다. 자원 할당 제한이란 메모리, CPU 등 리소스를 정해두어, 호스트에 문제가 발생하는 일이 없도록 한다. - 컨테이너 내
ps aux
명령어를 통해 할당된 리소스 확인이 가능하다.
Reference)
시작하세요! 도커 / 쿠버네티스