# Docker 설치하기

img

도커는 리눅스 컨테이너 기술이므로 macOS나 windows에 설치할 경우 가상머신에 설치가 됨

리눅스 컨테이너 말고 윈도우즈 컨테이너라는 것도 있지만 리눅스 컨테이너를 사용할 예정!

# Linux

리눅스에 도커를 설치하는 방법은 자동 설치 스크립트를 이용하는 것이 가장 쉽다. 다음 명령어를 입력하면 root 권한을 요구하고 잠시 기다리면 설치가 완료된다.

curl -fsSL https://get.docker.com/ | sudo sh

# sudo 없이 사용하기

docker는 기본적으로 root권한이 필요하다. root가 아닌 사용자가 sudo없이 사용하려면 해당 사용자를 docker그룹에 추가하면 된다.

sudo usermod -aG docker $USER # 현재 접속중인 사용자에게 권한주기
sudo usermod -aG docker your-user # your-user 사용자에게 권한주기

사용자가 로그인 중이라면 다시 로그인 후 권한이 적용된다.

# Docker for Mac / Docker for Windows

도커를 맥이나 윈도우즈에 설치하려면 Docker for mac 또는 Docker for windows를 설치하면 된다. 파일을 다운받고 설치하고 재부팅하면 대부분 문제없이 완료된다. 소소한 옵션들이 있는데 특별히 건드릴 부분은 없으나 한번 살펴보고 적절하게 설정하면 된다. (windows는 공유 드라이브를 선택!)

img

마치 네이티브스럽게 설치된 것 같지만 도커는 리눅스 컨테이너이므로 실제로는 가상머신에 설치가 되었다. 사용자는 가상머신을 사용한다는 느낌이 전혀 안드는데 그런부분을 굉장히 신경써서 설계한 것 같다. 예를 들면, 포트를 연결하기 위해 도커 컨테이너의 특정 포트를 가상머신에 연결하고 다시 mac이나 windows의 포트와 연결해야 한다. 디렉토리를 연결한다면 디렉토리를 가상머신과 공유하고 그 디렉토리를 다시 컨테이너와 연결해야 한다. 이런 한단계 추가적으로 거쳐야하는 부분을 자연스럽게 처리해준다!

docker for mac은 xhyve라는 macOS에서 제공하는 가상환경을 이용하고 docker for windows는 Hyper-V기능을 이용한다. 따라서 OS가 최신버전이 아니면 동작하지 않을 수 있다.

# 가상머신에 설치하기

이런저런 이유로 Docker for … 를 사용하지 못하는 경우 Docker machine을 이용할 수 있는데 처음 도커를 공부하는 경우에는 Virtual Box나 VMware같은 가상머신에 리눅스를 설치하고 리눅스에 접속하여 도커를 사용하는 방법을 권장함. 처음부터 Docker machine을 사용하면 환경이 약간 혼란스러울 수 있다.

# 설치확인하기

설치가 완료되었다면 정상적으로 설치되었는지 도커 명령어를 입력해 확인!

docker version

output:

Client:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.6.4
 Git commit:   78d1802
 Built:        Wed Jan 11 00:23:16 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.6.4
 Git commit:   78d1802
 Built:        Wed Jan 11 00:23:16 2017
 OS/Arch:      linux/amd64

Client와 Server 정보가 정상적으로 출력되었다면 설치 완료!

Server 정보가 안나오고 Error response from daemon: Bad response from Docker engine이라는 메시지가 출력되는 경우는 보통 docker daemon이 정상적으로 실행되지 않았거나 sudo를 입력하지 않은 경우.

버전 정보가 클라이언트와 서버로 나뉘어져 있는데, 도커는 하나의 실행 파일이지만 실제로 클라이언트와 서버역할을 각각 할 수 있다! 도커 커맨드를 입력하면 도커 클라이언트가 도커 서버로 명령을 전송하고 결과를 받아 터미널에 출력해 준다.

img

기본값이 도커 서버의 소켓을 바라보고 있기 때문에 사용자는 의식하지 않고 마치 바로 명령을 내리는 것 같은 느낌을 받는다. 이러한 설계가 mac이나 windows의 터미널에서 명령어를 입력했을때 가상 서버에 설치된 도커가 동작하는 이유이다.

# 컨테이너 실행하기

도커를 실행하는 명령어는 다음과 같다.

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

다음은 자주 사용하는 옵션들이다.

옵션설명
-ddetached mode 흔히 말하는 백그라운드 모드
-p호스트와 컨테이너의 포트를 연결 (포워딩)
-v호스트와 컨테이너의 디렉토리를 연결 (마운트)
-e컨테이너 내에서 사용할 환경변수 설정
–name컨테이너 이름 설정
–rm프로세스 종료시 컨테이너 자동 제거
-it-i와 -t를 동시에 사용한 것으로 터미널 입력을 위한 옵션
–link컨테이너 연결 [컨테이너명:별칭]

