방식
이미지의 Config.Volumes
선언되어 있으면, 자동으로 Docker 볼륨이 생성되고 마운트된다.
볼륨: 읽기-쓰기가 가능한 빈 저장소를 생성
빈 볼륨 생성
docker volume create <NAME>
볼륨 목록
docker volume ls
볼륨 삭제
docker volume rm <NAME>
사용하지 않는 볼륨 삭제
docker volume prune
사용하지 않는? 컨테이너에 마운트되지 않음
볼륨을 사용한 컨테이너
docker run -v <VOL-NAME>:<MOUNTPOINT>[:ro] <IMAGE>
지정한 볼륨 이름이 없으면 생성
docker run --name wp-db -d -e MYSQL_ROOT_PASSWORD=P@ssw0rd -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpadm -e MYSQL_PASSWORD=P@ssw0rd --restart always --cpus 0.5 --memory 1000m -v wp-db-vol:/var/lib/mysql mysql:5.7
바인드 방식은 컨테이너에게 제공할 볼륨을 호스트의 특정 디렉토리를 지정하는 방식
호스트의 디렉토리를 컨테이너에게 제공: 미리 데이터를 채워서 제공이 가능
docker run -v <ABSOLUTE_PATH>:<MOUNTPOINT>[:ro] <IMAGE>
디렉토리 전체 마운트
docker run -d -v /home/vagrant/contents:/usr/local/apache2/htdocs httpd
파일 마운트
docker run -d -v /home/vagrant/contents/hello.html:/usr/local/apache2/htdocs/hello.html httpd
팁! 파일명으로 패키지 찾을 때
yum provides /usr/bin/ip
apt install apt-file
apt-file update
apt-file search /usr/bin/ip
네트워크 플러그인 종류
인터페이스 확인
ip addr show
브릿지 확인 명령 설치
sudo apt install bridge-utils
brctl show
NAT 테이블 확인
sudo iptables -t nat -L -n
sudo apt update
sudo apt install iproute2
ip addr show
ip route
sudo iptables -t nat -L -n
호스트의 네트워크를 공유해서 사용
docker run -d --network host httpd
네트워크가 없는 컨테이너 생성
docker run -d --network none httpd
docker network create --driver bridge --subnet 192.168.200.0/24 --gateway 192.168.200.1 wordpress-network
docker run --name wp-db -d \
-e MYSQL_ROOT_PASSWORD=P@ssw0rd \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpadm \
-e MYSQL_PASSWORD=P@ssw0rd \
--restart always --cpus 0.5 --memory 1000m \
-v wp-db-vol:/var/lib/mysql \
--network wordpress-network \
mysql:5.7
docker run --name wp-web -d \
--link wp-db:mysql \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=wpadm \
-e WORDPRESS_DB_PASSWORD=P@ssw0rd \
-e WORDPRESS_DB_NAME=wordpress \
--restart always --cpus 0.5 --memory 500m \
-p 80:80 -v wp-web-app:/var/www/html \
--network wordpress-network \
wordpress:5-apache
docker exec -it wp-web bash
cat /etc/hosts
docker exec -it wp-db mysql -u wpadm -p
show database;
use wordpress;
show tables;
### wordpress 설치를 하고 나면
show tables; #테이블에 스키마가 생성됨
docker exec wp-db env
docker exec wp-web env
또 다른 방법
docker exec -it wp-web bash
ls
vi wp-config #정확한 이름 확인
getenv라는 함수의 환경변수의 값을 읽으라는 뜻임 없으면 뒤에 기본값을 선택하라는 뜻
이미지의 레이어가 한 개라고 가정했을 때
docker inspect hello-world
보면 레이어가 하나이다
이미지를 받을 때에도
이것이 레이어를 나타낸다고 배웠었다.
이 레이어는 read-only이다. 즉, 바뀌지 않는다. 그래서 이 이미지를 가지고 컨테이너를 만들게 된다. 이러면 컨테이너 또한 read-only이다. 근데 컨테이너는 여기에 레이어를 하나 더 붙이게 된다 read-write 레이어를 하나 더 얹어준다.
이후에 이 컨테이너에 무언가를 설치하고 구성을 하고 지우게되면 모두 지워지게 된다
무언가 작동을 위한 immutable infrastructure은 시간이 지나도 로그를 남기거나 하는것 없이 그냥 작동만하는 그 기능만을 하면 되는 구조이기 때문에 문제가 생기면 이미지를 그냥 교체하지만 하면 된다.
이와 반대로 immutable infrastructure를 할 수 없는 대표적인 구조는 데이터베이스이다.
/var/lib/mysql/.
게시글을 올리고 댓글을 달고하면 계속해서 이 데이터가 추가되고 변경될 것이다.
이 때 컨테이너를 날리게되면 DB의 내용도 지워지게 된다.
그렇다고 해서 항상 DB의 내용을 백업하고 다시 복구하고 하는 과정을 거쳐야하느냐에 대해서 이야기해보자.
즉,
container life cycle과 다른 별개의 스토리지를 만들어서 저장을 해주어야한다. 이것을 볼륨 Volume이라고 한다. 컨테이너를 지워도 볼륨은 별개로 남아있게된다.
AWS에서도 우리가 봤듯이 EBS개념이 이런 개념이다.
docker volume ls #실습을 많이할 수 록 쌓여있을것이다.
docker images
docker inspect mysql:5.7
docker volume
prune y #볼륨을 모두 제거
docker volume ls
이미지내에 Volumes라는 부분이 선언되어있으면 볼륨이 하나 생김
inspect 해서 Mounts라는 부분을 보면
이렇게해서 마운트가 자동으로 지정되어있다..
볼륨을 한 번 보면..
이렇게 되어있음
이렇게 마운트 되어있는거임
wordpress도 var/www/html가 볼륨으로 제공되어야한다고 되어있다.
docker volume ls
docker inspect wp-db
별도로 선언하지 않더라도 볼륨이 생성되고 볼륨이 마운트된다.
이곳이 마운트 지점
비교해보면
docker volume create --help
docker volume create
docker volume ls
그리고 -v
옵션을 통해 볼륨을 연결할 수 있다.
docker volume ls
docker run -itd -b test-vol:/test-vol ubuntu
docker inspect [b2c] #컨테이너이름
docker ps
docker exec -it b27 bash
pwd
ls
cd test-vol/
ls
echo "hello volume" > hello.txt
cat hello.txt
exit
sudo ls /var/lib/docker/volumes/test-vol/_date
sudo cat /var/lib/docker/volumes/test-vol/_date/hello.txt
docker ps
docker rm -f b27
docker volume ls
docker run -itd -b test-vol:/test ubuntu
docker exec [b0a] ls /test #컨테이너 이름
사실은 볼륨을 미리 정하지 않아도 된다
이렇게 알아서 볼륨이 하나 만들어짐
https://hub.docker.com/_/mysql
보면 볼륨에 관한 정보가 있는 것을 확인할 수 있음
https://hub.docker.com/_/wordpress
여기에서도 볼륨에 대한 내용들이 존재함
이렇게 이미지에 세팅이 되어있다면 자동으로 사용할 수 있음
다만 우리가 배운 수동 볼륨생성을 통해 볼륨이 없는 이미지들도 볼륨을 사용할 수 있게 해줄 수 있다.
여러 개의 볼륨을 마운트 할 수 도 있다.
docker run -itd -v abc:/abc -v xyz:/xyz ubuntu
docker volume ls
docker inspect [p59]
docker run --name wp-db -d -e MYSQL_ROOT_PASSWORD=P@ssw0rd -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpadm -e MYSQL_PASSWORD=P@ssw0rd --restart always --cpus 0.5 --memory 1000m -v wp-db-vol:/var/lib/mysql mysql:5.7
이름을 이렇게 직접 지정해주는 것이 나중
을 위해 더 효율적이다
docker rm -f 1d
docker ps -a
docker volume ls #볼륨은 당연히 지워지지않았음
docker run --name wp-db2 -d -v wp-db-vol:/var/lib/mysql mysql:5.7
docker run --name wp-db -d -e MYSQL_ROOT_PASSWORD=P@ssw0rd -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpadm -e MYSQL_PASSWORD=P@ssw0rd --restart always --cpus 0.5 --memory 1000m -v wp-db-vol:/var/lib/mysql mysql:5.7
이렇게 환경변수 없이 실행이 가능하다
이유는 무엇일까
환경변수가 볼륨에 저장되어있어서? 아님
사용자랑 데이터베이스 정보가 볼륨에 저장되어있어서 정답
좀더 풀어서 설명하면 환경변수를 설정해서 결국 사용자와 데이터베이스 정보를 설정하는 거였는데 결국 설정이 되어있으니 더이상 환경변수는 필요없고 이미 설정된 값을 볼륨에서 그냥 바로 불러오는 식으로 되는것임
여기서 질문
아까 wp-config파일에는 getenv라는 형태로 저장되어있었는데 그러면 데이터베이스 정보나 사용자 정보로 저장되는게 아니라 결국 환경변수가 저장되는 형태인것이 아닌가?
답변
wordpress와 데이터베이스는 다름 데이터베이스
그래서 주의할 점
환경변수는 이제 더이상 사용되지 않는다 왜냐하면 이미 기존에 환경변수를 이용해 세팅은 다끝났기 때문
기존의 패스워드로도 접속이 안되는 현상 발생 충돌이 났기 때문
그래서 다시
환경변수 없이 run
을 하면 잘 접속할 수 있다
docker run -itd -v abc:/abc --name u1 ubuntu
docker run -itd -v abc:/abc:ro --name u2 ubuntu
NFS개념과 비슷하지만 NFS는 동시에 쓰기작업을 하려면 lock을 걸어야함
컨테이너에는 lock기능이 없어서 동시에 데이터를 쓰게되면 데이터가 깨지는 문제가 발생할 수 있다
그래서 사용하는 것이
:ro
옵션
기본적으로는 :rw
옵션이 디폴트임
docker inspect u1
docker inspect u2
docker exec -it u1 bash
cd abc/
ls
touch a b c
ls
exit
docker exec -it u2 bash
cd abc/
ls
touch x y z
###불가능
지금까지 공부한 내용은 volume 방식이다
volume방식은 도커 데몬이 관리하고
bind방식은 도커 데몬이 관리하지 않는다는 차이점이 있다.
즉 docker volume
이라는 명령어로 확인할 수 없다.
각 방법에 대한 사용하는 이유가 있다
볼륨을 절대경로를 지정하느냐 볼륨을 지정하느냐에 따라 bind방식과
volume 방식을 나누게된다
docker inspect [컨테이너 이름]
이부분이 달리지게 된다. 정식이름이 이렇습니다.
바인드방식은 파일같은 것들을 미리 채워놓고 제공할 수 있다.
물론 볼륨방식도 채울 수 있지만 조금더 번거로운 작업이 된다.
이렇게 사용 용도가 나뉨
httpd의 정보를 확인
컨텐츠가 있어야하는 디렉토리 확인
그래서..
docker run -d -v /home/vagrant/contents:/usr/local/apache2/htdocs httpd
docker exec -it e0 bash
이번에는..
이걸 파일 마운트라고 함
파일로만 마운트를 시킬 수 있음
index.html
은 원래 있던 파일이고
우리가 마운트를 hello.html
file로만 마운트를 한다는 뜻임
기존방식은
이렇게 사용했었음 차이를 확인해보자
디렉토리 뿐만 아니라 파일 자체도 마운트를 시킬 수 있음
우리가 이미 만들어놓은 html파일이 있다면 그걸 사용하지 않고 새로 생성해서 마운트시키는거라고 보면 됨
여기서 질문 그럼 파일마운트를 여러 개 해야한다면?
-v 여러 개를 선언하면 가능하다
디렉토리를 마운트하면 기존에 있던 파일에 접근하지는 못함
그렇다고 파일이 사라지는 것은 아니고 파일에 굳이 접근하라는 말을 안했기 때문에 디렉토리만 접근하는 것임
디렉토리를 마운트하면 기존파일들이 다 사라지기 때문에 파일마운트로 파일들을 지정해서 살려줘야함
꽤 중요한 기법임 !
이렇게 미리 준비를 해놓고 제공할 수 있다.
볼륨방식은 파일마운트는 할 수 없다 오로지 디렉토리 끼리만 마운트 가능
이렇게 기존의 파일은 사라져버림
다만 이런 마운트 내용에대한 로그같은 것은 남겨지지 않음
생각해볼 문제
docker inspect wordpress:5-apache
이미지에 이미 volume 방식으로 되어있는데 굳이 왜 웹 어플리케이션인데 볼륨이 필요할까?
하지만 이것은 wordpress이기 때문에 필요하다
워드프레스에는 테마들이 꽤 많이 있다
이런 테마들을 설치하는 경우 또는 wordpress에는 수많은 plugin들이 존재하는데 이런것들을 사용하기 위함임
여기에 테마와 플러그인이 설치가 된다. 우리가 설치한 테마와 플러그인을 사용하기 위해서는 그것들을 설치할 공간이 필요했던 것임.
교재 43페이지에서..
볼륨을 공유하기위한 목적의 컨테이너를 따로 만들어서 할 수 도 있음
다만 해당 스토리지도 결국 컨테이너이기 때문에 리소스를 사용해야하는 것임 이 방식이 아까 배운 방식보다 리소스를 더 사용하기 때문에 좋은 방법은 아님
시작하기전에 컨테이너와 볼륨을 삭제하고
docker run -itd ubuntu
docker inspect 11e
이정도가 네트워크 정보이고 내부에서 외부로 나갈 수 있음 그 때 사용하는게 gateway임
apt install iproute2
ip
ip addr show
ip route
물론 inspect로 확인 가능하지만 이런 방법도 있다~
docker exec -it 11 bash
ip a s
ifconfig
사용 불가능
이런 바이너리와 라이브러리를 설치해놓지 않았음
컨테이너는 최소한의 바이너리와 라이브러리만 두는 원칙이 있기 때문
apt update
apt search apt-file
apt install apt-file
apt-file update
apt-file search /bin-ip
centos에서는..
yum provides /usr/sbin/ip
yum provides /var/www/html
yum provides /usr/bin/ping
yum provides /etc/ssh/ssh_config
어느 패키지로 인해서 설치되어있는지 확인 가능
기존에 사용하던 명령어를 사용하기위한 설치 패키지를 찾을 때
ip a s
docker ps
docker rm -f 11
없어져있음
ubuntu 컨테이너를 2개 만들고나면
veth.. 네트워크가 추가된 것을 확인할 수 있다.
이것을 그림으로 그려보면..
veth는 virtual ethernet이라는 뜻
교제 49페이지에도 이런 내용이 있음
중간에 router 역할을 하는 곳에서 단순히 브릿지간에 연결시키는거 뿐만 아니라 많은 역할을 함 이것에 대해서 더 알아볼 예정
brctl #명령어 없음
sudo apt install bridge-utils
brctl show
docker ps
docker rm -f 36
brctl show
ip link
명확하게 연결한것을 확인할 수 있음
그래서 그 라우팅 역할을 하는 애가 누구냐 하는 것을 공부할 예정
iptables
커널영역 중에 netfilter가 있는데 이게 방화벽 라우팅 역할을 다 해줌
이 도구를 사용하기 위한 명령어가 iptables이다.
RH계열에서는 Firewalld Debian계열에서는 UFW
iptables는 가장 기본적인 올드한 명령어임 firewalld나 UFW는 데몬에서 작동을 함 결국 iptable명령어로 바꿔서 netfilter를 제어하는거임
sudo iptables -t nat -L -n
#-t는 우리가 보고자하는 테이블의 타입
#-L는 리스트
#-n은 numeric 숫자임
MASQUERADE
ip의 헤더를 변경시킨다라는 의미
출발지 ip를 바꾸어서 나가라 라는 뜻
사설ip로는 통신을 할 수가 없기 때문임
iptabels에 대해서 깊이있게 공부해보는 것을 추천
기본적으로 nat게이트웨이를 이렇게 여러번 걸쳐서 통신이 가능하게 되는 거임
docker network
docker network ls
docker ps
docker inspect
이 브릿지 타입의 네트워크를 기본적으로 사용하게 되는 것임
...
브릿지 네트워크를 사용하는 컨테이너
docker run -d -p 8080:80 httpd
docker ps
#구글에서 192.168.100.100검색
sudo iptables -t nat -L -n
이 그림을 이해하는게 매우 중요하다
DNAT는 -p옵션을 붙여야만 생김
docker run -d -p 8081:80 httpd
이렇게 만들면 172.17.108.3번인 새로 만든 컨테이너로 연결이 된다는 개념..
docker network ls
docker run -d --network host httpd
docker ps
docker exec -it 22 bash
ip
apt update
apt install iproute2
ip a s #컨테이너 내부
###브릿지를 사용하지 않고 호스트의 네트워크를 그대로 사용하는게 가능하다
컨테이너가 그냥 호스트의 네트워크를 사용하는 것도 가능하다
다만 이미 호스트 네트워크를 컨테이너가 사용하고 있기 때문에 한 번 터 같은 방식으로 run
했을 때 불가능하다.
또하나 host방식에서는 네트워크가 존재하지 않는다.
네트워크관련된 패키지를 설치한 장성균강사님이 만든 깃헙에서 제공하는 레지스트리에 있는 이미지인데
none으로 실행해서 네트워크가 아무것도 없음
네트워크를 굳이 제공할 필요가 없는 어플리케이션을 실행할 때 쓰라고 만든 내용임
도커 호스트가 여러 개 일 경우가 있음
이 때 서로 다른 도커 호스트에 있는 컨테이너를 같은 네트워크에 배치시키고 싶을 때 사용할 것
컨테이너가 수만개가 되면 결국 여러 대의 컴퓨터에 여러 개의 도커 호스트를 어쩔 수 없이 사용하게 됨
서브넷이 너무 크면 브로드캐스트를 할 때 엄청난 과부하가 걸리게됨
그래서 실제로 이런 방식을 사용하지는 않음
58페이지..
overlay는 네트워크의 일반적인 용어, 터널링을 의미함, 도커 스웜은 도커 호스트 여러 개를 클러스터링하자는 뜻임
docker network create --driver bridge --subnet 192.168.200.0/24 --gateway 192.168.200.1 wordpress-network
docker network inspect wordpress-network
brctl show
docker run --name wp-db -d...
docker inspect [container name]
docker inspect [container name---wp-web]
192.168.100.100에 접속하면
docker volume ls
docker compose라는 IaC기능이 있기도 하다
내일은 도커의 이미지를 만들어보는 시간을 가질 예정
도커 이미지를 레지시트리에 올리고 받아볼 예정
질문사항
docker inspect 98
보통은 id를 지정하려고 하는데 이미지중에 98번이 있을 수 있고 컨테이너 이름이 98번으로 시작할 수 가 있는데 그러면 오류가 나옴
그래서 2자리가안되면 3자리 ,4자리 더 할 수도 있는데
docker image inspect d2 이런식으로 하면 image id만 조회를 하기 때문에 괜찮다
docker container inspect
docker volume inspect
docker network inspect
docker container prune명령어는 모든 중단되어있는 컨테이너를 삭제하는 명령어임
docker volume prune 사용하지 않는 볼륨을 삭제
docker image prune
docker network prune 단, 우리가 직접 만든 네트워크만 사라지는거고 기본적인 네트워크는 당연히 삭제가 안됨