A ship in harbor is safe, but that is not what ships are built for.

개발일지/AI 캠프

내일배움캠프 AI - 50일차 TIL, 2022.11.10

플리피나리 2022. 11. 11. 03:34
반응형

스파르타 코딩클럽 내일배움캠프 AI 웹개발자양성과정 3회차

2022.11.10. 50일차 - TIL

 

 

1. Docker 원격강의

  • 목표
    1) 리눅스에서 docker 패키지를 설치할 수 있다.
    2) docker compose를 설치하고, 컨테이너를 생성할 수 있다.
    3) 포트포워딩에 대해 이해하고 활용할 수 있다,
    4) docker volume에 대해 이해하고 활용할 수 있다.
    5) 이미지를 직접 빌드할 수 있다.
    6) entrypoint를 사용해 컨테이너가 생성될 때 원하는 명령어를 실행시킬 수 있다.
    7) docker compose 에서 두 개 이상의 컨테이너를 생성하고, depends_on을 사용해 실행 순서를 관리할 수 있다.
  • docker : 다양한 어플리케이션을 컨테이너 환경에서 테스트 및 배포할 수 있는 소프트웨어 플랫폼(가상 머신과 다른점 확실히 알기) -> docker 이미지를 통해 동일한 환경을 가진 컨테이너를 쉽게 생성 관리 가능

  • docker 이미지 : docker 컨테이너를 생성하기 위한 것으로 docker 컨테이너가 생성될 때 실행되는 실행파일, 설정 등을 가지고 있다.
  • docker를 사용한 컨테이너 생성과 활용
# docker 패키지 설치
# 실행 전에 반드시 sudo apt update 필수
# 관리자 권한(sudo)으로 설치시 나타나는 모든 물음에 yes를 사용해(-y) docker 패키지(docker.io)를
# 설치한다.(apt install)
sudo apt install docker.io -y


# docker 설치 확인
# docker 버전 출력 확인
sudo docker --version


# docker 컨테이너 생성하기
# 관리자 권한(sudo)으로 httpd의 가장 최신 이미지(httpd:latest)를 사용해 컨테이너를 
# 실행(docker run)시키고, 80번 포트로 접속했을 때 컨테이너에 접근할 수 있도록 
# 포트포워딩(-p 80:80)을 한다.
sudo docker run -d -p 80:80 httpd:latest


# 실행중인 컨테이너 확인하기
# -a : 중지된 컨테이너 목록까지 포함해 모두 확인
# CONTAINER ID : 컨테이너가 가지는 고유 id
# IMAGE : 컨테이너 생성 시 사용된 이미지
# COMMAND : 컨테이너 생성 시 실행되는 명령어
# STATUS : 컨테이너 상태
# PORTS : 사용중인 포트
sudo docker ps
sudo docker ps -a


# 다운받은 이미지 확인하기
# REPOSITORY : 이미지 저장소 이름
# TAG : 이미지 버전
# IMAGE ID : 이미지 고유 id
# CREATED : 이미지 생성일
# SIZE : 이미지 용량
sudo docker images


# 컨테이너 내부로 들어가기
# 컨테이너 아이디 다 안 입력해도 ok(구별만 가능하면...)
# /bin/bash : 컨테이너 접속 시 사용될 쉘
sudo docker exec -it $container_id /bin/bash
  • docker-compose : docker 2개 이상의 컨테이너를 더욱 간편하게 관리하기 위해 사용되는 툴 -> docker-compose.yml파일에 컨테이너에서 사용될 이미지, 옵션 등을 작성 후 사용
# docker-compose 설치하기
# /usr/lib/docker 경로에 cli-plugins라는 디렉토리를 생성(mkdir), 상위 폴더 없을 시 자동 생성(-p)
sudo mkdir -p /usr/lib/docker/cli-plugins

# github에 release된 docker-compose 파일을 /usr/lib/docker/cli-plugins/ 경로에 다운로드
sudo curl -SL https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-x86_64 -o /usr/lib/docker/cli-plugins/docker-compose
# 다운받은 docker-compose 파일(/usr/lib/docker/cli-plugins/docker-compose)에 실행 권한(chmod +x) 부여
sudo chmod +x /usr/lib/docker/cli-plugins/docker-compose
# docker-compose 설치 버전 확인
sudo docker compose version


