Docker 컨테이너 CLI
도커 이미지
컨테이너 생성 및 실행
$> docker run -i -t {이미지명} [시작 스크립트]
-i : iteractive
-t : tty
종료: 컨테이너 정지
$> exit
또는
ctrl + D
종료: 컨테이너는 계속 실행
ctrl + p, q
run은 아래를 합친것
1) 이미지 다운로드
$> docker pull {이미지명}
2) 컨테이너 생성
$> docker create -i -t --name {컨테이너명} {이미지명}
--name : 컨테이너 이름 설정
3) 컨테이너 실행
$> docker start {컨테이너명 | ID}
4) 컨테이너 접속
$> docker attach {컨테이너명 | ID}
run vs create
docker run: pull -> create -> start -> attach
docker create: pull -> create
도커 이미지 다운로드
$> docker pull {이미지명}
도커 이미지 목록 확인
$> docker images
컨테이너 생성 / 삭제
목록 확인
$> docker ps
$> docker ps --format "table {{.ID}}\t{{.Status}}\t{{.Image}}\t{{.Names}}"
--format : formatting
\t : tab
$> docker ps -a
-a : 정지된 컨테이너까지 모두
상태: Up(실행중) / Exited(종료)
컨테이너 정보 확인
$> docker inspect {컨테이너명}
ex) container id 확인: docker inspect mysql | grep "Id"
컨테이너 이름 변경
$> docker rename {현재명} {바꿀명}
컨테이너 정지
$> docker stop {컨테이너명 | ID}
컨테이너 삭제
$> docker rm {컨테이너명 | ID}
$> docker rm -f {컨테이너명 | ID}
-f : docker stop 없이 강제 삭제
중지된 모든 컨테이너 삭제
$> docker container prune
모든 컨테이너 ID를 나열하고 중지 & 삭제
$> docker stop $(docker ps -a -q)
$> docker rm $(docker ps -a -q)
-q : display ID only
컨테이너 포트
컨테이너는 기본적으로 172.17.0.x의 IP를 할당 받는다.
-> Docker for Mac만 호스트에서 컨테이너 IP로 접근 불가능
호스트와 컨테이너 포트 연결
$> docker run -i -t --name {컨테이너명} -p {[호스트IP:]호스트포트}:{컨테이너포트} {이미지명}
-p : port fowrading. 여러개 하려면 -p 여러번 해주면 된다.
ex) docker run -i -t -p 3306:3306 -p 192.168.0.100:7777:80 mysql
포트 포워딩 확인
$> docker port {컨테이너명}
결과 ex) 80tcp -> 0.0.0.0:32768
0.0.0.0은 호스트의 활용 가능한 모든 네트워크 인터페이스와 바인딩함을 의미.
컨테이너 백그라운드 모드
Example)
1. mysql 데몬을 실행해 보자
$> docker run -d --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress mysql:5.7
-d : detach mode(=background)
-e : 환경변수 설정
위를 실행해 보면 mysqld(데몬)가 foreground로 돌고 있어 attach 해봐야 mysql의 로그밖에 볼수 없다.
$> docker attach mysqldb
터미널 접속을 하고 싶으면 아래처럼 새로운 shell을 실행시켜 접속하자.
$> docker exec -it mysqldb /bin/bash
2. 위 mysql을 사용하는 wordpress 서버를 실행해 보자
$> docker run -d -e WORDPRESS_DB_PASSWORD=password --name wordpress --link wordpressdb:mysql -p 80 wordpress
--link : 다른 컨테이너로 접근. NAT IP로 할 수 있지만 내부 IP는 실행마다 바뀌기 때문에 alias로 하는게 좋음. wordpressdb:mysql -> wordpressdb 컨테이너를 wordpress 컨테어너에서는 mysql이란 이름으로 사용. (주의) link에 입력된 컨테이너가 실행중이 아니면 link 적용한 컨테이너도 실행 안됨. deprecated 되고 향후 bridge로 바뀔것.
3. 접근 되는지 확인해 보자
#> docker exec wordpress curl mysql:3306 --slient
볼륨
1. 호스트 볼륨 공유하기
mysql 실행
$> docker run -d --name wordpressdb_hostvolume -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -v /Users/tester/docker_volume:/var/lib/mysql mysql:5.7
-v [호스트 디렉토리]:[컨테이너 디렉토리] : 호스트의 디렉터리를 컨테이너의 디렉토리로 마운트(복사아님). 파일도 가능.
cf) -v = --mount
-v [host_dir]:[container_dir] = --mount type=bind,source=[host_dir],target=[container_dir]
2. 볼륨 컨테이너
호스트를 마운트 하는 컨테이너 생성
$> docker run -it --name volume_container -v /Users/tester/test_docker/volume:/home ubuntu:14.04
위 컨테이너(볼륨컨테이너)를 통한 마운트
$> docker run -it --name volume_from_container --volumes-from volume_container ubuntu:14.04
3. 도커 볼륨
도커볼륨 생성
$> docker volume create --name myvolume
생성된 볼륨 확인
$> docker volume ls
$> docker volume inspect myvolume
(= docker inspect --type volume myvolume)
위 도커 볼륨 사용
$> docker run -it --name myvolume_1 -v myvolume:/root/ ubuntu:14.04
$> docker run -it --name myvolume_2 -v myvolume:/root/ ubuntu:14.04
-v [volume_name]:[container_dir]
cf) -v = --mount
-v [volume_name]:[container_dir] = --mount type=volume,source=[volume_name],target=[container_dir]
마운트 확인
$> docker container inspect myvolume_1
(=docker inspect --type container myvolume_1)
4. 도커 네트워크
docker0에 binding된 veth 보기(linux)
$> brctl show docker0
1. 브리지 네트워크
생성
$> docker network create --driver bridge mybridge
확인
$> docker network inspect mybridge
생성한 브리지를 이용한 컨테이너 생성
$> docker run -it --name mybridge_container --net mybridge ubuntu:14.04
--net : 브리지 설정
브리지 disconnect / connect
$> docker network disconnect mybridge mybrdige_container
$> docker network connect mybridge mybrdige_container
cf) subnet, ip range, gateway 할당(only bridge, overlay network)
docker network create --driver=bridge \
--subnet = 172.72.0.0/16 \
--ip-range=172.72.0.0/24 \
--gateway=172.72.0.1 \
my_custom_network
--net-alias
같은 브리지 네트워크 안에서는 도커 내장 DNS를 통해 name resolving 할 수 있다.(내장 DNS 주소: 127.0.0.11)
ex)
$> docker run -itd --name network_alias_container_1 --net mybridge --net-alias alias_test ubuntu:14.04
$> docker run -itd --name network_alias_container_2 --net mybridge --net-alias alias_test ubuntu:14.04
$> docker run -itd --name network_alias_ping --net mybridge ubuntu:14.04
3번째 컨테이너에서 "ping -c 1 alias_test "를 해보자.
2. 호스트 네트워크
생성
$> docker run -it --name network_host --net host ubuntu:14.04
3. NONE 네트워크
생성
$> docker run -it --name network_none --net none ubuntu:14.04
4. 컨테이너 네트워크 공유
컨테이너 생성
$> docker run -itd --name network_container_1 ubuntu:14.04
위 컨테이너 네트워크 공유
$> docker run -itd --name network_container_2 --net container:network_container_1 ubuntu:14.04
--net container:[컨테이너명]
5. MacVLAN
MacVLAN 생성
$> docker network create -d macvlan --subnet=192.168.0.0/24 --ip-range=192.168.0.64/28 --gateway=192.168.0.1 -o macvlan_mode=bridge -o parent=eth0 my_macvlan
-d : 네트워크 드라이버로 macvlan 사용 지정 = --driver macvlan
--subnet : 컨테이너가 사용할 네트워크 정보.
--ip-range : MacVLAN을 생성하는 호스트에서 사용할 컨테이너 IP 범위.
--gateway : 네트워크 게이트웨이.
-o : 네트워크 추가 옵션.
MacVLAN 사용
$> docker run -it --name {컨테이너명} --hostname {컨테이너 호스트명} --network my_macvlan ubuntu:14.04
6. 도커 로그
컨테이너의 표준 출력(StdOut)과 에러(StdErr)를 볼 수 있다. JSON 형태로 파일을 저장한다.
$> docker logs {컨테이너명}
Options
--tail : 보고싶은 마지막 라인수.
--since : 특정 시간 이후로 보고 싶을 때
-t : timestamp 표시
-f : 로그 스트림. 실시간 로그를 확인 할 수 있다.
cf) run에서 호스트에 저장되는 log 파일(json) 크기 설정
$> docker run -it --log-opt max-size=10k --log-opt max-file=3 --name log-test ubuntu:14.04
syslog로 저장
$> docker run -it --log-driver=syslog ubuntu:14.04 echo syslogtest
rsyslog로 원격 로그 저장 하기
1) rsyslog 서버 컨테이너
$> docker run -it -h rsyslog --name rsyslog_server -p 514:514 -p 514:514/udp ubuntu:14.04
cf) /etc/rsyslog.conf에 rsyslog 서버 구동 항목 주석 제거
# provides UDP syslog reception$ModLoad imudp$UDPServerRun 514# provides TCP syslog reception$ModLoad imtcp$InputTCPServerRun 514
$> service rsyslog restart
$> tail -f /var/log/syslog
2) rsyslog 클라이언트 컨테이너
$> docker run -it --log-driver=syslog --log-opt syslog-address={tcp | udp}://{서버주소} --log-opt tag="mylog" ubuntu:14.04
echo로 아무거나 넣어 보기 -> 서버 tail에 로그 나오나?
cf) 로그파일 따로 만드는 옵션
--log-opt syslog-facility="파일명"
fluentd와 mongoDB를 이용한 로깅
3개의 서버 필요
1. 몽고DB 서버
2. fluentd 서버
3. 도커(로그를 생성할) 서버
1) MongoDB 컨테이너 실행
$> docker run --name mongoDB -d -p 27017:27017 mongo
2) fluentd 컨테이너 실행
$> docker run -d --name fluentd -p 24224:24224 -v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf -e FLUENTD_CONF=fluent.conf alicek106/fluentd:mongo
fluent.conf 작성 내용
<source>@type forward</source><match docker.**>@type mongodatabase nginxcollection accesshost 172.17.0.1port 27017flush_interval 10s</match>
cf) 도커 허브의 fluentd 이미지에는 mongoDB 연결 플러그인이 내장되어 있지 않지만, 이 책의 저자가 미리 작성해 둔 alicek106/fluentd:mongo 이미지에는 mongoDB 플로그인이 들어 있음.
3) nginx 컨테이너 실행
docker run -p 80:80 -d --log-driver=fluentd --log-opt fluentd-address={fluentd 서버 IP}:24224 --log-opt tag=docker.nginx.webserver nginx
cf) fluent.conf 파일에서 match docker.**로 매칭되는 녀석들을 몽고로 보내기로 셋팅되어 있기 때문에 로그의 tag를 docker.nginx.webserver로 설정 하였다.
4) 로그 확인
브라우져에서 localhost로 nginx 접속해 본 후, 몽고 콘솔 접속
$> docker exec -it mongoDB mongo
> show dbs
...
> use nginx
...
> show collections
...
> db['access'].find()
...
AWS CloudWatch로 로깅
ec2 instance 내부에서 컨테이너 생성
$> docker run -it --log-driver=awslogs --log-opt awslogs-region={region} --log-opt awslogs-group={CloudWatch 그룹명} --log-opt awslogs-stream={CloudWatch 그룹내 스트림명} ubuntu:14.04
7. 컨테이너 자원 제한
default -> 제한 없음
리소스 조회
$> docker inspect {컨테이너명}
"HostConfig": {
...
}
실행 되어 있는 컨테이너 자원 변경
-> docker update {변경할 자원 제한} {컨테이너명}
$> docker update --cpuset-cpus=1 ubuntu
메모리 & swap 설정
$> docker run -it --name swap_500m --memory=200m --memory-swap=500m ubuntu:14.04
cpu 제한
--cpu-shares : cpu 사용 비
(1) $> docker run -it --name cpu_1024 --cpu-shares 1024 ubunt:14.04
(2) $> docker run -it --name cpu_512 --cpu-shares 512 ubuntu:14.04
-> host의 cpu 사용율은 cpu_1024 : cpu_512 = 2 : 1이 된다.
--cpuset-spus
특정 cpu 사용하도록 설정
$> docker run -d --name cpuset_2 --cpuset-cpus=2 alicek106/stress stress --cpu 1
-> 컨테이너가 3번 cpu만 사용하도록 설정
--cpuset-cpus="0,3" -> 1번과 4번 사용
--cpuset-cpus="0-2" -> 1, 2, 3번 사용
--cpu-period, --cpu-quota
period 기간안에서 quota 만큼 실행(100000 / 50000 = 1/2 cpu 50% 점유)
$> docker run -d --name quota_1_4 --cpu-period=100000 --cpu-quota=50000 alicek106/stress stress --cpu 1
아래와 동일
$> docker run -d --name cpus_container --cpus=0.5 alicek106/stress stress --cpu 1
8. Blocking I/O 제한
default는 제한 없음
쓰기 작업 최대 1MB로 제한
$> docker run -it --device-write-bps /dev/xvda:1mb ubuntu:14.04
IOPS로 제한(5M제한)
$> docker run -it --device-write-iops /dev/xvda:5 ubuntu:14.04
댓글
댓글 쓰기