지난번에 도커가 어떻게 나왔고, 어떤 구성으로 되어있는지 간략하게 봤다면, 이번에는 도커에서 로깅이나 데이터를 관리할 때 사용하게 되는 Volumn과 네트워크에 대해 알아보고 가겠습니다.
이번 편은 참고한 자료의 양이 방대하고 자세히 나와있지만 필요한 부분만 요약 및 정리했기 때문에 자세히 보고 싶으시다면 아래 참고 링크를 확인해 주시면 감사하겠습니다.
도커의 Image 구성
도커의 이미지는 여러 layer로 이루어져 있는데요. 이에 대해 한 번 자세히 알아보겠습니다.
도커의 이미지는 Docker hub에 저장하고 사용할 수 있도록 하는 경우가 많습니다. 이러한 이미지는 다운 받는 순간부터 많은 정보를 주는데 이 부분부터 확인해 보겠습니다.
docker pull mysql:latest

현재 mysql의 최신버전을 다운 받는 상태인데 여러 개가 보입니다.
[ Pull한 위치 ]
또한 다운받게 되면 마지막에 어디에서 가져왔는지 보여주며 docker.io/library
를 나타내는데,
docker의 경우 기본 저장소를 docker.io로 하기 때문에 mysql:lastest또한 기본 저장소에서 찾아서 가져오게 되는 것입니다.
그럼 여기서 생각할 수 있는 의문은 '어? mysql을 저렇게 해서 가져온 거면, 동일한 이름으로 내가 직접 만들면 내 이미지를 가져올 수 있겠네?'
네, 맞습니다! 이미지 자체가 고유 번호를 의미하는 것이 아니기 때문에 이러한 점을 유의해야 합니다.
[ layer들의 모임: 이미지 ]
다운 받는 순간 여러 해쉬코드 값들이 보이고 pull complete가 나오는데 이는 하나의 이미지가 여러 layer로 이루어져 있다는 것을 보여줍니다.

이렇게 pull한pull 한 layer들은 다시 컨테이너로 실행하게 될 때 쌓아서 실행하게 되는데 pull 한 layer들 순서대로 쌓입니다.
또한, 이러한 layer들은 전부 read Only라는 점입니다.
그럼 이 layer들이 뭐를 나타내는 거지? 라고 생각하실 수 있는데

위와 같이 각 Image파일을 구성하기 위해 작성했던 명령문 한 줄 한 줄 이 layer로 들어갔습니다.
이제 layer들이 뭔지 알았고 여러 레이어들로 구성되어 있는 것까지 알겠는데, 그럼 read-only만 있는 거야?
라고 생각할 수 있지만
read-write가 가능한 부분이 있습니다.

이미지를 실행시키면 layer들이 쌓여 컨테이너가 만들어지고 마지막으로 가장 위에 read-write가 가능한 layer가 한 개더 생성됩니다.
도커 Image 실행
지금 까지 이미지가 어떻게 구성하고 있는지 봤다면, 도커가 이러한 이미지를 어떻게 올리는지에 대해 알아보겠습니다.
간단하게 알고 가야 할 부분은 chroot
입니다.
chroot
는 루트 디렉터리를 바꾼다.라고 생각하면 됩니다.

리눅스에서 file tree를 보면 위와 같이 root 디렉터리에서 접근이 다른 폴더를 접근이 가능하게 되어 있는데요.
이미지를 실행하여 컨테이너를 만들게 되면

아래와 같이 Container B자체가 root dir로 사용하여 각 컨테이너를 분리하여 사용할 수 있게 됩니다.
정리하자면,
Image를 실행시키면, Image를 토대로 새로운 Container를 만드는데, 컨테이너를 만들 때 read-wirte에 대한 layer를 추가한다. 이후 이 컨테이너는 os 커널에서 제공하는 root가 아닌, Container가 root path가 되며 해당 container에서만 사용할 수 있도록 분리가 된다.
추가적을 궁금할 수 있는 부분은 리눅스에는 여러 버전이 있는데 이런 것도 설정이 가능할까?
네 가능합니다. 제공 목록
여러 os 및 각 os에 대해서도 버전마다 다르게 제공됩니다.
아래는 도커 실행에 대한 명령어와 mysql을 사용할 때 필요 옵션입니다.
docker run -d -p 3306:3306 --name my-mysql -e MYSQL_ROOT_PASSWORD=test mysql:latest
컨테이너에서 이미지 뽑기
이렇게 컨테이너에 올리게 된다면 추가적으로 설치가 필요한 것들이 있을 수 있다.
예를 들어
docker pull nginx:latest
docker run nginx
docek exec -it [내 Nginx name] /bin/bash
를 하면 nginx의 root로 접속할 수 있다.
여기서 만약 어떤 파일을 찾기 위해 mlocate라는 패키지를 다운로드하고자 한다고 하자 그럼 mlocate가 처음 없으므로
not found가 뜰 것입니다


따라서 설치가 필요하기 때문에
apt-get update
apt-get install mlocate
updatedb
를 하여 찾으면 나오게 됩니다. 이렇게 mlocate를 기본으로 이제 사용하고 싶다고 가정하겠습니다.
이런 상황에서는 어떻게 해야 할까요?
commit
을 통해 새로운 image를 저장하시면 됩니다.
그럼 먼저 변경사항부터 보면