엄청나게 직관적인 옵션으로 몇번 실행해보면 자연스럽게 익숙해진다.

# ubuntu 16.04 container

시작은 가볍게 ubuntu 16.04 컨테이너를 생성하고 컨테이너 내부에 들어가 봅니다.

docker run ubuntu:16.04

이미지를 처음 다운받는 경우

run명령어를 사용하면 사용할 이미지가 저장되어 있는지 확인하고 없다면 다운로드(pull)를 한 후 컨테이너를 생성(create)하고 시작(start) 한다.

ubuntu:16.04이미지를 다운받은 적이 없으면 이미지를 다운로드 한 후 컨테이너가 실행된다. 컨테이너는 정상적으로 실행됐지만 뭘 하라고 명령어를 전달하지 않았기 때문에 컨테이너는 생성되자마자 종료된다.

컨테이너는 프로세스이기 때문에 실행중인 프로세스가 없으면 컨테이너는 종료된다.

이번에는/bin/bash명령어를 입력해서ubuntu:16.04컨테이너를 실행해보자.

docker run --rm -it ubuntu:16.04 /bin/bash

# in container
$ cat /etc/issue
Ubuntu 16.04.1 LTS \n \l

$ ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

컨테이너 내부에 들어가기 위해 bash 쉘을 실행하고 키보드 입력을 위해-it옵션주고, 프로세스가 종료되면 컨테이너가 자동으로 삭제되도록--rm옵션도 추가한다.

다운로드가 되어있기 때문에 이미지를 다운로드 하는 화면 없이 바로 실행된다. cat /etc/issuels를 실행해보면 ubuntu 리눅스인걸 알 수 있다! (가벼운 가상머신 느낌)

exit로 bash 쉘을 종료하면 컨테이너도 같이 종료된다. 도커를 이용하여 가장 기본적인 컨테이너를 순식간에 만들어 보았다.

# redis container

2번째 컨테이너는 redis이다.

redis (opens new window)는 메모리기반의 다양한 기능을 가진 스토리지이다! 6379 포트로 통신하며 telnet 명령어로 테스트해 볼 수 있다.

redis 컨테이너는 detached mode(백그라운드 모드)로 실행하기 위해 -d 옵션을 추가하고 -p 옵션을 추가하여 컨테이너의 포트를 호스트의 포트로 연결해보았다.

-d 옵션이 없다면 프로세스가 foreground로 실행되어 아무키도 입력할 수 없게 된다.
컨테이너를 종료하려면 ctrl + c를 입력하자.

docker run -d -p 1234:6379 redis
5dff91d2cd859b48806231627aadf2066b9b10a8687c765b71ae6cae834ed751

# redis test
$ telnet localhost 1234
set mykey hello
+OK
get mykey
$5
hello

-d 옵션을 주었기 때문에 컨테이너를 실행 하자마자 컨테이너의 ID(5dff91d2…)를 보여주고 바로 쉘로 돌아왔다.

컨테이너는 종료된 것이 아니라 백그라운드 모드로 동작하고 있고 컨테이너 ID를 이용하여 컨테이너를 제어할 수 있다.

-p 옵션을 이용하여 호스트의 1234포트를 컨테이너의 6379포트로 연결하였고 localhost의 1234포트로 접속하면 하면 redis를 사용할 수 있다.

테스트 결과 redis에 접속하여 새로운 키를 저장하고 불러오는데 성공했다. 실행이 간단한건 물론이고 호스트의 포트만 다르게 하면 하나의 서버에 여러개의 redis 서버를 띄우는 것도 매우 간단하다.

# MySQL 5.7 container

3번째 실행할 컨테이너는 MySQL서버이다. 가장 흔하게 사용하는 데이터베이스인데 이번에는 -e 옵션을 이용하여 환경변수를 설정하고 --name 옵션을 이용하여 컨테이너에 읽기 어려운 ID 대신 쉬운 이름을 부여할 예정이다.

--name 옵션을 생략하면 도커가 자동으로 이름을 지어 줍니다. 이름은 유명한 과학자나 해커의 이름과 수식어를 조합하여 랜덤으로 생성 (opens new window)합니다.
(ex - boring_wozniak) 우리나라 과학자 장영실 (opens new window)도 등록되어 있습니다.

MySQL Docker hub (opens new window)페이지에 접속하면 간단한 사용법과 환경변수에 대한 설명이 있다.

여러가지 설정값이 있는데 패스워드 없이 root계정을 만들기 위해 MYSQL_ALLOW_EMPTY_PASSWORD 환경변수를 설정한다.

그리고 컨테이너의 이름은 mysql로 할당하고 백그라운드 모드로 띄우기 위해 -d 옵션을 준다. 포트는 3306포트를 호스트에서 그대로 사용하겠다.

docker run -d -p 3306:3306 \
  -e MYSQL_ALLOW_EMPTY_PASSWORD=true \
  --name mysql \
  mysql:5.7

