생활코딩 도커 입구수업을 듣고 정리한 글입니다.
내 컴퓨터에서 애플리케이션을 만들려면? 운영체제에 여러 소프트웨어를 깔아야 한다.
웹서버, 데이터베이스 등등.. 이것들은 매번 설치하는게 너무 까다롭다!
애플리케이션을 개발하기 위한 환경. 어떻게 구성하면 좋을까?
비싸다
겨우 웹서버를 운영하기위해서 운영체제를? 운영체제 위에 몇개의 운영체제가 있는거야
이미 존재하는 운영체제를 공유하므로 추가 설치에 대한 어려움이 없다.
운영체제가 하나니까 속도도 빠르다.
저장장치의 용량을 아낄 수 있다.
우리는 일반적으로 app store로부터 설치하고 싶은 program을 탐색하고 원하는 program을 설치한다. 그리고 program을 실행하면 process가 생성이 된다. 마찬가지로 docker hub로부터 우리는 원하는 image를 탐색하고 image를 다운받아서 실행하면 container가 실행된다.
그림3-1. docker hub - image - container
app store
-docker hub
, program
-image
, process
-container
에 대응된다.docker hub
로부터 image
를 다운받는는 행위를 pull
이라고 한다.image
를 실행시키는 행위를 run
이라하며 이를 통해 image
가 container
로 바뀐다.container
안에 포함되어있는 실행되도록 조치되어있는 프로그램이 실행이 된다.command: docker pull httpd
docker pull httpd
이미지를 다운로드 했다면 docker 기본 명령어를 통해 컨테이너를 실행하고 상태를 확인해보자
docker run httpd # 컨테이너 생성 및 실행
docker run --name ws2 httpd # 컨테이너 이름(ws2)을 지정하면서, 생성 및 실행
docker ps # 현재 실행중인 컨테이너 확인
docker stop ws2 # ws2 컨테이너를 중지
docker start ws2 # ws2 컨테이너를 시작
docker logs ws2 # ws2 컨테이너의 로그 출력
docker logs -f ws2 # ws2 컨테이너의 로그 출력(와칭)
docker rm ws2 # ws2 컨테이너를 삭제 (stop된 컨테이너만 가능)
docker rm --force ws2 # ws2컨테이너를 삭제(stop을 하지 않고도 삭제할 수 있다.)
docker rmi httpd # httpd이미지를 삭제
docker docs
우리는 도커의 명령어를 통해 아파치를 실행하였다. 주의해야할 것은 도커가 설치되어 있는 호스트와 컨테이너간에는 별도의 포트 및 파일시스템이 존재한다는 점이다.
일반적으로 클라이언트로부터 http요청을 받게되면 아파치 웹서버는 80포트에서 대기하다가 응답을 준다. 현재 우리가 실행한 아파치서버도 동일하게 동작할까? 아니다. 도커 Host와 도커 Container가 격리되어 있고 연결이 되어있지 않기 때문이다.
때문에 도커를 사용할 경우에는 포트포워딩을 통해 도커 호스트와 도커 컨테이너간의 연결이 필요하다. 이는 기존의 실행 명령어였던 docker run httpd
→ docker run -p 80:80
httpd로 수정해서 옵션값에 도커 Host, 도커 Container에 대한 포트를 입력해 연결할 수 있다.
그림 5-1. 도커 Host와 도커 Container
그림 5-2. 포트 변경
도커 컨테이너에서 포트포워딩을 적용해서 아파치 웹서버 실행
$ docker pull httpd
$ docker run --name ws3 -p 8081:80 httpd
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Sat Sep 04 12:57:25.189271 2021] [mpm_event:notice] [pid 1:tid 281473784407408] AH00489: Apache/2.4.48 (Unix) configured -- resuming normal operations
[Sat Sep 04 12:57:25.189345 2021] [core:notice] [pid 1:tid 281473784407408] AH00094: Command line: 'httpd -D FOREGROUND'
^C[Sat Sep 04 12:57:37.032332 2021] [mpm_event:notice] [pid 1:tid 281473784407408] AH00491: caught SIGTERM, shutting down
실행중인 도커 컨테이너 확인 컨테이너의 80포트로 연결되었음을 확인이 가능하다
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80499d92c8ff httpd "httpd-foreground" 7 seconds ago Up 6 seconds 0.0.0.0:8081->80/tcp, :::8081->80/tcp ws3
http://localhost:8081/index.html
접속아래 로그를 보면 index.html파일을 성공적으로 응답하였다.
$ docker logs -f ws3
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Sat Sep 04 12:57:25.189271 2021] [mpm_event:notice] [pid 1:tid 281473784407408] AH00489: Apache/2.4.48 (Unix) configured -- resuming normal operations
[Sat Sep 04 12:57:25.189345 2021] [core:notice] [pid 1:tid 281473784407408] AH00094: Command line: 'httpd -D FOREGROUND'
[Sat Sep 04 12:57:37.032332 2021] [mpm_event:notice] [pid 1:tid 281473784407408] AH00491: caught SIGTERM, shutting down
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Sat Sep 04 13:00:45.637085 2021] [mpm_event:notice] [pid 1:tid 281472961082736] AH00489: Apache/2.4.48 (Unix) configured -- resuming normal operations
[Sat Sep 04 13:00:45.637310 2021] [core:notice] [pid 1:tid 281472961082736] AH00094: Command line: 'httpd -D FOREGROUND'
172.17.0.1 - - [04/Sep/2021:13:01:00 +0000] "GET /index.html HTTP/1.1" 200 45
172.17.0.1 - - [04/Sep/2021:13:01:00 +0000] "GET /favicon.ico HTTP/1.1" 404 196
우리의 목적은 It works!를 출력하는게 아닌, 우리의 웹 앱을 만드는 것이다. 그러려면 도커 컨테이너 안에서 파일을 수정해야 한다.
docker exec
명령을 통해 ws3컨테이너로 명령어를 보낼 수 있다.
$ docker exec ws3 pwd
/usr/local/apache2
$ docker exec ws3 ls
bin
build
cgi-bin
conf
error
htdocs
icons
include
logs
modules
docker exec
명령을 통해 컨테이너 안에 있는 shell을 실행한다. 컨테이너에 따라 bash shell이 있을 수 있고, 없다면 sh를 실행해서 연결을 유지하도록 한다.
일단 shell이 실행되면 ls
, pwd
등등 모든 명령어는 도커 컨테이너 환경에서 실행이 된다.
$ docker exec ws3 /bin/sh
$ docker exec -it ws3 /bin/sh
# pwd
/usr/local/apache2
# ls
bin build cgi-bin conf error htdocs icons include logs modules
# exit
$ docker exec -it ws3 /bin/bash
$ cd /usr/local/apache2/htdocs/
$ apt update
$ nano index.html
6강에서 우리는 컨테이너의 파일을 직접 수정하였다. 그러나 이러한 작업은 컨테이너가 사라진다면 헛수고가 된다.
그림 7-1. 컨테이너를 삭제하면 컨테이너의 파일 시스템도 삭제된다.
만약 실행 환경만 컨테이너에게 맡기고, 파일을 수정하는 작업은 호스트에서 진행한다면 어떨까?
컨테이너 구조를 사용하는 이유를 생각해본다면(필요할때 생성하고, 삭제할 수 있는 구조)이 방법이 더 적절해보인다. 또한 파일의 버전관리까지 가능하다.
그림 7-2. 실행환경은 컨테이너에게, 파일 수정은 호스트에서.
컨테이너를 실행할 때 -v
옵션을 통해 호스트의 파일 시스템을 할당할 수 있다.
/Users/jaesik/Projects/docker
경로에 index.html
파일을 생성하였다.$ docker run --name ws3 -p 8888:80 -v /Users/jaesik/Projects/docker:/usr/local/apache2/htdocs/ httpd
$ docker run --name {{container_name}} -p {{host_port:container_port}} -v {{host_dir}}:{{container_dir}} httpd
1장에서 언급한대로 도커의 기본적인 개념과 원리를 살펴보았다. 설치 및 실행 기본 명령어를 통해 기본적인 사용법 또한 익혔다. 만들고 있던 앱이 있다면 도커를 통해 환경을 구성해보고 후속 주제를 공부해보면 좋을 것 같다.