티스토리 뷰

728x90
반응형

도커 컨테이너 다루기

컨테이너를 외부에 노출

컨테이너는 가상 머신과 마찬가지로 가상 IP 주소를 할당 받는다. 기본적으로 도커는 컨테이너에 172.17.0.x의 IP를 순차적으로 할당한다.

아무런 설정을 하지 않았다면 이 컨테이너는 외부에서 접근할 수 없으며 도커가 설치된 호스트에서만 접근할 수 있다. 외부에 컨테이너의 애플리케이션을 노출하기 위해서는 eth0의 IP와 포트를 호스트의 IP와 포트에 바인딩해야 한다.

컨테이너에 아파치 웹서버를 설치하고 외부에 노출해보자.

$ docker run -i -t --name mywebserver -p 80:80 ubuntu:14.04

-p 옵션은 컨테이너의 포트를 호스트의 포트와 바인딩해 연결할 수 있게 설정한다. 호스트포트:컨테이너포트 형식으로 쓰면된다.

$ apt-get update
$ apt-get install apache2 -y
$ service apache2 start



컨테이너 애플리케이션 구축

한 컨테이너에 프로세스 하나만 실행하는 것이 도커의 철학.

데이터베이스와 워드프레스 웹 서버 컨테이너를 연동해 워드프레스 기반 블로그 서비스를 만들어보자.

$ docker run -d --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress mysql:5.7

$ docker run -d -e WORDPRESS_DB_PASSWORD=password --name wordpress --link wordpressdb:mysql -p 80 wordpress

$ docker ps
# 확인
$ docker port wordpress
# 호스트와 바인딩된 포트만 확인

첫 번째 명령어는 mysql 이미지를 사용해 데이터베이스 컨테이너를, 두 번째 명령어는 미리 준비된 워드프레스 이미지를 이용해 워드 프레스 웹 서버 컨테이너를 생성한다.

-d는 Detached 모드로 컨테이너를 실행한다. 컨테이너를 백그라운드에서 동작하는 애플리케이션으로써 실행하도록 설정하는것. Detached 모드인 컨테이너는 반드시 컨테이너에서 프로그램이 실행돼야 하며, 포그라운드 프로그램이 실행되지 않으면 컨테이너는 종료된다. mysql은 하나의 터미널을 차지하는 mysqld를, 워드프레스는 하나의 터미널을 차지하는 apache2-foreground를 실행한다.

-e 옵션은 컨테이너 내부의 환경변수를 설정한다.

mysql 컨테이너로 가서 환경변수를 출력해보자. exec 명령어를 사용해서 컨테이너 내부의 셀을 사용한다.

$ docker exec -i -t wordpressdb /bin/bash
root@a93sfef334g:/$ echo $MYSQL_ROOT_PASSWORD
password

exec 명령어를 사용하면 컨테이너 내부에서 명령어를 실행한 뒤 그 결괏값을 반환받는다. 거기에 -it 옵션을 추가해 /bin/bash를 상호 입출력이 가능한 형태로 exec 명령어를 사용한다. exit나 Ctrl + P+Q로 빠져나온다. mysqld 프로세스가 컨테이너 안에서 포그라운드 모드로 동작하기 때문에 exit를 써도 컨테이너는 종료가 안된다.

비밀번호처럼 민감한 정보를 컨테이너 내부의 환경 변수로 설정하는 것은 매우 바람직하지 않다. 이런 경우에는 도커 스웜 모드의 secret이나 쿠버네티스의 secret과 같은 기능을 활용해 안전하게 비밀번호를 전달하는 것이 좋다.

A 컨테이너에서 B 컨테이너로 접근하는 방법 중 가장 간단한 것은 NAT로 할당받은 내부 IP를 쓰는 것이다. 도커 엔진은 컨테이너에게 내부 IP를 172.17.0.2, 3, 4와 같이 순차적으로 할당한다. 근데 이건 컨테이너를 시작할 때마다 재할당하는 것이라 매번 변경되서 IP로 접근하기 힘들다. 따라서 --link 옵션은 내부 IP를 알 필요 없이 항상 컨테이너에 별명으로 접근하도록 설정한다. 즉 위에서 워드프레스 웹 서버 컨테이너는 wordpressdb의 IP를 몰라도 mysql이라는 호스트명으로 접근할 수 있게 된다.



도커 볼륨

mysql 컨테이너를 삭제하면 컨테이너 계층에 저장돼있던 데이터베이스의 정보도 삭제된다. 도커의 컨테이너는 생성과 삭제가 매우 쉬우므로 실수로 컨테이너를 삭제하면 데이터를 복구할 수 없게 된다. 이를 방지하기 위해 컨테이너의 데이터를 영속적 데이터로 활용할 수 있는 방법이 있다.

  • 호스트와 볼륨을 공유
  • 볼륨 컨테이너를 활용
  • 도커 관리 볼륨

호스트 볼륨 공유

$ docker run -d \
> --name wordpressdb_hostvolume \
> -e MYSQL_ROOT_PASSWORD=password \
> -e MYSQL_DATABASE=wordpress \
> -v /home/wordpress_db:/var/lib/mysql \
> mysql:5.7

