[Docker] 도커

7 분 소요

들어가며

해당 게시글은 인프런 subicura 강사님의 초보를 위한 도커 안내서 강의를 바탕으로 쓰였음을 미리 밝힙니다.

도커란 무엇인가

서버를 관리한다는 것

  • 도커는 컨테이너 기반의 오픈소스 가상화 플랫폼이다.
  • Oracle, Wordpress, Gitlab 등 매우 복잡하다.
  • AWS, Azure, Google Cloud 등 계속해서 바뀌는 서버 환경
  • Node.js, Python, Ruby 등 계속해서 바뀌는 개발 환경

서버관리 방식의 변화

  • 전통 방식: Add user -> System Env -> Firewall -> Network -> dependencies -> Python -> Git clone -> Package -> Configuration -> Migration -> Proxy -> Run (한땀한땀 관린 필요)
  • 하나의 단계에서라도 사소한 문제 발생시 서버가 죽게 된다.
  • 도커의 경우 어떠한 프로그램도 컨테이너로 만들 수 있고 어디서든 돌아간다.
  • 가상머신처럼 독립적으로 실행되지만 가상머신보다 빠르고 가상머신보다 쉽고 가상머신보다 효율적이다.

도커의 등장

  • 서버를 관리하기 위한 노력
    • 서버배포.pptx -> 문서화 한다
    • 상태관리 도구(CHEF, puppet, ANSIBLE)
    • 가상머신
    • 자원격리: 프로세스를 가상으로 분리, 파일 / 디렉토리를 가상으로 분리, CPU / MEMORY / IO 그룹별 제한(리눅스 커널의 기능을 이용한 빠르고 효율적인 서버 관리)
  • 도커의 등장
    • 컨테이너: 격리된 환경에서 작동하는 가상의 프로세스
    • 리눅스 커널의 여러 기술을 활용
    • 하드웨어 가상화 기술보다 가벼움
    • 이미지 단위로 프로세스 실행 환경을 구성

도커란

  • 도커의 특징: 확장성 / 이식성 / 표준성 / 이미지 / 설정관리 / 자원관리
  • 도커가 설치되어 있다면 어디서든 컨테이너를 실행할 수 있음
  • 특정 회사나 서비스에 종속적이지 않음
  • 쉽게 개발서버를 만들 수 있고 테스트서버 생성도 간편함
  • 컨테이너라는 표준으로 서버를 배포하므로 모든 서비스들의 배포과정이 동일해짐
  • 이미지에서 컨테이너를 생성하기 때문에 반드시 이미지를 만드는 과정이 필요
  • Dockerfile를 이용하여 이미지를 만들고 처음부터 재현 가능
  • 빌드 서버에서 이미지를 만들면 해당 이미지를 이미지 저장소에 저장하고 운영서버에서 이미지를 불러옴
  • 설정은 보통 환경변수로 제어함
  • MYSQL_PASS=password와 같이 컨테이너를 띄울때 환경변수를 같이 지정
  • 하나의 이미지가 환경변수에 따라 동적으로 설정파일을 생성하도록 만들어져야함
  • 컨테이너는 삭제시 모든 데이터가 초기화됨
  • 업로드 파일의 경우 별도의 저장소 필요
  • 세션이나 캐시를 redis 와 같은 외부로 분리 —> 컨테이너: 서버 관리 혁신

컨테이너의 미래

  • 여러대의 서버와 여러개의 서비스를 관리하기 쉽게(쿠버네티스)
  • 스케쥴링
    • 컨테이너(서비스 프로세스)를 적당한 서버에 배포해 주는 작업
    • 전략: idle 서버에 배포, 순서배포, 랜덤배포
    • 서버가 죽으면 실행중이던 컨테이너를 다른 서버에 띄어줌
  • 클러스터링
    • 여러 개의 서버를 하나의 서버처럼 사용(컨테이너 사이의 통신)
    • 흩어져 있는 여러 개의 컨테이너도 가상 네트워크를 이용하여 마치 같은 서버에 있는 것처럼 쉽게 통신
  • 서비스 디스커버리
    • 서비스를 찾아주는 기능
    • 클러스터 환경에서 컨테이너는 어느 서버에 생성될지 알 수 없고 다른 서버로 이동할 수도 있음
    • 컨테이너와 통신을 하기 위해서 어느 서버에서 실행중인지 알아야 하고 컨테이너가 생성되고 중지될 때 어딘가에 IP와 Port같은 정보를 업데이트해줘야 함
    • key-value 저장소에 정보를 저장할 수도 있고 내부 DNS 서버를 이용