# MySQL test
$ mysql -h127.0.0.1 -uroot

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> quit

순식간에 MySQL서버가 실행되었다. 이번 테스트는 호스트 OS에 MySQL 클라이언트가 설치되어 있어야 한다.

추후에 실행중인 MySQL 도커 컨테이너에 접속하여 클라이언트를 실행해 보도록 하겠다.

처음 접속 시도 시 에러가 날 경우 MySQL서버가 최초로 실행되면서 준비작업을 하기 때문에 발생하는 에러이다.

컨테이너를 실행하면 백그라운드에서 MySQL서버를 띄우는 시간이 필요하기 때문에 잠시 후에 다시 시도 했을 때 정상적으로 접속된 걸 확인할 수 있을 것이다.

# WordPress container

이번에는 블로그 엔진으로 유명한워드프레스 (opens new window)를 실행한다. 워드프레스는 데이터베이스가 필요하기 때문에 조금 복잡한 형태를 띄지만 크게 어렵지 않다.

바로 전에 생성했던 MySQL 컨테이너에 워드프레스 데이터베이스를 만들고 WordPress 컨테이너를 실행할 때 --link 옵션을 이용하여 MySQL 컨테이너를 연결해보겠다.

--link 옵션은 환경변수와 IP정보를 공유하는데 링크한 컨테이너의 IP정보를 /etc/hosts에 자동으로 입력하므로 워드프레스 컨테이너가 MySQL 데이터베이스의 정보를 알 수 있게 된다!

먼저, 워드프레스용 데이터베이스를 생성하고 워드프레스 컨테이너를 실행한다. 호스트의 8080포트를 컨테이너의 80포트로 연결하고 MySQL 컨테이너와 연결한 후 각종 데이터베이스 설정 정보를 환경변수로 입력한다.

# create mysql database
$ mysql -h127.0.0.1 -uroot
create database wp CHARACTER SET utf8;
grant all privileges on wp.* to wp@'%' identified by 'wp';
flush privileges;
quit

# run wordpress container
docker run -d -p 8080:80 \
  --link mysql:mysql \
  -e WORDPRESS_DB_HOST=mysql \
  -e WORDPRESS_DB_NAME=wp \
  -e WORDPRESS_DB_USER=wp \
  -e WORDPRESS_DB_PASSWORD=wp \
  wordpress

컨테이너가 제대로 실행되었는지 웹 브라우저로 확인해보자.

img

워드프레스가 실행되었다! 단지 이미지를 다운받고 적절한 환경변수를 입력하여 컨테이너를 실행했고, 워드프레스 컨테이너 내부는 apache2와 php가 설치되어 있지만 추상화되어 있어 실행과정에서는 드러나지 않는다.

이번 예제는 테스트용으로만 사용해야 합니다. 운영 환경에서 사용하려면 추가적인 셋팅이 필요합니다. 이부분은 밑에서 다시 다룹니다.

--link옵션은 deprecated 되어 곧 사용할 수 없습니다. 대신 Docker network 기능을 이용해야 하지만 쉬운 이해를 돕기 위해 사용하였습니다.

이제, 원하는 서비스가 있다면 이미지를 찾거나 직접 만들고, 어디서나 손쉽게 서비스를 실행할 수 있을 것이다.

# Tensorflow

마지막으로 이렇게 활용할 수 있다라는 예제로 tensorflow를 실행보도록 하겠다.

tensorflow (opens new window)는 손쉽게 머신러닝을 할 수 있는 툴이다. tensorflow는 python으로 만들어져 python과 관련 패키지를 설치해야 한다.

이번에 설치하는 이미지는 python과 함께 numpy, scipy, pandas, jupyter, scikit-learn, gensim, BeautifulSoup4, Tensorflow가 설치되어 있다. 뭔가 복잡해 보이지만 도커라면 손쉽게 실행해 볼 수 있다.

docker run -d -p 8888:8888 -p 6006:6006 teamlab/pydata-tensorflow:0.1

설치된 파일이 많아 다운로드 하는데 시간이 좀 걸린다. 컨테이너가 실행되면 웹 브라우저에서 jupyter에 접속하여 머신러닝을 시작해 보자!

img

성공적으로 tensorflow 테스트를 마쳤다. 여기까지 ubuntu, MySQL, redis, Wordpress, tensorflow를 실행해 보았다.

가상머신을 이용해서 동일한 작업을 했다면 컴퓨터가 엄청나게 버벅이기 시작했겠지만 컨테이너 기반의 도커를 이용하여 매우 가볍게 실행하고 있다.

내부 구조나 설치과정은 자세히 모르지만, 간단한 도커 명령어로 여러개의 서비스를 순식간에 실행하고 사용할 수 있다니 정말 최고다.

# Reference

초보를 위한 도커 안내서 - 설치하고 컨테이너 실행하기 (opens new window)

Last Updated: 6/18/2023, 2:13:15 PM