# docker-compose로 컨테이너 생성하기
# docker 컨테이너 삭제하기
sudo docker ps -a  # docker에 존재하는 컨테이너 목록보기
sudo docker rm -f $container_id  # 컨테이너의 실행 중 여부와 관계없이 강제로 삭제하기

# docker-compose.yml 작성해보기
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.

services:
  example: # 서비스 이름을 지정, 서비스 이름은 컨테이너끼리 통신할 때 사용
    container_name: example # 컨테이너 이름을 지정
    image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정
    restart: always # 컨테이너가 종료됐을 때 다시 실행
    
# 컨테이너 실행시켜보기
# up : docker-compose.yml 파일을 읽어 정의된 서비스 실행
# -d : 컨테이너를 데몬(백그라운드)으로 실행
sudo docker compose up -d

# 컨테이너 중지시키기
sudo docker compose stop  # 컨테이너 중지시키기
sudo docker compose start # 컨테이너 재실행
sudo docker ps -a  # docker에 존재하는 컨테이너 목록보기
sudo docker compose down  # 컨테이너 중지시키기(컨테이너를 remove해 중지)
sudo docker compose up # 컨테이너 재실행(컨테이너 재생성 후 재실행)
sudo docker ps -a  # docker에 존재하는 컨테이너 목록보기
  • 포트 포워딩(port forwarding) : 외부에서 서버의 특정 포트에 접근했을 때 지정한 서비스로 전달해주는 것
    - http(80), https(443), postgresql(5432), django(8000), ssh(22)
    - 80:8000 >> 외부에서 80포트로 접속했을 때 해당 컨테이너의 8000번 포트로 접속
# docker-compose.yml 수정
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의

services:
  example: # 서비스 이름을 지정, 서비스 이름은 컨테이너끼리 통신할 때 사용
    container_name: example # 컨테이너 이름을 지정
    image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정
    ports: # 포트포워딩을 설정
     - 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결
    restart: always # 컨테이너가 종료됐을 때 다시 실행
    
# 컨테이너 실행
sudo docker compose restart

# 컨테이너 로그 확인
sudo docker compose logs
# 실시간 컨테이너 로그 확인
sudo docker compose logs -f
  • volume : 컨테이너에 저장되는 데이터의 일부를 host와 공유해주는 역할 -> host에 저장된 데이터는 사용자가 직접 삭제하기 전까지 계속 유지
    - docker volume : docker 엔진이 권장하는 방식으로 생성된 volume은 host의 /var/lib/docker/volumes/ 경로에 저장 -> 컨테이너간 파일을 공유 or 중요도가 높은 파일
    - bind mount : docker 엔진의 관리를 받지 않아 사용자가 직접 파일을 추가/수정/삭제 가능 -> 설정파일 혹은 소스코드를 프로젝트와 서버가 공유할 때
    - tmpfs mount : 휘발성 메모리인 RAM에 저장 -> 많은 양의 데이터 or 보안적으로 중요한 데이터
# docker-compose.yml(bind mount)
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의

services:
  example: # 서비스 이름을 지정, 서비스 이름은 컨테이너끼리 통신할 때 사용
    container_name: example # 컨테이너 이름을 지정
    image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정
    ports: # 포트포워딩을 설정
      - 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결
    volumes: # volume을 설정
      - ./example_http_code/:/usr/local/apache2/htdocs/ # 정의한 volume의 mount할 경로를 지정
    restart: always # 컨테이너가 종료됐을 때 다시 실행
    
##############################################################################################    
    
# docker.compose.yml(docker volume)
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의

volumes:
  example_http_code: {} # docker volume을 정의합니다.

services:
  example: # 서비스 이름을 지정, 서비스 이름은 컨테이너끼리 통신할 때 사용
    container_name: example # 컨테이너 이름을 지정
    image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정
    ports: # 포트포워딩을 설정
      - 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결
    volumes: # volume을 설정
      - example_http_code:/usr/local/apache2/htdocs/ # 정의한 volume의 mount할 경로를 지정
    restart: always # 컨테이너가 종료됐을 때 다시 실행
# volume 설정 확인하기
# volume 목록보기
sudo docker volume ls

# volume의 이름으로 설정 정보 확인하기
sudo docker volume inspect $volume_name