도커 - 설치부터 실행까지

도커 설치하기

  • 도커는 기본적으로 linux를 지원하기 때문에 MacOS와 Windows에 설치되는 Docker는 가상머신에 설치됨
  • MacOS는 xhyve를 사용하고 Windows는 Hyper-V 사용
  • docker CLI 는 도커 호스트에 명령을 전달하고 겨로가를 받아서 출력함

도커 기본 명령어(run)

  • docker run ubuntu:20.04
    • run 명령어를 사용하면 사용할 이미지가 저장되어 있는지 확인하고 없다면 다운로드 (pull) 한 후 컨테이너를 생성(create)하고 시작(start)한다. 컨테이너는 정상적으로 실행됐지만 뭘 하라고 명령어를 전달하지 않았기 때문에 컨테이너는 생성되자마자 종료된다. 컨테이너는 프로세스이기 때문에 실행중인 프로세스가 없으면 컨테이너는 종료된다.
    • 이미지마다 컨테이너가 만들어질때 실행할 명령어를 지정할 수 있고 ubuntu:20.04는 /bin/sh 가 지정되어 쉘이 실행되야 하지만, 입력을 받을 수 있도록 -it 옵션을 입력하지 않았기 때문에 바로 실행이 종료되었다.
  • docker run --rm -it ubuntu:20.04 /bin/sh
    • 컨테이너 내부에 들어가기 위해 sh 를 실행하고 키보드 입력을 위해 -it 옵션을 준다. 추가적으로 프로세스가 종료되면 컨테이너가 자동으로 삭제되도록 --rm 옵션도 추가한다.--rm 옵션이 없다면 컨테이너가 종료되더라도 삭제되지 않고 남아 있어 수동으로 삭제 해야한다.
  • docker run --rm -it centos:8 /bin/sh
    • 도커는 다양한 리눅스 배포판을 실행할 수 있다. 공통점은 모두 동일한 커널을 사용한다는 점이다. Ubuntu 또는 CentOS에 포함된 다양한 기본기능이 필요 없는 경우, Alpine 이라는 초소형 (5MB) 이미지를 사용할 수도 있다.
  • MySQL 실행하기
    • docker run -d -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=true --name mysql mysql:5.7
    • MySQL 데이터베이스를 실행
docker exec -it mysql mysql // 컨테이너 mysql에 접속하여 mysql 명령어 실행
create database wp CHARACTER SET utf8;
grant all privileges on wp.* to wp@'%' identified by 'wp';
flush privileges;
quit
  • exec 명령어: exec 명령어는 run 명령어와 달리 실행중인 도커 컨테이너에 접속할 때 사용하며 컨테이너 안에 ssh server등을 설치하지 않고 exec 명령어로 접속한다.

도커 기본 명령어

  • docker ps: 실행중인 컨테이너 목록을 확인하는 명령어
  • docker ps -a: 중지된 컨테이너도 확인하려면 -a 옵션
  • docker stop [OPTIONS] CONTAINER [CONTAINER...]: 실행중인 컨테이너를 중지하는 명령어. 실행중인 컨테이너를 하나 또는 여러개 (띄어쓰기) 중지할 수 있다.
  • docker rm [OPTIONS] CONTAINER [CONTAINER...]: 종료된 컨테이너를 완전히 제거하는 명령어
  • docker logs [OPTIONS] CONTAINER: 컨테이너가 정상적으로 동작하는지 확인하는 좋은 방법은 로그를 확인하는 것. -f, –tail 옵션
  • docker images [OPTIONS] [REPOSITORY[:TAG]]: 도커가 다운로드한 이미지 목록을 보는 명령어
  • docker pull [OPTIONS] NAME[:TAG|@DIGEST]: 이미지를 다운로드하는 명령어
  • docker rmi [OPTIONS] IMAGE [IMAGE...]: 이미지를 삭제하는 방법. images 명령어를 통해 얻는 이미지 목록에서 이미지 ID를 입력하면 삭제가 된다. 단, 컨테이너가 실행중인 이미지는 삭제되지 않는다.
  • docker network create [OPTIONS] NETWORK(docker network create app-network): 도커 컨테이너끼리 이름으로 통신할 수 있는 가상 네트워크를 만든다. app-network 라는 이름으로 wordpress와 mysql이 통신할 네트워크를 만든다.
  • docker network connect [OPTIONS] NETWORK CONTAINER (docker network connect app-network mysql): 기존에 생성된 컨테이너에 네트워크를 추가. mysql 컨테이너에 네트워크를 추가
