Docker와 VM의 차이
* VM : Virtual Machine 가상 머신으로, 분할 공간의 가상 환경을 제공한다.
* 호스트 OS : 서버 OS
* 게스트 OS : VM이 서버 OS위에 올리는 가상 OS
* 하이퍼바이저 : 게스트 OS를 구동하고 모니터링하는 소프트웨어
-> 유형 1 : Native/Bare-Metal 하이퍼바이저, 호스트 OS 없이 게스트 OS들만 존재
ex. VMware의 ESXi, Citrix의 Xen, Microsoft의 Hyper-V
-> 유형 2 : Hosted 하이퍼바이저, 호스트 OS 위에 게스트 OS들을 둔다.
ex. VmWare의 Workstation, Oracle의 VirtualBox
가상 머신(VM)의 경우, 하이퍼바이저를 통해 호스트 OS 위에 게스트 OS들을 두거나, 호스트 OS 없이 게스트 OS들을 사용할 수 있도록 분할된 가상 환경을 제공한다. 이 경우, 각각의 분할된 OS 마다 자원을 할당해주어야 한다.
도커(Docker)의 경우, 이와 달리 하나의 호스트 OS 의 커널을 각각의 컨테이너가 공유하는 형태를 띈다.
Docker의 컨테이너가 독립된 공간을 가질 수 있는 이유
Docker는 기본적으로 리눅스를 기반으로 만들어진 오픈 소스 프로그램이다.
리눅스 커널의 Cgroup은 프로세스들이 쓸 수 있는 사용량을 제한하며, Name space는 각 프로세스가 볼 수 있는 범위를 제한한다. (자세한 내용은 아래 참고 링크 확인) 도커는 이러한 리눅스의 특성을 활용해 Container를 구성했고, 각 Container는 따라서 마치 게스트 OS와 같이 독립된 공간을 가질 수 있다.
리눅스에서 Docker 설치하기
나는 윈도우를 쓰고 있지만 도커는 Linux 기반이기에...
오라클 클라우드 리눅스 OS에 접속해 아래와 같이 Docker를 설치해줬다.
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce
systemctl start docker
docker --version
OS가 리눅스가 아니면 홈페이지를 통해 Docker를 다운받을 수도 있었다.
https://www.docker.com/get-started/
Docker를 통해 컨테이너 생성
docker run -i -t --name [db이름] -e MYSQL_ROOT_PASSWORD="비밀번호" -d persona:5.7.30
// -it : 컨테이너에 쉘로 접속하기 위한 옵션
// --name : 컨테이너 이름 할당
// -e : 환경변수 세팅
// -d : 백그라운드로 컨테이너 실행
> Docker는 image만 있다면 어디서든지 컨테이너 생성이 가능하다.
> 컨테이너는 가상 머신과 마찬가지로 가상 IP 주소를 할당 받으며, 기본적으로 172.17.0.x의 IP를 순차적으로 할당한다.
docker run -it --name network_test ubuntu:14.04
* 위와 같이 -p 옵션이 없이 docker를 실행하면, 이 컨테이너는 외부에서 접속을 할 수 없고, 호스트에서만 접속이 가능하다.
> 따라서, 외부에서 접근을 할 수 있도록 하려면 이 컨테이너에 -p 옵션을 두고 {호스트port}:{도커port} 로 연결하거나, {외부IP:port}:{도커port} 로 연결하도록 해야한다.
docker run -it --name network_test -p {ip:port}:{port} ubuntu:14.04
원격으로 MySQL Container 접속하기
호스트의 3306 포트에서 컨테이너의 3306 포트로 연결하여, 호스트에서 컨테이너의 mysql를 접속할 수 있게 한다면,
아래와 같이 코드를 작성하면 된다.
-- docker container 생성
docker run -it --name db001 -e MYSQL_ROOT_PASSWORD="root" -p 3306:3306 -d percona:5.7.30
-- percona에서 mysql 이미지를 다운로드한다.
https://docs.percona.com/percona-server/8.0/yum-download-rpm.html
> 이제 호스트OS 3306에서 컨테이너 3306로 MySQL 접속이 가능하게 됐다.
> 하지만 위의 경우, 컨테이너를 삭제하면 컨테이너 계층의 mysql 데이터 또한 삭제되게 된다. mysql 처럼 데이터의 영속성이 중요한 경우 이와 같이 컨테이너-영속성 데이터가 종속관계가 되어서는 안된다.
* mysql의 데이터는 기본적으로 /var/lib/mysql 경로에 저장하는데,
Docker 컨테이너 안의 /var/lib/mysql 에 데이터가 저장되어, 컨테이너를 삭제하면 /var/lib/mysql 데이터가 유실된다.
> 이를 막기 위한 방법은, 컨테이너와 독립적으로 데이터를 저장하는 것이다. 이때, 볼륨이라는 개념을 이해해야하는데, 볼륨은 운영체제에서 논리 드라이브(local drive)라고도 불리는 것으로, SSD와 같은 물리 드라이브와 달리 논리적으로만 존재하는 드라이브를 말한다. 대표적으로 C드라이브가 이 볼륨에 해당된다.
> 볼륨을 컴퓨터가 사용할 수 있도록 적용하는 과정을 마운트라고 하는데, 컨테이너가 삭제되더라도 데이터를 유지하기 위해서는, 호스트 OS로부터 컨테이너로 볼륨를 마운트해야 한다.
> 볼륨을 마운트하는 방법은 크게 세가지가 있다.
1) 호스트와 볼륨을 공유하는 방법
2) 볼륨 컨테이너를 활용하는 방법
3) 도커가 관리하는 볼륨을 사용하는 방법
Docker Volume
1. 호스트와 볼륨 공유
-v 옵션을 통해 호스트 OS의 특정 디렉토리와 컨테이너의 특정 디렉토리를 공유할 수 있다.
// 먼저 호스트에 디렉토를 생성한다.
mkdir -p /db/db001/data
// 호스트 디렉토리의 권한을 수정한다.
chmod 777 /db <-- /db 하위 폴더까지 권한 수정
// -v {호스트디렉토리}:{컨테이너디렉토리}
docker run -it --name db001 -p 3306:3306 \
-v /db/db001/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
2. 도커 볼륨
이건 percona 사이트에서 권장하는 방식이기도 한데,
* percona에서 권장하는 docker를 통한 mysql 설치 https://docs.percona.com/percona-server/8.0/quickstart-docker.html
먼저 docker volume create로 볼륨을 생성한다.
docker volume create --name {볼륨 이름}
그리고 나서 volume ls로 볼륨을 조회하면 아래와 같이 볼륨 내역이 나타난다.
[root@sideproject opc]# docker volume ls
DRIVER VOLUME NAME
local ec9de5f4574d28879fead241b36addffc99ae8390048546c07ac2067265e8e56
local mysqlVolume
local myvol
이후 docker run과 함께 -v 옵션에 {호스트의 volume 이름}:{컨테이너 경로}를 넣어주면 Container안의 /var/lib/mysql 경로와 호스트의 /var/lib/docker/volumes/{볼륨이름}/_data와 마운트를 해준다.
docker run -it --name db001 -p 3306:3306 \
-v myvolume:/var/lib/mysql\
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
// 옵션 설명
// --name : 컨테이너 이름
// -d : detached container (백그라운드에서 동작한다)
// -e : 환경설정
// --volume : 영속적인 데이터베이스 스토리지 생성
아래의 명령어를 통해 확인해보니, /var/lib/docker/volumes의 하위로 호스트 경로가 생성되는 걸 볼 수 있었다.
[root@sideproject opc]# docker inspect --type volume mysqlVolume
[
{
"CreatedAt": "2023-12-28T13:48:57Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysqlVolume/_data",
"Name": "mysqlVolume",
"Options": null,
"Scope": "local"
}
]
이제 도커로 mysql에 접속을 해본다. 접속이 잘된다.
docker exec -it psmysql mysql -uroot -p
호스트에서 cd로 /var/lib/docker/volumes/{볼륨이름}/_data로 가니 mysql 데이터가 나타난다.
[root@sideproject _data]# ll
total 96708
-rw-r-----. 1 1001 1001 56 Dec 28 14:45 auto.cnf
-rw-r-----. 1 1001 1001 180 Dec 28 14:46 binlog.000001
-rw-r-----. 1 1001 1001 16 Dec 28 14:46 binlog.index
-rw-------. 1 1001 1001 1705 Dec 28 14:45 ca-key.pem
-rw-r--r--. 1 1001 1001 1120 Dec 28 14:45 ca.pem
-rw-r--r--. 1 1001 1001 1120 Dec 28 14:45 client-cert.pem
-rw-------. 1 1001 1001 1705 Dec 28 14:45 client-key.pem
-rw-r-----. 1 1001 1001 196608 Dec 28 14:46 #ib_16384_0.dblwr
-rw-r-----. 1 1001 1001 8585216 Dec 28 14:45 #ib_16384_1.dblwr
-rw-r-----. 1 1001 1001 5625 Dec 28 14:46 ib_buffer_pool
-rw-r-----. 1 1001 1001 12582912 Dec 28 14:46 ibdata1
-rw-r-----. 1 1001 1001 12582912 Dec 28 14:46 ibtmp1
drwxr-x---. 2 1001 1001 4096 Dec 28 14:46 #innodb_redo
drwxr-x---. 2 1001 1001 187 Dec 28 14:46 #innodb_temp
drwxr-x---. 2 1001 1001 143 Dec 28 14:45 mysql
-rw-r-----. 1 1001 1001 31457280 Dec 28 14:46 mysql.ibd
drwxr-x---. 2 1001 1001 8192 Dec 28 14:45 performance_schema
-rw-------. 1 1001 1001 1705 Dec 28 14:45 private_key.pem
-rw-r--r--. 1 1001 1001 452 Dec 28 14:45 public_key.pem
-rw-r--r--. 1 1001 1001 1120 Dec 28 14:45 server-cert.pem
-rw-------. 1 1001 1001 1705 Dec 28 14:45 server-key.pem
drwxr-x---. 2 1001 1001 28 Dec 28 14:46 sys
-rw-r-----. 1 1001 1001 16777216 Dec 28 14:46 undo_001
-rw-r-----. 1 1001 1001 16777216 Dec 28 14:46 undo_002
3. 묵시적인 볼륨 생성
-v 옵션으로 컨테이너 경로만 적어주고 볼륨명은 설정하지 않을 수도 있다.
이 경우, ddab0e38151fcbf21f049846c07c081c8c7b111ace4217afed91cd9014e81ab4 와 같이 볼륨명이 자동으로 생성된다. 호스트 경로에 위 볼륨명이 같이 붙기 때문에 경로가 엄청 길어져서 별로 권장되지는 않는 방식이다.
docker run -it -p 3306:3306 \
--name mysqlVolumeAuto \
-v /db/db001/data3 \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
[정리해보기] Docker 명령어 모음
// 컨테이너 풀
docker pull ubuntu:16.04
// 포어그라운드 실행
docker run -i -t ubuntu:16.04 bin/bash
// 이름 할당
docker run -i -t --name my_ubuntu ubuntu:16.04 /bin/bash
// 컨테이너 포트 포워딩
docker run -i -t --name my_ubuntu -p 80:80 /bin/bash
// 데몬으로 실행
docker run -d -p 80:80 nginx
// 컨테이너 종료
exit
// 컨테이너 나오기
Ctrl + P,Q
// 컨테이너 목록 확인
docker ps -a(모두확인)
// 컨테이너 중지
docker stop my_ubuntu
// 컨테이너 중지 및 삭제
docker rm -f my_ubuntu
// 컨테이너 종료 시 자동 삭제
docker run -i -t --rm my_ubuntu ubuntu:16.04
// 이미지 목록
docker images
// 이미지 삭제
dockr rmi ubuntu:16.04
[출처 : https://dongle94.github.io/docker/docker-basic-use/ ]
참고
https://developer-cheol.tistory.com/29
3. Docker Volume (tistory.com)
https://selog.tistory.com/entry/%EA%B0%80%EC%83%81%ED%99%94-%EA%B0%80%EC%83%81%EB%A8%B8%EC%8B%A0VM%EA%B3%BC-%ED%95%98%EC%9D%B4%ED%8D%BC%EB%B0%94%EC%9D%B4%EC%A0%80-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0
https://velog.io/@whattsup_kim/Linux-Kernel-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%A6%AC%EB%88%85%EC%8A%A4%EC%9D%98-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B2%A9%EB%A6%AC-%EA%B8%B0%EB%8A%A5-cgroup-namespace-union-mount
https://velog.io/@kdaeyeop/%EB%8F%84%EC%BB%A4-Docker-%EC%99%80-VM%EC%9D%98-%EC%B0%A8%EC%9D%B4
'Infra > Docker' 카테고리의 다른 글
[Docker] Proxy Layer 구성하기 (2) | 2024.01.08 |
---|---|
[Docker] Orchestra를 통해 High Availability(HA) 구축하기 (1) | 2024.01.08 |
[Docker] 브리지를 통해 컨테이너 통신 (1) | 2024.01.08 |
[Docker] Master-Slave Replication 구성 (0) | 2023.12.31 |
[Docker] 호스트OS에 log, config 연결 (+my.cnf) (1) | 2023.12.29 |