❒ From the book “도커, 컨테이너 빌드업!”
# 이미지 다운로드
docker pull node
# 컨테이너화
# --publish [host_port]:[container_port]
docker run -dp 8080:80 -it --name=nodejs_test node:latest
# 컨테이너 실행 확인
docker ps
# 소스코드 로컬->컨테이너 내부
cat > nodejs_test.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World!');
}).listen(80);
docker cp nodejs_test.js nodejs_test:/nodejs_test.js
# 실행중인 npm이 설치된 nodejs_test 컨테이너에 bash shell로 접속
docker exec -it nodejs_test /bin/bash
> ls
nodejs_test.js
> node -v
> node nodejs_test.js &
> exit
curl localhost:8080
Hello World!
# docker run --publish [host_port]:[container_port]
# docker run -dp 8080:80 docker/getting-started:pwd
# 호스트 PC에서 localhost:8080으로 접근
cat > Dockerfile
FROM ubuntu:18.04
MAINTAINER RABOOF <raboof@email.com>
RUN \
apt-get update && \
apt-get install -y apache2
RUN sed -i 's/80/7080/g' /etc/apache2/ports.conf
EXPOSE 7080
CMD ["apachectl", "-D", "FOREGROUND"]
# 호스트가 아닌, 컨테이너 서비스를 통해 명령어 실행
docker run -it busybox sh
docker run busybox echo 'Hello World'
docker run명령어 [클라이언트]
-> 서버의 도커데몬
-> docker.sock의 도커 API로 컨테이너 생성
-> 수행된 컨테이너에 포함된 서비스 결과를 [클라이언트]에 전달
docker -v
docker version
docker info
docker system info
docker info --format ''
# 회수 가능한 공간: RECLAIMABLE
docker system df
docker system df -v
# 회수 가능공간 확보
docker system prune
# 실시간 로그 출력
# 터미널 두개로 확인
docker system events
docker run -itd -p 80:80 --name=webapp nginx
docker ps
docker stop webapp
docker system events
docker system events --filter 'type=image'
docker system events --filter 'event=stop'
docker system events --filter 'container=webapp'
docker system events --filter 'event=stop' --filter 'container=webapp'
docker system events --since 24h
docker system events --format ''
# 도커데몬 디버깅을위한
# OS별 도커데몬 로그 위치
# 우분투, CENTOS /var/lib/docker
# RHEL /var/log/messages
# 데비안 /var/log/message.log
# 윈도우 ~AppData\Local
# macOs..
# 로그내용 중 msg 키워드 정보가 상세 로그 내용임
sudo journalctl -u docker.service
# 유사한 도커 데몬 디버그
sudo dockerd -D
# 리눅스 시스템에도 기본적인 로그 수집 데몬이 있음
syslogd
rsyslogd
# [참고] 도커로그를 호스트 운영체제 로그수집 데몬에 연결해서 로그 기록 할 수도 있음
# 도커 허브
# tag생략 시 latest
docker pull imagename:tag
docker pull imagename:digest
docker pull gcr.io/google-samples/hello-app:1.0
docker push
docker login
docker logout
docker image ls
docker image inspect imagename --format="" httpd
docker image inspect imagename --format="" httpd
docker image inspect imagename --format="" httpd
# docker login 이후
docker search httpd
docker image history [OPTIONS] IMAGE
docker image history httpd
# docker pull
# docker hub에서 로컬로 다운하면서 생성된 레이어 distribution id 출력
# 이미지 변경 되면, 로컬 저장된 이미지를 제외한 새로운 레이어 계층들만 로컬에 다운로드
docker pull httpd:latest
docker tag 원본이미지:[태그] 참조이미지:[태그]
docker images
REPO TAG IMAGE ID
httpd latest b2c2ec
docker tag b2c2ec debian-httpd:1.0
docker images
REPO TAG IMAGE ID
debin-httpd 1.0 b2c2ec
httpd latest b2c2ec
docker push [본인아이디]/httpd:3.0
docker pull [본인아이디]/httpd:3.0
# 베이스 이미지에 특정 애플리케이션을 서비스와 코드를
# 포함해 컨테이너로 포함해 실행하는 경우 docker commit으로
# 컨테이너를 이미지로 저장가능
# 1.
docker login
username:
password:
cat ~/.docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "...."
}
}
}
docker info | grep username
# config.json 파일의 auth 값이 삭제되고, docker info에서도 사용자명이 제거됨
docker logout
# 2.
# hub.docker.com > Account settings > Security > New Access Token
# 복사된 액세스 토큰 사용하여 로그인
vi .access_token
cat .access_token | docker login --username jnuho --password-stdin
docker image save [옵션] <파일명> [image명]
docker image load [옵션]
# 이미지-> .tar 저장
docker pull mysql:5.7
docker images
docker image save mysql:5.7 > test-mysql57.tar
ls -lh test-mysql57.tar
# 묶인 파일내용 확인
tar tvf test-mysql57.tar
docker image rm mysql:5.7
docker images
# 이미지<- .tar 로드: 방법1
docker image load < test-mysql57.tar
docker images
# 이미지<- .tar 로드: 방법2
cat test-mysql57.tar | docker import - mysql57:1.0
docker images
# 이미지 용량 줄이기 : gzip
docker image save mysql:5.7 | gzip > test-mysql57zip.tar.gz
ls -lh test-mysql57zip.tar.gz
docker image rm mysql:5.7
docker images
docker image load < test-mysql57zip.tar.gz
docker images
docker image rm [option] {이미지이름[:태그] | 이미지ID}
docker rmi {옵션} {이미지이름[:태그] | 이미지 ID}
docker pull ubuntu:14.04
docker image rm ubuntu:14.04
docker image rm b2c2a
docker image rm -f b2c2a
# show images ids
docker images -q
# remove all images
docker rmi $(docker images -q)
docker rmi $(docker images | grep debian)
docker rmi $(docker images | grep -v centos)
# 상태가 exited 인 container를 찾아서 모두 삭제
vi .bashrc
alias cexrm='docker rm $(docker ps --filter 'status=exited' -a -q)'
source .bashrc
alias
# -a옵션으로 사용 중이 아닌 모든 이미지 제거
docker image prune -a
docker image prune -a -f --filter "until=48h"
# 도커 컨테이너의 PID 1번 프로세스도 init 프로세스?
# 호스트의 셸 프로세스 ID
echo $$
32370
docker run -it centos:8 bash
> echo $$
1
# 다른 터미널에서 실행 중인 PID 조회
ps -ef | grep 32370
# docker run과 달리, container 내부접근 없이 생성(스냅샷)만 수행
docker crerate -it --name container-test1 ubuntu:14.04
docker ps -a
# status : created -> up
docker start container-test1
docker ps
# 컨테이너에 접속 - 실행중인 어플리케이션 컨테이너에 단순한 조회 작업 수행
docker attach container-test1
exit
docker rm container-test1
# docker run = [pull] + create + start + [command]
docker run -it --name container-test1 ubuntu:14.04 bash
exit
docker rm container-test1
docker run -it --name container-test1 ubuntu:14.04 hostname
docker pull mysql:5.7
docker images | grep mysql
docker run -it mysql:5.7 /bin/bash
> cat /etc/os-release
> /etc/init.d/mysql start
> mysql -uroot
mysql> show databases;
mysql> create database dockerdb;
mysql> show databases;
> cd /var/lib/mysql
> ls
... dockerdb...
docker ps -a
docker start ba5a
docker exec -it ba5a bash
# 컨테이너 종료시키지 않고 나가려면 ctrl+p+q
docker inspect flamboyant_nash | grep IPAddress
docker exec -it flamboyant_nash bash
# 다른이름으로 새로운 컨테이너 실행
docker run -it mysql:5.7 bash
# http://hostip:9559 에서 볼수 있음
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=9559:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
1c653c540628 google/cadvisor:latest "/usr/bin/cadvisor -…" 8 seconds ago Up 7 seconds 0.0.0.0:9559->8080/tcp, :::9559->8080/tcp cadvisor
docker pull nginx:1.8
docker images
docker run --name webserver1 -d -p 8001:80 nginx:1.18
docker ps
sudo netstat -nlp | grep 8001
curl localhost:8001
docker stats webserver1
docker top webserver1
# -f: 실시간, -t 마지막로그
docker logs -f webserver1
docker stop webserver1
docker start webserver1
vi index.html
<h1> Hello Jpub Docker. </h1>
docker cp index.html webserver1:/usr/share/nginx/html/index.html
curl localhost:8001
# 프로세스 일시중단
docker pause webserver1
docker ps
docker unpause webserver1
docker ps
docker restart webserver1
cat > py_lotto.py
from random import shuffle
from time import sleep
gamenum = input('로또 게임 횟수 입력:')
for i in range(int(gamenum)):
balls = [x+1 for x in range(45)]
ret = []
for j in range(6):
shuffle(balls)
number = balls.pop()
ret.append(number)
ret.sort()
print('로또번호[%d]: ' %(i+1), end='')
print(ret)
sleep(1)
# 파이썬 컨테이너 실행 후 py_lotto.py 코드복사
docker run -it -d --name=python_test -p 8900:8900 python
docker cp py_lotto.py python_test:/
# 파이썬 컨테이너에 설치된 모듈 확인
docker exec -it python_test bash
> python --version
> pip list
> python -c 'help("modules")'
docker exec -it python_test python /py_lotto.py
docker run -d -p 8010:80 --name=webserver10 nginx:latest
# 컨테이너 -> 로컬로 복사
docker cp webserver10:/etc/nginx/nginx.conf ./nginx.conf
# 변경후 다시 로컬->컨테이너로 복사
docker cp nginx.conf webserver10:/etc/nginx/nginx.conf
docker restart webserver10
cat > nodejs_test.js
var http = require('http');
var content = function(req, res) {
resp.end("Good morning Korea~!" + "\n");
resp.writeHead(200);
}
var web = http.createServer(content);
web.listen(8002);
# Host OS에서 실행시 nodejs 미설치로 에러발생!
node nodejs_test.js
# 컨테이너에서 실행 가능
docker pull node
docker run -d -it -p 8002:8002 --name=nodejs_test node
docker ps
docker cp nodejs_test.js nodejs_test:/nodejs_test.js
# 컨테이너 내부에서 nodejs_test.js를 실행!
docker exec -it nodejs_test node /nodejs_test.js
curl localhost:8002
# 노드 서버 실행 중인 컨테이너 이름변경하고 싶다면 docker rename
# 동적으로 변경됨!
# docker rename <기존 Container명> <새로운 Container명>
docker renmae nodejs_test nodeapp
docker ps
# nodejs_test.js를 실행하는 컨테이너를 다시 이미지로 저장 가능
docker run -it --name=webserver8 -d -p 8008:80 nginx:latest
docker ps
curl localhost:8008
cat > index.html
<h1> Hello World! </h1>
docker cp index.html webserver8:/usr/share/nginx/html/index.html
# 추가된 웹소스 변경 정보 확인
# A 추가, D 삭제, C 변경
docker diff webserver8
C /usr/share/nginx/html/index.html
# 컨테이너 -> 이미지
docker commit -a "jpub" webserver8 webfront:1.0
docker images | grep webfront
# 이미지 -> 도커허브
docker login
# 본인ID/이미지:태그
docker tag webfront:1.0 jnuho/webfront:1.0
docker push jnuho/webfront:1.0
docker run -it --name webserver9 -d -p 8009:80 jnuho/webfront:1.0
curl localhost:8009
docker volume create 볼륨명
# 볼륨 생성
docker volume create my-appvol-1
docker volume ls
docker volume inspect my-appvol-1
# --mount 옵션으로 볼륨 지정
docker run -d --name vol-test1 \
--mount source=my-appvol-1,target=/app \
ubuntu:20.04
# -v 옵션으로 볼륨 지정
docker run -d --name vol-test2 \
-v my-appvol-1:/var/log \
ubuntu:20.04
# 볼륨 미리 만들지 않아도 자동 생성
docker run -d --name vol-test3 \
-v my-appvol-2:/var/log \
ubuntu:20.04
docker volume ls
DRIVER VOLUME NAME
local my-appvol-1
local my-appvol-2
docker inspect vol-test1
"Mounts": [{}]...
docker inspect --format="" vol-test1
[{}]
# 자원 삭제: 컨테이너 제거-> 볼륨 삭제
docker volume rm my-appvol-1
docker stop vol-test1 vol-test2
docker rm vol-test1 vol-test2
docker volume rm my-appvol-1
# --mount 옵션으로 사전에 생성한 경로와 바인드 마운트 지정.
mkdir /home/foo/target
docker run -d -it --name bind-test1 \
--mount type=bind,source=$(pwd)"/target,target=/var/log \
centos:8
# -v 옵션으로 사전에 생성한 경로와 바인드 마운트 지정.
docker run -d -it --name bind-test2 \
-v "$(pwd)"/target:/var/log \
centos:8
...
# 볼륨 생성
docker volume create mysql-data-vol
docker volume ls
# mysql 컨테이너 실행 시 데이터베이스 설정도 추가하여 실행
# hub.docker.com의 mysql페이지에 환경변수 설명 참조
docker run -it --name=mysql-vtest \
-e MYSQL_ROOT_PASSWORD=jhlee \
-e MYSQL_DATABASE=dockertest \
-v mysql-data-vol:/var/lib/mysql -d \
mysql:5.7
docker exec -it mysql-vtest bash
/etc/init.d/mysql start
mysql -uroot -p
show databases;
use dockertest;
create table mytab (c1 int, c2 char);
insert into mytab values (1, 'a');
select * from mytab;
exit
ls /var/lib/mysql/dockertest/
exit
docker inspect --format="" mysql-vtest
sudo ls -l /var/lib/docker/volumes/mysql-data-vol/_data/dockertest
# 컨테이너 장애 테스트 케이스: 컨테이너 정지,제거 후 동일 볼륨지정 컨테이너 실행 시
# 기존 데이터 그대로 유지 확인
docker stop mysql-vtest
docker rm mysql-vtest
docker run -it --name=mysql-vtest \
-e MYSQL_ROOT_PASSWORD=jhlee \
-e MYSQL_DATABASE=dockertest \
-v mysql-data-vol:/var/lib/mysql -d \
mysql:5.7
mkdir nginx-log
docker run -d -p 8011:80 \
-v /home/jhlee/nginx-log:/var/log/nginx \
nginx:1.19
http://localhost:8011
tail -f nginx-log/access.log
# 지정된 날짜/시간 내에 기록된 IP 정보를 내림차순으로 카운트하여 횟수와 IP 주소 출력.(예, 01/Mar/2021:12:32:37)
awk '$4>"[로그에 기록된 날짜, 시간]" && $4<"[로그에 기록된 날짜, 시간]"' access.log | awk '{ print $1}' | sort | uniq -c | sort -r | more
도커 볼륨 활용3: 컨테이너 간 데이터 공유를 위한 데이터 컨테이너 만들기
docker-compose 실습 : go-playground
# docker-compose.yml
version: '2'
services:
playground:
image: x1unix/go-playground:latest
environment:
APP_CLEAN_INTERVAL=10m # Build files remove interval
APP_DEBUG=false # Enable debug mode
ports:
- 127.0.0.1:8000:8000