도커 입구 수업

guava·2021년 9월 4일
0
post-thumbnail

생활코딩 도커 입구수업을 듣고 정리한 글입니다.

1. 수업 소개

내 컴퓨터에서 애플리케이션을 만들려면? 운영체제에 여러 소프트웨어를 깔아야 한다.
웹서버, 데이터베이스 등등.. 이것들은 매번 설치하는게 너무 까다롭다!
애플리케이션을 개발하기 위한 환경. 어떻게 구성하면 좋을까?

어떻게 구성할까?

첫번째 방법! 별도의 컴퓨터로 구성한다.

  • 웹서버, 데이터베이스가 설치된 컴퓨터를 따로 제공받는다.

    비싸다

두번째 방법은? 가상OS를 설치한다.

  • 하나의 컴퓨터에 가상의 컴퓨터를 만들고 여기에 운영체제 및 웹서버를 설치한다.

    겨우 웹서버를 운영하기위해서 운영체제를? 운영체제 위에 몇개의 운영체제가 있는거야

세번째..! 컨테이너 환경을 구성한다.

  • 한대의 컴퓨터 안에서 각각의 앱을 실행시킨다. 각각의 앱은 격리된 환경에서 실행된다.
  • 운영체제가 설치된 컴퓨터는 host이고 host에서 실행되는 격리된 각각의 실행 환경은 container이다.
  • 각각의 container에는 앱을 실행하는데 필요한 라이브러리와 실행파일들만 포함되어 있다.

이미 존재하는 운영체제를 공유하므로 추가 설치에 대한 어려움이 없다.
운영체제가 하나니까 속도도 빠르다.
저장장치의 용량을 아낄 수 있다.

요약

  • 리눅스 운영체제에는 이미 이러한 컨테이너 실행법이 내장되어있다.
  • 이를 쉽게 실행해주는 제품중 하나가 "Docker"이다.
  • 본 수업의 목표는 도커의 이용자가 되는 것. 최소한의 개념과 원리를 살펴본다.

2. 설치

개요

  • 도커와 위에서 돌아가는 컨테이너 기술은 리눅스 운영체제의 기술이다.
  • Windows, MacOS 등 리눅스가 아닌 운영체제로 도커를 동작한다고 하더라도, 도커가 리눅스 가상머신을 설치하고 그 위에서 앱들을 동작시킨다.
  • 때문에 내 컴퓨터가 리눅스가 아니라면, 성능이 다소 저하될 수 있다.
  • 도커를 사용하는 이유? 편의성

설치

  1. 도커 사이트에서 운영체제별 설치 안내를 확인 후 진행
  2. 터미널에서 docker images 시 에러가 나지 않고 메시지가 뜨거나 그러면 잘 설치된것.

3. 이미지 pull

우리는 일반적으로 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이라하며 이를 통해 imagecontainer로 바뀐다.
  • container안에 포함되어있는 실행되도록 조치되어있는 프로그램이 실행이 된다.

이미지 다운받는 방법

command: docker pull httpd

  1. hub.docker.com → explore → containers에서 원하는 컨테이너 설치 (apache 웹서버 설치하기)
  2. 1번에서 httpd 컨테이너 검색 (httpd: apache 웹서버 이름)
    그림3-2. official Image는 도커에서 공식 관리하는 이미지
    그림3-3. 컨테이너 선택 시 우측에 설치 명령어가 나와있다
  3. 2번에서 명령어 확인 후 httpd 컨테이너 설치 docker pull httpd
  4. docker images 명령을 통해 설치된 목록을 확인한다.

    docker images

4. 컨테이너 run

이미지를 다운로드 했다면 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

5. 네트워크

우리는 도커의 명령어를 통해 아파치를 실행하였다. 주의해야할 것은 도커가 설치되어 있는 호스트와 컨테이너간에는 별도의 포트 및 파일시스템이 존재한다는 점이다.

일반적으로 클라이언트로부터 http요청을 받게되면 아파치 웹서버는 80포트에서 대기하다가 응답을 준다. 현재 우리가 실행한 아파치서버도 동일하게 동작할까? 아니다. 도커 Host와 도커 Container가 격리되어 있고 연결이 되어있지 않기 때문이다.

때문에 도커를 사용할 경우에는 포트포워딩을 통해 도커 호스트와 도커 컨테이너간의 연결이 필요하다. 이는 기존의 실행 명령어였던 docker run httpddocker 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

결과

아래 로그를 보면 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

6. 명령어 실행

우리의 목적은 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

docker exec

7. 호스트와 컨테이너의 파일시스템 연결


6강에서 우리는 컨테이너의 파일을 직접 수정하였다. 그러나 이러한 작업은 컨테이너가 사라진다면 헛수고가 된다.
그림 7-1. 컨테이너를 삭제하면 컨테이너의 파일 시스템도 삭제된다.

만약 실행 환경만 컨테이너에게 맡기고, 파일을 수정하는 작업은 호스트에서 진행한다면 어떨까?
컨테이너 구조를 사용하는 이유를 생각해본다면(필요할때 생성하고, 삭제할 수 있는 구조)이 방법이 더 적절해보인다. 또한 파일의 버전관리까지 가능하다.

그림 7-2. 실행환경은 컨테이너에게, 파일 수정은 호스트에서.

방법

컨테이너를 실행할 때 -v옵션을 통해 호스트의 파일 시스템을 할당할 수 있다.

  1. 우선 /Users/jaesik/Projects/docker 경로에 index.html파일을 생성하였다.
  2. 다음 명령어를 통해 컨테이너를 실행하였다.
$ 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장에서 언급한대로 도커의 기본적인 개념과 원리를 살펴보았다. 설치 및 실행 기본 명령어를 통해 기본적인 사용법 또한 익혔다. 만들고 있던 앱이 있다면 도커를 통해 환경을 구성해보고 후속 주제를 공부해보면 좋을 것 같다.

0개의 댓글