본문 바로가기

Docker

컨테이너 포트 포워딩 [정리]

컨테이너 포트 포워딩

도커는 iptables의 NAPT 기능을 통해 트래픽 제어를 한다. 이를 이용해서 단일 ip로 여러 개의 컨테이너에 대한 트래픽 1:N 매핑이 가능하다.

실습 컨테이너 일괄 삭제

docker rm -f `docker ps -q --filter name=my-ubuntu*`

컨테이너 생성

docker run -itd --name my-ubuntu -p 1234:1234 -p 5000:8080 -p 3000:3333 ubuntu:22.04
docker run -itd --name my-nginx -p 8888:80 nginx:latest

컨테이너 포트 정보 확인

docker ps
docker port my-ubuntu
docker port my-nginx

컨테이너 접근 확인

nc -v localhost 8888
# ctrl + c 로 빠져나오기

iptables 확인

iptables의 테이블 리스트

  • filter : 규칙 기반 패킷 필터용
  • nat : source, destination 등을 변경하는 경우의 규칙 정의 용도
  • mangle
  • raw

Chain

chain은 패킷이 흐르는 규칙의 순서를 의미

  • INPUT chain : 들어오는 패킷을 처리하는 규칙
  • OUTPUT chain : 나가는 패킷을 처리하는 규칙
  • FORWARD chain : 전달되는 패킷을 처리하는 규칙

NAT

  • POSTROUTING : Source NAT(SNAT) 타겟과 매칭되어 내부 네트워크에서 방화벽을 통해 외부로 나갈 때 사용
  • PREROUTING : Destination NAT(DNAT) 타겟과 매칭되어 주로 외부에서 방화벽 내부 서버로 향하는 패킷을 포워딩 할 때 사용
  • OUTPUT : nat 테이블을 빠져나갈 때 사용

filter table(default) 확인

iptables -L -v -n

Chain DOCKER 의 내용을 확인해보면 docker0 인터페이스로 들어오는 트래픽을 제외한 0.0.0./0 모든 ip 대역의 요청에 대해 컨테이너 타겟 포트로 가는 것을 허용한다는 규칙이 생겨있다.

nat table 확인

iptables -t nat -L -v -n

Chain DOCKER 의 내용을 확인해보면 docker0 인터페이스로 들어오는 트래픽을 제외한 0.0.0./0 모든 ip 대역의 요청에 대해 목적지 포트를 변경해주는 DNAT 규칙이 생겨있는 것을 확인할 수 있다.

ec2의 경우 보안 그룹에 nginx 컨테이너의 외부 노출 포트(8888/TCP)를 열어주면 해당 포트로 nginx 접근이 가능해진다.


볼륨

컨테이너는 기본적으로 내부에서 생성된 모든 파일은 쓰기 가능한 컨테이너 레이어에 저장함

이는 다음을 의미.

  • 컨테이너가 삭제되면 데이터도 같이 삭제됨
  • 다른 프로세스에서 필요한 경우 데이터를 가져오는 것이 어려움
  • 컨테이너의 쓰기 레이어는 호스트 시스템과 긴밀하게 연결되어 있음. 때문에 데이터를 다른 곳으로 쉽게 이동할 수 없음.
  • 컨테이너 쓰기 레이어에 데이터를 쓰기 위해서는 스토리지 드라이버가 필요함. 스토리지 드라이버의 사용은 Linux 커널 사이의 추상화 계층이 추가되어 성능 저하를 일으킴.
    • 볼륨 사용 시 호스트 시스템에 직접 데이터를 쓰기 때문에 이러한 오버헤드가 없음

데이터를 유지하는 방법은 크게 3가지 방식이 있음

  • volume : 호스트 파일 시스템의 일부에 저장됨(/var/lib/docker/volumes/). 가장 권장되는 방식. 여러 컨테이너 간 데이터를 공유하는 경우에도 유용함.
  • bind mount : 호스트 시스템의 마운트 경로를 지정할 수 있음. 단, 항상 컨테이너의 경로를 덮어쓰기 때문에 사용 사례에 따라 적절하지 않을 수 있음(이미지의 해당 경로에 사전에 준비되어 있는 데이터가 있는 경우)</aside>
  • <aside> 💡 bind mount 사용 시 호스트 시스템의 중요한 파일을 수정하거나 삭제할 수 있는 부작용이 있으므로 주의해야 함.
  • tmpfs mount : 호스트 시스템의 메모리에 데이터를 저장하는 방식. 따라서 휘발성이기 때문에 비지속적 상태의 데이터 혹은 민감 정보를 저장하는 데 사용할 수 있음. 메모리 영역이기 때문에 컨테이너 간 공유할 수 없음.

실습 컨테이너 일괄 삭제

docker rm -f `docker ps -q --filter name=my-ubuntu*`

1. volume

볼륨 생성

docker volume create my-volume

볼륨 생성 확인

docker volume ls
docker inspect my-volume

컨테이너 생성

docker run -itd --name my-ubuntu3 -v my-volume:/opt/data ubuntu:22.04

볼륨 확인

docker exec -it my-ubuntu3 bash
cd /opt/data

데이터 생성

echo "this is test data" > test.txt
exit

컨테이너 삭제 후 재생성

docker rm -f my-ubuntu3
docker run -itd --name my-ubuntu -v my-volume:/opt/data ubuntu:22.04

볼륨 재확인

docker exec -it my-ubuntu bash
cat /opt/data/test.txt
exit

호스트 시스템 볼륨 확인

cd /var/lib/docker/volumes/my-volume/_data
ls
cat test.txt

이 데이터는 지워지지 않고 계속 쌓이므로 필요에 따라 docker volume prune 명령으로 사용하지 않는 컨테이너의 볼륨을 정리할 수 있음

2. bind mount

마운트 경로 생성

# ubuntu 계정 쉘으로 수행
cd ~ # /home/ubuntu
mkdir -p my-volume/data
cd my-volume/data
echo "this is test data" > test.txt
cat test.txt

컨테이너 생성

-v <호스트 시스템 경로>:<컨테이너 경로> 로 마운트 할 수 있으며 호스트 시스템 경로는 절대경로여야 한다. 컨테이너에 이미 해당 경로가 있으면 해당 경로를 덮어쓴다.

docker run -itd --name my-ubuntu2 -v /home/ubuntu/my-volume:/opt/ ubuntu:22.04

볼륨 확인

docker exec -it my-ubuntu2 bash
cat /opt/data/test.txt
exit

3. tmpfs mount

--tmpfs 혹은 --mount 옵션으로 사용 가능하지만 --mount 옵션을 권장함.

컨테이너 생성

docker run -itd --name my-ubuntu3 --mount type=tmpfs,destination=/opt/data ubuntu:22.04

확인

docker inspect my-ubuntu3 --format '{{ json .Mounts }}'

컨테이너 내부 경로 확인 및 쓰기 작업 테스트 해볼 것

'Docker' 카테고리의 다른 글

다양한 도커 이미지 실행해보기 [정리]  (0) 2024.07.17
볼륨 [정리]  (0) 2024.07.17
네트워크 구성 확인 & 생성 [정리]  (0) 2024.07.17
이미지 & 컨테이너 [정리]  (0) 2024.07.17
Docker 설치 [정리]  (0) 2024.07.17