docker run -d -p 8080:80 \
  --network=app-network \
  -e WORDPRESS_DB_HOST=mysql \
  -e WORDPRESS_DB_NAME=wp \
  -e WORDPRESS_DB_USER=wp \
  -e WORDPRESS_DB_PASSWORD=wp \
  wordpress
  • 워드프레스를 app-network에 속하게 하고 mysql을 이름으로 접근

도커 기본 명령어(volume)

docker stop mysql
docker rm mysql
docker run -d -p 3306:3306 \
  -e MYSQL_ALLOW_EMPTY_PASSWORD=true \
  --network=app-network \
  --name mysql \
  -v /Users/subicura/Workspace/github.com/subicura/docker-guide/ch02/mysql:/var/lib/mysql \
  mysql:5.7
  • mysql을 삭제후에 다시 실행하면 데이터베이스 오류가 발생
  • -v 옵션으로 데이터베이스와 로컬 디렉토리를 연동, 이후 컨테이너 삭제 후 다시 컨테이너 생성을 하면 기존 데이터베이스와 동일한 데이터베이스 생성
  • -v /my/own/datadir:/var/lib/mysql

도커 컴포즈

version: '2'
services:
  db:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
  wordpress:
    image: wordpress:latest
    volumes:
      - ./wp:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_PASSWORD: wordpress
  • docker-compose up -d
  • docker-compose down: docker compose를 이용하여 mysql과 wordpress를 종료
  • services: 실행할 컨테이너 정의, docker run --name django 과 같다고 생각할 수 있음
  • image: 컨테이너에 사용할 이미지 이름과 태그, 태그를 생략하면 latest, 이미지가 없으면 자동으로 pull
  • ports: 컨테이너와 연결할 포트(들), {호스트 포트}:{컨테이너 포트}
  • environment: 컨테이너에서 사용할 환경변수(들), {환경변수 이름}:{값}
  • volumes: 마운트하려는 디렉터리(들), {호스트 디렉터리}:{컨테이너 디렉터리}
  • restart: 재시작 정책, restart: “no”, restart: always, restart: on-failure, restart: unless-stopped
  • build: 이미지를 자체 빌드 후 사용, image 속성 대신 사용함, 여기에 사용할 별도의 도커 파일이 필요함

도커 컴포즈 명령어

  • up
    • docker-compose.yml에 정의된 컨테이너를 실행
    • docker-compose up
    • docker-compose up -d
    • docker-compose up --force-recreate: 컨테이너를 새로 만들기
    • docker-compose up --build: 도커 이미지를 다시 빌드(build로 선언했을 때만)
  • stop
    • 컨테이너 멈춤
    • docker-compose stop
    • docker-compose stop wordpress: wordpress 컨테이너만 멈춤
  • start
    • 멈춘 컨테이너를 재개
    • docker-compose start
    • docker-compose start wordpress: wordpress 컨테이너만 재개
  • restart
    • 컨테이너를 재시작
    • docker-compose restart
    • docker-compose restart wordpress: wordpress 컨테이너만 재시작
  • down
    • 컨테이너를 종료하고 삭제
    • docker-compose down
  • logs
    • 컨테이너의 로그
    • docker-compose logs
    • docker-compose logs -f
  • ps
    • 컨테이너 목록
    • docker-compose ps
  • exec
    • 실행 중인 컨테이너에서 명령어 실행
    • docker-compose exec {컨테이너 이름} {명령어}
    • docker-compose exec wordpress bash
  • build
    • 컨테이너 build 부분에 정의된 내용대로 빌드
    • docker-compose build
    • docker-compose build wordpres: wordpress 컨테이너만 build

도커 - 이미지 만들고 배포하기

도커 이미지 만들기 - 기본

  • 이미지란
    • 도커는 레이어드 파일 시스템 기반
    • AUFS, BTRFS, Overlayfs, …
    • 이미지는 프로세스가 실행되는 파일들의 집합(환경) 프로세스는 환경(파일)을 변경할 수 있음
    • 이 환경을 저장해서 새로운 이미지를 만든다
  • 읽기 전용 vs 쓰기 가능: 베이스 이미지에서 커스텀 후 새로운 이미지 만들기
