Docker

도커는 컨테이너 기반 오픈소스 가상화 플랫폼이며,
라이브러리, 시스템 도구, 코드, 런타임을 포함한 소프트웨어를 컨테이너로 패키징시키는 것이다.

로컬 PC, AWS, GCP, Azure 등 환경에 관계없이 빠르게 배포 및 테스트할 수 있다.

Container 가상화

VM:container

  • Virtual Machine 가상화
    • Hypervisor 위에 Guest OS가 구동
    • 별도의 VM과 OS를 필요로 하기 때문에 자원의 비효율성(용량, 메모리)
  • Container 가상화
    • Docker 엔진을 통해 각 App이 OS 자원을 직접 사용 (앱 실행에 필요한 자원만 사용)
    • 별도의 OS 없이 Docker 엔진 공유 (가벼움)

Docker image

이미지는 컨테이너 실행에 필요한 파일과 설정값을 포함하고 있는 것이다. 즉, 컨테이너는 이미지를 실행한 상태이다.

Docker Container

컨테이너란 격리된 공간에서 프로세스가 동작하는 기술이다. 컨테이너는 프로세스를 격리하는 방식이기 때문에 기존 가상화 기술에 비해 가볍고 빠르다.

Docker cacheing

한번 이미지를 빌드한 뒤 dockerfile에 동일한 명령어가 있으면 이전의 빌드에서 사용했던 캐시를 사용한다. build할 때 using Cache log가 나오는 것을 확인할 수 있다. 캐시가 필요하지 않다면 --no-cache 옵션을 추가하면 된다.

Dockerfile

  • FROM절 : 컨테이너의 원형(틀) 역할을 할 도커 이미지(OS)를 정의한다.
  • COPY절 : 쉘 스크립트 파일을 도커 컨테이너 안의 /usr/local/bin에 복사하기 위하여 정의한다.
  • RUN절 : 도커 컨테이너 안에서 명령을 수행하기 위함. 여기까지 도커 빌드 과정에서 실행되며 그 결과로 새로운 이미지가 만들어진다.
  • CMD절 : 완성된 이미지를 도커 컨테이너로 실행하기 전에 먼저 실행할 명령을 정의한다.

코드로 관리하는 인프라(IaC)와 불변 인프라(Immutable Infrastructure)

  • IaC : 서버를 어떻게 구성할 것인지, 어떤 라이브러리와 도구를 설치할지를 코드로 정의하고 Chef나 Ansible 같은 프로비저닝 도구로 서버를 구축
    • stable 버전을 install하는 코드를 실행하는 예시를 들면, stable 버전은 자주 변하기 때문에 항상 같은 결과를 보장하지 않는 단점이 있음
  • 불변 인프라(Immutable Infrastructure) : 어떤 시점의 서버 상태를 저장해 복제할 수 있게 하는 개념
    • 서버에 변경을 원할 때는 새로운 서버를 구축하고 그 상태를 이미지로 저장한 다음, 해당 이미지를 복제
  • 도커를 사용하면 IaC와 불변 인프라의 개념을 간단하고 낮은 비용으로 실현할 수 있음
    • 인프라 구성이 Dockerfile로 관리되므로 IaC는 도커의 대원칙
    • 컨테이너형 가상화 기술 사용을 통해, 기존 컨테이너를 빠르게 폐기하고 새롭게 구축 가능 (불변 인프라)

Container Orchestration

  • 도커 컴포즈를 단일 서버를 넘어 여러 서버에 걸쳐 있는 여러 컨테이너를 관리할 수 있도록 한것이 도커 스웜(Docker Swarm)이다.
  • 도커 스웜은 컨테이너 증가, 감소는 물론, 노드의 리소스를 효율적으로 활용하기 위해 컨테이너 배치 및 로드 밸런싱 등의 기능을 갖춤
  • 배포 시 롤링 업데이트가 가능 (오래된 컨테이너와 새로운 컨테이너를 단계적으로 서비스에 교체 투입하는 것)
  • 이렇게 여러 서버에 걸쳐 있는 여러 컨테이너를 관리하는 기법은 컨테이너 오케스트레이션이라고 한다.
  • 컨테이너 오케스트레이션의 표준은 쿠버네티스(k8s)이다.

Docker Network Mode

  1. bridge
    • docker 기본 네트워크 방식
    • 각 컨테이너마다 고유한 network namespace 영역이 생성
    • docker daemon을 실행하면 docker0라는 bridge가 생성되며 해당 bridge에 container들의 인터페이스들이 하나씩 binding되는 구조
  2. host
    • 컨테이너가 독립적인 네트워크 영역을 갖지 않고 host와 네트워크를 함께 사용
    • docker run --net=host httpd web01 과 같이 생성
    • 컨테이너의 ip와 인터페이스 정보는 host의 네트워크 정보와 동일
    • host옵션으로 생성된 컨테이너는 bridge를 사용하지 않으므로 docker0에 바인딩되지 않는다.
  3. container
    • 기존 존재하는 다른 컨테이너의 network 환경을 공유
  4. none
    • 격리된 네트워크 영역을 가지지만, 인터페이스가 없는 상태로 컨테이너 생성
    • bridge에도 연결되지 않은 상태이며, 이 상태로는 외부 통신 불가
    • 인터페이스를 직접 커스터마이징하기 위한 옵션

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

