20220529 필기노트

강재민·2022년 5월 9일
1

필기노트

목록 보기
3/23

수업 내용 요약


Docker 볼륨

방식

  • Bind: 볼륨은 도커 데몬이 관리하지 않음
  • Volume: 볼륨은 도커 데몬이 관리함

이미지의 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

사용 용도

  • 바인드: 설정파일, 기타 파일을 제공하기 위한 목적
  • 볼륨: 데이터를 저장하기 위한 빈 디렉토리 제공하기 위한 목적

Docker 네트워크

팁! 파일명으로 패키지 찾을 때

yum provides /usr/bin/ip

apt install apt-file
apt-file update
apt-file search /usr/bin/ip

네트워크 플러그인 종류

  • bridge: 기본 네트워크
  • host
  • null
  • ...

브릿지 네트워크

호스트 확인

인터페이스 확인

ip addr show
  • docker0: 브릿지
  • vethX: 가상 인터페이스

브릿지 확인 명령 설치

sudo apt install bridge-utils
brctl show

NAT 테이블 확인

sudo iptables -t nat -L -n
  • MASQUERADE: Source NAT

컨테이너 확인

sudo apt update
sudo apt install iproute2
ip addr show
ip route

포트 포워딩이 설정된 컨테이너

sudo iptables -t nat -L -n
  • DNAT: Destination NAT

호스트 네트워크

호스트의 네트워크를 공유해서 사용

docker run -d --network host httpd

Null 네트워크

네트워크가 없는 컨테이너 생성

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
###불가능

bind방식

지금까지 공부한 내용은 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
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번인 새로 만든 컨테이너로 연결이 된다는 개념..


host type

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 type


네트워크관련된 패키지를 설치한 장성균강사님이 만든 깃헙에서 제공하는 레지스트리에 있는 이미지인데
none으로 실행해서 네트워크가 아무것도 없음
네트워크를 굳이 제공할 필요가 없는 어플리케이션을 실행할 때 쓰라고 만든 내용임


ipvlan 또는 macvlan

도커 호스트가 여러 개 일 경우가 있음
이 때 서로 다른 도커 호스트에 있는 컨테이너를 같은 네트워크에 배치시키고 싶을 때 사용할 것

컨테이너가 수만개가 되면 결국 여러 대의 컴퓨터에 여러 개의 도커 호스트를 어쩔 수 없이 사용하게 됨


서브넷이 너무 크면 브로드캐스트를 할 때 엄청난 과부하가 걸리게됨
그래서 실제로 이런 방식을 사용하지는 않음

58페이지..


overlay type

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기능이 있기도 하다

내일은 도커의 이미지를 만들어보는 시간을 가질 예정
도커 이미지를 레지시트리에 올리고 받아볼 예정

https://hub.docker.com/

질문사항

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 단, 우리가 직접 만든 네트워크만 사라지는거고 기본적인 네트워크는 당연히 삭제가 안됨

0개의 댓글