$ docker run -it --name git ubuntu:latest bash
root@2f8bfff679f9:/# git
bash: git: command not found
root@2f8bfff679f9:/# apt-get update
root@2f8bfff679f9:/# apt-get install -y git
root@2f8bfff679f9:/# git --version
git version 2.17.1
$ docker commit git ubuntu:git
sha256:f95008381e220660f6330bcc544640091f59793e213ff5fe9a8298d784a345fa
$docker images | grep ubuntu
ubuntu   git         f95008381e22     17 seconds ago  186MB
ubuntu   latest      cf0f3ca922e0     5 days ago     64.2MB
  • Dockerfile
명령어 설명
FROM 기본 이미지
RUN 쉘 명령어 실행
CMD 컨테이너 기본 실행 명령어 (Entrypoint의 인자로 사용)
EXPOSE 오픈되는 포트 정보
ENV 환경변수 설정
ADD 파일 또는 디렉토리 추가. URL/ZIP 사용가능
COPY 파일 또는 디렉토리 추가
ENTRYPOINT 컨테이너 기본 실행 명령어
VOLUME 외부 마운트 포인트 생성
USER RUN, CMD, ENTRYPOINT를 실행하는 사용자
WORKDIR 작업 디렉토리 설정
ARGS 빌드타임 환경변수 설정
LABEL key - value 데이터
ONBUILD 다른 빌드의 베이스로 사용될때 사용하는 명령어
  • 이미지 빌드하기
docker build -t {이미지명:이미지태그} {빌드 컨텍스트} 
$ docker build -t sample:1 .
  • 현재 디렉토리의 Dockerfile로 빌드
    • -f 옵션을 사용해 다른 위치의 Dockerfile 파일 사용 가능
    • -t 명령어로 도커 이미지 이름을 지정
    • {네임스페이스}/{이미지이름}:{태그} 형식
  • 마지막에는 빌드 컨텍스트 위치를 지정
    • 현재 디렉터리를 의미하는 점(.)을 주로 사용
    • 필요한 경우 다른 디렉터리를 지정할 수도 있음
  • .dockerignore
    • .gitignore와 비슷한 역할
    • 도커 빌드 컨텍스트에서 지정된 패턴의 파일을 무시
    • .git이나 민감한 정보를 제외하는 용도로 주로 사용
    • .git이나 에셋 디렉터리만 제외시켜도 빌드 속도 개선
    • 이미지 빌드 시에 사용하는 파일은 제외시키면 안 됨
  • Dockerfile
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y git
$ docker build -t ubuntu:git-dockerfile .
$ docker images | grep ubuntu

도커 이미지 만들기(웹 애플리케이션)

# 1. node 이미지 사용 
FROM node:12-alpine
#2.패키지 우선 복사
COPY ./package* /usr/src/app/
WORKDIR /usr/src/app
RUN     npm install
# 3. 소스 복사
COPY . /usr/src/app
# 4. WEB 서버 실행 (Listen 포트 정의) 
EXPOSE 3000
CMD node app.js
docker build -t subicura/app .
docker run --rm -d -p 3000:3000 subicura/app
  • FROM: FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
    • 베이스 이미지 지정
    • FROM ubuntu:latest
    • FROM node:12
    • FROM python:3
  • COPY: COPY [--chown=<user>:<group>] <src>... <dest>
    • 파일 또는 디렉토리 추가
    • COPY index.html /var/www/html/
    • COPY ./app /usr/src/app
  • RUN: RUN <command>
    • 명령어 실행
    • RUN apt-get update
    • RUN npm install
  • WORKDIR: WORKDIR /path/to/workdir
    • 작업 디렉토리 변경
    • WORKDIR /app
  • EXPOSE
    • 컨테이너에서 사용하는 포트 정보
    • EXPOSE 8000
  • CMD: CMD ["executable","param1","param2"], CMD command param1 param2
    • 컨테이너 생성시 실행할 명령어
    • CMD [“node”, “app.js”]
    • CMD node app.js

이미지 저장소

  • docker login
  • docker push {ID}/example
  • docker pull {ID}/example

태그:

카테고리:

업데이트:

댓글남기기