# 사용하지 않는 dockeer volume 삭제하기
sudo docker volume prune
  • Dockerfile : docker 이미지를 직접 생성하기 위한 용도로 작성하는 파일(기본 이미지 지정, 특정 패키지 설치, 파일 추가 등) -> 사용자가 개발한 프로젝트 혹은 설정파일 등을 이미지에 포함시키거나 이미지에 기본적으로 특정 패키지를 설치하고 싶을 때 사용
# Dockerfile 작성하기
# 빌드할 때 사용할 이미지 지정
FROM httpd:latest

# 현재 경로에 존재하는 index.html 파일을 컨테이너 내부로 복사
COPY ./index.html /usr/local/apache2/htdocs/index.html


# docker-compose.yml
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의

services:
  example: # 서비스 이름을 지정, 서비스 이름은 컨테이너끼리 통신할 때 사용
    container_name: example # 컨테이너 이름을 지정
    build: . # 현재 경로에 있는 Dockerfile을 사용해 이미지를 생성
    ports: # 포트포워딩을 설정
      - 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결
    restart: always # 컨테이너가 종료됐을 때 다시 실행
    
    
# index.html을 작성해 docker 실행하기
vi index.html  # 내용 추가
sudo docker compose up --build -d
  • entrypoint : docker 컨테이너가 생성될 때 기본적으로 실행 할 명령어를 지정해주는 옵션 -> Dockerfile과 docker-compose.yml 모두 작성 가능(docker-compose.yml 명령어가 우선적)
# Dockerfile
FROM python:3.9.15

# .pyc 파일을 생성하지 않도록 설정
ENV PYTHONDONTWRITEBYTECODE 1

# 파이썬 로그가 버퍼링 없이 즉각적으로 출력하도록 설정
ENV PYTHONUNBUFFERED 1

# /app/ 디렉토리를 생성
RUN mkdir /app/

# /app/ 경로를 작업 디렉토리로 설정
WORKDIR /app/

# main.py 파일을 /app/ 경로로 복사
COPY ./main.py /app

############################################################################################

# docker-compose.yml
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의

services:
  example: # 서비스 이름을 지정, 서비스 이름은 컨테이너끼리 통신할 때 사용
    container_name: example # 컨테이너 이름을 지정
    build: . # 현재 경로에 있는 Dockerfile을 사용해 이미지를 생성
    entrypoint: sh -c "python3 main.py" # 작업 디렉토리에 존재하는 main.py 파일을 실행
    restart: always # 컨테이너가 종료됐을 때 다시 실행
    
############################################################################################

# vi 편집기로 python 파일 생성 후 entrypoint 사용해 컨테이너에서 실행
sudo docker compose up --build -d  # 컨테이너 생성
sudo docker compose logs -f  # log 명령어
  • 컨테이너는 ports 혹은 서비스 이름 등이 중복되지 않는 값으로 설정한다.
# 컨테이너 두 개 이상 띄워보기
# docker-compose.yml
version: '3.8'

services:
  example1:
    container_name: example1
    image: 'httpd:latest'
    ports:
      - 80:80
    restart: always
    
  example2: # 서비스 이름이 동일하면 컨테이너가 정상적으로 생성되지 않을 수 있다.
    container_name: example2 # 컨테이너 이름이 동일하면 컨테이너 생성 시 에러가 발생한다.
    build: .
    entrypoint: sh -c "python3 main.py"
    restart: always
    
# 컨테이너를 실행시켜 두 개의 컨테이너가 실행되는 것을 확인
sudo docker compose up

# depends_on을 사용해 컨테이너 실행 순서 바꾸기
# docer-compose.yml
version: '3.8'

services:
  example1:
    container_name: example1
    image: 'httpd:latest'
    ports:
      - 80:80
    depends_on:
      - example2 # 해당 컨테이너보다 먼저 실행되어야 하는 컨테이너를 지정한다.
    restart: always
    
  example2: # 서비스 이름이 동일하면 컨테이너가 정상적으로 생성되지 않을 수 있다.
    container_name: example2 # 컨테이너 이름이 동일하면 컨테이너 생성 시 에러가 발생한다.
    build: .
    entrypoint: sh -c "python3 main.py"
    
    restart: always
    
# 실행순서 확인
sudo docker compose up -d
반응형