'Docker & k8s' 카테고리의 다른 글

[K8S] 2. Kubernetes Commands  (0) 2022.02.03
[K8S] 1. Kubernetes Core Component  (0) 2022.02.03
도커란? (Docker)  (0) 2020.12.17
쿠버네티스(k8s)는 무엇인가  (0) 2020.12.17
How to fix docker error processing tar file  (1) 2020.11.13

공간이 부족하거나 권한 문제로 발생하는 도커 오류이다.

다음과 같은 스크립트로 해결할 수 있다.

 

1. docker image prune

2. systemctl stop docker

3. rm -rf /var/lib/docker

4. systemctl start docker

 

이후 permission issue가 발생한다면

 

5. sudo chmod 666 /var/run/docker.sock

'Docker & k8s' 카테고리의 다른 글

[K8S] 2. Kubernetes Commands  (0) 2022.02.03
[K8S] 1. Kubernetes Core Component  (0) 2022.02.03
도커란? (Docker)  (0) 2020.12.17
쿠버네티스(k8s)는 무엇인가  (0) 2020.12.17
도커 컨테이너 한꺼번에 종료  (0) 2020.11.28

Nginx 를 이용한 Django 배포 (feat. Docker)

runserver로만 장고 서버를 구동하고 있었는데, 성능이나 안정성 이슈가 있다고 한다. django의 runserver 커맨드는 주로 테스트용으로 사용되며, production 용도로는 WAS(Nginx, gunicorn)과 연동하여 배포하는 것이 일반적인 방법이다. 따라서 프로젝트를 진행하면서 django에 웹 서버인 nginx를 연동하는 과정이 있었다.

Docker를 이용하여 nginx를 쉽게 연동하는 방법이 있어 소개해보자 한다.

기존 장고 프로젝트가 있는 상태를 가정하고 진행하겠다. 우분투 기준으로 설명하려한다.

  1. 가상환경으로 들어가서 gunicorn을 설치한다. (무거운 uWSGI 대신 gunicorn으로 nginx와 연결하였다)

    • 참고로 uWSGI나 gunicorn같은 웹서버를 쓸 때, static file을 모으지 않으면 css가 적용되지 않은 상태로 나온다. 해결을 위해서,

      1. settings.py에 아래 코드 추가

        STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
      2. collectstatic 명령어를 통해 static file을 모아줌

        python manage.py collectstatic
  2. source venv/bin/activate pip install gunicorn

  3. 도커 설치

    • 설치에 필요한 패키지들 설치
    • sudo apt-get update && sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-common
    • ppa관련 에러가 뜬다면 아래 스크립트 실행
    • sudo add-apt-repository -r ppa:jonathonf/python-3.6 sudo apt update
    • 도커 설치
    • curl -fsSL https://get.docker.com/ | sudo sh
    • 설치된 도커는 아래 스크립트로 확인할 수 있다.permission denied가 난다면, /var/run/docker.sock 파일의 권한을 변경
    • sudo chmod 666 /var/run/docker.sock
    • docker version
  4. 프로젝트의 루트 디렉토리에 Dockerfile 이라는 파일을 추가해준다. 내용은 아래와 같다.

    • 파이썬 버전에 맞게 첫 줄을 작성해주고
    • 도커 내에서 /code 라는 이름의 폴더를 생성
    • 로컬의 requirements.txt 파일을 mount하고 패키지를 설치하는 과정
    • 현재 로컬의 모든 파일, 폴더를 /code/ 로 마운트
  5. FROM python:3.6 RUN mkdir /code WORKDIR /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/

  6. nginx 폴더를 만들고, nginx.conf 파일 생성server_name에는 도메인 주소를 넣으면 된다. (ex> ec2-54-180-94-185.ap-northeast-2.compute.amazonaws.com)

  7. server { location / { proxy_pass http://web:8000/; } location /static/ { alias /static/; } listen 80; server_name <도메인 주소>; }

  8. 프로젝트의 루트 디렉토리에 docker-compose.yml 파일 생성<프로젝트이름> 는 wsgi.py가 속한 폴더의 이름 (커스텀하지 않는다면 프로젝트 이름)

  9. depends_on을 통해 순서가 있게 서비스가 실행될 것이다. (web -> nginx)

  10. version: '3' services: nginx: image: nginx:latest ports: - '80:80' volumes: - .:/code - ./nginx:/etc/nginx/conf.d - ./staticfiles:/static depends_on: - web web: build: context: . dockerfile: Dockerfile command: gunicorn <프로젝트이름>.wsgi:application --bind 0.0.0.0:8000 volumes: - .:/code - ./staticfiles:/staticfiles expose: - '8000'

  11. settings.py의 ALLOWED_HOSTS에 'web'을 추가

  12. ALLOWED_HOSTS = ['web']

  13. 도커를 실행하고, 브라우저에서 도메인명을 입력하여 정상 작동하는지 확인

    • docker-compose 설치
    sudo pip install docker-compose
    docker-compose up --build

    shell을 꺼도 작동을 하도록 백그라운드 실행을 원한다면 -d 옵션을 추가하면 된다.

  14. docker-compose up --build -d

+ Recent posts