$ docker run -d \
> -e WORDPRESS_DB_PASSWORD=password \
> --name wordpress_hostvolume \
> --link wordpressdb_hostvolume:mysql \
> -p 80 \
> wordpress

-v 옵션은 호스트의 디렉터리와 컨테이너의 디렉터리를 공유한다는 뜻이다. [호스트의 공유 디렉터리]:[컨테이너의 공유 디렉터리] 형태로 쓰면된다.

-v 옵션을 써서 컨테이너의 디렉터리를 호스터와 공유하면 각 디렉터리가 동기화가 되는것이 아닌 완전히 같은 디렉터리다.

볼륨 컨테이너

볼륨을 사용하는 두 번째 방법은 -v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는것. 컨테이너를 생성할 때 --volumes-from 옵션을 설정하면 -v 옵션을 적용한 컨테이너의 볼륨 디렉터리를 공유할 수 있다. 이건 직접 볼륨을 공유하는 것이 아닌 -v 옵션을 적용한 컨테이너를 통해 공유하는 것이다.

$ docker run -it \
--name volume_overide \
-v /home/wordpress_db:/home/testdir_2 \
alicek106/volume_test

root@234ijlf3234li:/$ ls /home/testdir_2/
auto.cnf ib_buffer_pool ... 
... ... ... ... ...


나와서

$ docker run -it \
--name volumes_from_container \
--volumes-from volume_overide \
ubuntu:14.04

root@123dskfj34:/$ ls /home/testdir_2/
auto.cnf ib_buffer_pool ... ...
... ... ... ... ...

이 예제는 volume_overide 컨테이너에서 볼륨을 공유받는 경우이다. volume_overide 컨테이너는 /home/testdir_2 디렉터리를 호스트와 공유하고 있으며, 이 컨테이너를 볼륨 컨테이너로서 volumes_from_container 컨테이너에 다시 공유하는 것이다.

지금까지 적용한 컨테이너 사이의 관계는 아래와 같다.

example

이러한 구조를 활용하면 호스트에서 볼륨만 공유하고 별도의 역할을 담당하지 않는 일명 '볼륨 컨테이너'로서 활용하는것도 가능하다. 즉, 볼륨을 사용하려는 컨테이너에 -v 옵션 대신 --volumes-from 옵션을 사용함으로써 볼륨 컨테이너에 연결해 데이터를 간접적으로 공유받는 방식

도커 볼륨

세 번째 방법은 docker volume 명령어를 사용하는 것. 볼륨을 다루는 명령어는 docker volume으로 시작하며, docker volume create 명령어로 볼륨을 생성한다. 다음 명령은 myvolume이라는 볼륨을 생성한다.

$ docker volume create --name myvolume 
myvolume

$ docker volume ls

다음 명령어를 입력해 myvolume이라는 볼륨을 사용하는 컨테이너를 생성한다.([볼륨의 이름]:[컨테이너의 공유 디렉터리])

$ docker run -it --name myvolume_1 \
-v myvolume:/root/ \
ubuntu:14.04

root@9ef3f23455:~$ echo hello, volume! >> /root/volume

/root 디렉터리에 volume이라는 파일을 생성했다. 다른 컨테이너도 myvolume 볼륨을 쓰면 볼륨을 활용한 디렉터리에 volume 파일이 존재할 것이다. 컨테이너에서 호스트로 빠져나온 뒤 또 다른 하나의 컨테이너를 생성해 확인해보자.

$ docker run -it --name myvolume_2 \
-v myvolume:/root/ \
ubuntu:14.04

root@9ef3f23455:~$ cat /root/volume
hello, volume!

docker volume 명령어로 생성한 볼륨은 아래 그림과 같은 구조로 활용된다.

example

볼륨은 디렉터리 하나에 상응하는 단위로서 도커 엔진에서 관리한다. 도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제로 어디에 저장되는지 사용자는 알 필요가 없다.

docker inspect 명령어를 사용시 myvolume 볼륨이 실제로 어디에 저장되는지 알 수 있음.

$ docker inspect --type volume myvolume
[
    {
        "CreatedAt": "2021-05-18T00:42:03+09:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myvolume/_data",
        "Name": "myvolume",
        "Options": {},
        "Scope": "local"
    }
]

docker volume create 명령을 별도로 입력하지 않아도 -v 옵션을 입력할 때 이를 수행하도록 설정할 수 있다.

$ docker run -it --name volume_auto \
-v /root \
ubuntu:14.04

도커 볼륨을 사용하고 있는 컨테이너를 삭제해도 볼륨이 자동으로 삭제되지는 않는다. 사용되지 않는 볼륨을 한꺼번에 삭제하려면 docker volume prune 명령어를 사용한다.

$ docker volume prune

이렇게 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계하는 것을 stateless하다고 말한다. 컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공받는다. 컨테이너가 삭제돼도 데이터는 보존되므로 스테이트리스한 컨테이너 설계는 도커를 사용할 때 매우 바람직한 설계이다.

이와 반대는 stateful하다고 말하는데 이런 설계는 지양하는게 좋음.





출처
시작하세요! 도커/쿠버네티스(용찬호 저, 위키북스)
example

728x90
반응형
댓글
반응형
250x250
글 보관함
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday
링크