이렇게 변경된 사항들을 전부 적용하여 새로운 Imagge를 만들기 위해서
아래와 같이 진행하게 되면

docker ps
docker commit [containerId] [새로운 이미지]
새로운 image를 만들게 되는데, Docker Desktop에서 보면

정상적으로 만들어진 것을 볼 수 있습니다.
이제 새로운 환경에서 동작되는 것을 확인하기 위해
docker run nginx:new
이렇게 실행을 하고 접속을 하면

test.txt파일도 추가되어 있고, 정상적으로 파일을 찾는 것을 확인할 수 있습니다.
여기서 추가적으로 주의해야 할 점은 이렇게 새롭게 추가된 layer는 readOnly로 변경된 다는 것입니다.
도커 volume
위에서도 말씀드렸지만, docker container가 올라가면 read-write공간이 생기지만, 종료 시 사라진다는 단점이 있었습니다.
우리가 log와 같은 파일을 보전해야 하는 일이 필요한데 이러한 역할을 해주는 것이 도커의 Volumn입니다.
사실 도커에서는 volume말고도 여러 저장 환경을 제공해 줍니다. 이에 대해 알아보죠

1. Volumn
도커에 의해 생성되는 저장소입니다. 따라서 도커에 의해 관리가 되고, 호스트 디렉터리에서 Docker Volumn을 생성하여 따로 지정한 컨테이너 폴더와 마운트되어 사용하게 됩니다.
또한 명시적으로도 생성이 가능하지만, 서비스 생성 중에 자동으로 볼륨을 생성하게 됩니다.
먼저 volume을 생성해야 합니다.

이렇게 Host에서 사용할 수 있는 volume이 생성되게 되고, 여기서
마운트를 위해
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=test --name my-mysql --mount source=my-volume,target=/var/lib/mysql mysql:latest
이런 식으로 값을 넣어주시면 됩니다.
Source는 내 volume, target은 마운트 할 게스트 디렉터리인데, mysql의 경우 /var/lib/mysql에 할당해 주시면 됩니다.
*추가적으로
Dockerfile에서 VOLUME
명령어를 지원해 주는데, 이는 docker에서 데이터를 저장할 때 컨테이너가 종료되어도 데이터는 유지하게 하기 위해 마운트를 할 수 있게 도와줍니다. 이 또한 Volume
과 동일한 방식이어서, 로컬에 마운트 하는 것이 아니라 docker에 마운트를 하게 됩니다.

위는 /tmp에 volume을 설정한 결과입니다.
하지만 이 방식은 예전에 지원하던 방식으로 최근에는 파라미터나 docker-compose에서 확장된 기능으로 제공합니다.
2. Bind mount
Volumn과 비슷한 기능을 하지만, 제한적으로 동작합니다. 로컬 경로를 통해 컨테이너를 마운트를 합니다. 따라서 컨테이너에서 생기는 데이터를 로컬에서 바로 볼 수 있습니다. 하지만 컨테이너 내에서 실행되는 프로세스를 통해 호스트 파일 시스템을 변경할 수 있다는 점이 보안상 문제가 됩니다.
3. tmpfs
컨테이너 내에서만 지속이 되기 때문에 컨테이너가 종료가 되면 정보들을 삭제하게 됩니다. 따라서 중요한 정보들이 해당 경우에 많이 저장되게 됩니다.
도커의 네트워킹
도커는 하나의 서비스에서 내부적으로 연결하거나 외부에서 접근할 수 있도록 네트워크 관련 기능을 제공합니다.
도커 자체가 기본적으로 네트워킹에 대해서 제공해 주므로 간단하게 알아만 보겠습니다. 자세한 내용은 참고 링크를 확인해 주세요.
1. Bridge 네트워크
bridge뜻 그대로 다리역할을 하는 네트워크입니다. 동일한 네트워크를 구성하게 되는 컨테이너들을 서로 통신할 수 있게 도와주며, 다른 브리지 네트워크와의 연결은 분리시켜 줍니다.
브릿지 네트워크도 세부적으로는 Custom 브릿지 네트워크
와 기본 브릿지 네트워크
가 있는데 custom이 기본에 비해 자동으로 DNS를 제공하여 좀 더 원활한 네트워크 간 분할을 도와줍니다.
Overlay같이 하나의 클래스터 내에서 여러 도커 호스트를 swarm으로 관리하는 등의 방식을 찾아보던 중 현재 너무 깊어지는 관계로 이 부분에 대해서는 생략했습니다. 추후 알아볼 예정입니다.
참고 링크
만들면서 이해하는 도커(Docker) 이미지: 도커 이미지 빌드 원리와 OverlayFS | 44BITS
Volumes | Docker Documentation
Networking overview | Docker Documentation
134. [Docker] Deep Dive into Docker Overlay Network 1편 (VXLAN) : 네이버 블로그 (naver.com)
'사용기 > 도커' 카테고리의 다른 글
[도커 사용기] 2 - Docker Compose로 배포 환경 구성 (0) | 2023.07.30 |
---|---|
[도커 사용기] 1 . 도커란? (0) | 2023.07.29 |