수업 68일차

galoo·2023년 10월 11일
0

HelloVision Dx Data School

목록 보기
62/72

✔ Docker-Compose

작성 방법

기본 구성

  • 주 항목 / 정의 내용으로 나누어진다.

버전 정의

  • yaml 코드의 첫 줄에는 버전을 정의해야 한다.

서비스 정의

  • 컨테이너를 실행하는 것과 동일한 개념
  • 서비스 이름을 정의하고, 하위 레벨에 도커 명령과 유사하게 컨테이너 실행에 필요한 옵션을 작성
  • docker run --name=myweb nginx:latest 가 있을 때, yaml은?
version "3"
services:
  myweb:
    image: ningx:latest
  • Dockerfile을 이용한 이미지의 경우
version "3"
services:
  myweb:
    build: .
  mariadb:
    build:
      context: .
      dockerfile: 도커파일경로

하위 옵션

  • container_name
    - --name과 같은 옵션으로, 컨테이너 이름설정
  • ports
    - -p와 같은 옵션으로, 포트포워딩 설정
  • expose
    - 외부로 노출하지는 않고, 필요 시 링크로 연결된 서비스와 서비스 간의 통신을 허용할 때 사용하는 포트
  • networks
    - --net옵션과 같은 옵션으로, 하나의 네트워크로 묶을 때 사용
  • volumes
    - -v옵션과 같은 옵션으로, 볼륨을 사용하고자 할 때 사용
  • environments
    - -e옵션과 같은 옵션으로, 환경 설정을 할 때 사용
  • command
    - 서비스가 구동된 뒤 실행할 명령어를 작성
  • restart
    - --restart옵션과 동일하며, 재시작 옵션
  • depends_on
    - 서비스 간의 종속성을 의미하며, 먼저 실행해야 하는 서비스를 지정

네트워크 정의

  • 네트워크
    - 여러 컨테이너들이 서로 연결될 수 있도록 해주는 것
  • docker-compose는 네트워크를 지정하지 않으면, 자체 기본 네트워크를 자동으로 생성
  • 최상위 레벨에 networks 지정 시, 해당 이름의 네트워크가 생성되고, 대역은 172.x.x.x로 자동할당 됩니다.
  • cmd에다가 docker network ls 해보면 bridge로 되어있는 것이 기본

볼륨 정의

  • 도커 엔진 내부의 공간과 컨테이너 사이의 데이터를 공휴가 위한 것
  • 컨테이너 내부의 데이터를 반 영구적으로 보관하기 위한 목적으로 사용

✔ 도커 명령어와 Docker-compose 비교

  • DB-mysql:8.0을 사용하고, 웹-wordpress:5.7을 이용하는 웹 애플리케이션 서비스
    - 각 컨테이너는 각각의 볼륨을 소유하고, 2개의 컨테이너는 하나의 네트워크로 묶어서 사용
    - 이 작업을 할 때, wordpress나 redmine을 많이 사용하는데, 이유는 wordpress나 redmine은 mysql이나 mariadb가 연결되지 않으면 에러를 발생시키기 때문이다.

도커 명령어 사용

  • 2개의 볼륨 생성
    - docker volume create mydb_data
    - docker volume create myweb_data
  • 볼륨 확인
    - docker volume ls
  • 네트워크를 생성
    - docker network create 이름
  • 네트워크를 확인
    - docker network ls
  • MySQL 컨테이너부터 생성해보자(wordpress)
    - docker run -dit --name=컨테이너이름 -v mydb_data:/var/lib/mysql --net=myapp-net --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=관리자비밀번호 -e MYSQL_DATABASE=데이터베이스이름 -e MYSQL_USER=기본유저 -e MYSQL_PASSWORD=유저비밀번호 mysql:8.0
    - docker run -dit --name=mysql_app -v mydb_data:/var/lib/mysql --net=myapp-net --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=supersonic -e MYSQL_DATABASE=sonic -e MYSQL_USER=sonic -e MYSQL_PASSWORD=supersonic mysql:8.0
    - 확인: docker ps
    - docker ps 에서 안되고 docker ps -a에서 확인된다면 실행 오류
    - 포트 확인 : db 접속도구에서 확인해보자 (3306번 포트)
  • WordPress 컨테이너 생성
    - 로그 데이터는 사용자가 보아야 하는 데이터이므로, 볼륨에 연결하지 않고 하드디스크에 직접 연결하기도 합니다.
    - docker run -dit --name=컨테이너 이름 -v myweb_data:/var/www/html wordpress:5.7 -v ${PWD}/myweb-log:/var/log --net=myapp-net --restart=always -p 외부에노출할포트:80 -e WORDPRESS_DB_HOST=데이터베이스컨테이너:포트번호 -e WORDPRESS_DB_NAME=사용할데이터베이스이름 -e WORDPRESS_DB_USER=데이터베이스계정 -e WORDPRESS_DB_PASSWORD=계정비밀번호 --link 사용할데이터베이스컨테이너:mysql wordpress:5.7
    - docker run -dit --name=wordpress_app -v myweb_data:/var/www/html -v ${PWD}/myweb-log:/var/log --net=myapp-net --restart=always -p 8001:80 -e WORDPRESS_DB_HOST=mysql_app:3306 -e WORDPRESS_DB_NAME=sonic -e WORDPRESS_DB_USER=sonic -e WORDPRESS_DB_PASSWORD=supersonic --link mysql_app:mysql wordpress:5.7
    - 최종
    - docker run -dit --name=wordpress_app -v myweb_data:/var/www/html -v ./myweb-log:/var/log --net=myapp-net --restart=always -p 8008:80 -e WORDPRESS_DB_HOST=mysql_app:3306 -e WORDPRESS_DB_NAME=sonic -e WORDPRESS_DB_USER=sonic -e WORDPRESS_DB_PASSWORD=supersonic --link mysql_app:mysql wordpress:5.7
    - ${PWD}부분이 틀렸다 \rarr 현위치로 -v ./myweb-log로 수정
    - 확인 : docker ps
    - 브라우저에서 localhost:외부에 노출할 포트번호

docker-compose.yaml 이용

빈 디렉 생성

디렉에 docker-compose.yaml 생성

version: "3"
services:
  mydb:
    image: mysql:8.0
    container_name: mysql_app
    volumes:
      - mydb_data:/var/lib/mysql
    networks:
      - myapp-net
    restart: always
    ports:
      - "3306:3306" # 3306 쓰고있으면 mysql 컨테이너 끄기(stop)
    environment:
      MYSQL_ROOT_PASSWORD: supersonic
      MYSQL_DATABASE: sonic
      MYSQL_USER: sonic
      MYSQL_PASSWORD: supersonic 
  myweb:
    image: wordpress:5.7
    container_name: wordpress_app
    volumes:
      - myweb_data:/var/www/html
      - ./myweb-log:/var/log
    networks:
      - myapp-net
    restart: always
    ports:
      - "8008:80"
    environment:
      WORDPRESS_DB_HOST: mydb:3306
      WORDPRESS_DB_NAME: sonic
      WORDPRESS_DB_USER: sonic
      WORDPRESS_DB_PASSWORD: supersonic
    depends_on:
      - mydb 
networks:
  myapp-net: {}
volumes:
  mydb_data: {}
  myweb_data: {}
  • networks는 backend-net과 frontend-net 사용이 가능하다고 하네

✔ Load Balancer

Load Balancing (부하 균등)

  • 동일한 기능을 수행하는 여러 개의 애플리케이션을 만들어두고 요청이 오면 적절한 애플리케이션(하드웨어)을 선택해서 수행하도록 해주는 기능
  • 부하 분산을 위한 필수 네트워크 기술
  • 리소스 활용도를 최적화하고 처리량을 최대화하며 지연 시간을 줄이고, 내결함성(Fault Tolerance) 구성을 보장해서 안정적인 시스템 운영이 가능하도록 합니다.

  • Docker는 HaProxy, Nginx/Apache 등 외부 서비스를 이용해서 로드 밸런싱을 구현하는 것이 가능합니다.

로드 밸런싱 알고리즘

  • 라운드 로빈 알고리즘 (RR)
    - 클라이언트 요청을 서버의 가중치를 고려해서 구성된 서버에 균등 배분하는 방식으로 경로 보장이 안됨
  • 최소 연결(Least Connection)
    - 현재 연결된 클라이언트 수가 가장 적은 서버로 요청을 전달, 경로 보장이 안됨
  • IP Hash
    - 해시 키를 이용해서 IP별 INDEX를 생성해서 동일 IP주소는 동일 서버로의 경로를 보장하는 방식으로, 해당 서버의 장애가 발생하면 주소는 변경되고, 균등 배분 보장이 안됨
    - 트랜잭션이 긴 작업에 이용함
  • General Hash
    - 사용자가 정의하는 키를 이용한 서버 지정 방식
  • 최소 시간(Least Time)
    - 요청에 대한 낮은 평균 지연 시간을 기준으로 계산해서 서버를 지정
  • random

로드 밸런서 구현

  • 동일한 python flask 앱을 3개 만들고, 앞에 nginx를 추가해서 클라이언트의 요청을 nginx가 받아서 RR 방식을 이용해서 각 flask 앱에 전송
  • 원래는 모든 flask 앱이 동일한 모양이어야 하지만, 편의상 보여지는 내용을 다르게 구성

실습

=>디렉토리 생성
mkdir loadbalancer
cd loadbalancer
mkdir nginx_alb pyfla_app1 pyfla_app2 pyfla_app3
____
=>nginx 작업
 - cd nginx_alb
____
 - Dockerfile 생성
FROM nginx
#기본 환경 설정을 제거
RUN rm /etc/nginx/conf.d/default.conf
#환경 설정 파일을 복사
COPY nginx.conf /etc/nginx/conf.d/default.conf
____
 - niginx.conf 파일을 생성하고 작성
upstream web-alb{
    server 172.17.0.1:5001;
    server 172.17.0.1:5002;
    server 172.17.0.1:5003;
}
server{
    location /{
        proxy_pass http://web-alb;
    }
}
___
=>pyfla_app1 작업
 - Dockerfile 생성
FROM python:3
COPY . .
WORKDIR /
RUN pip install flask
COPY . /
ENTRYPOINT ["python"]
CMD ["app.py"]
____
 - app.py 파일 생성
 from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
    return "Web Application [1]" + "\n"
#flask를 5000번 포트로 실행
if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0")
=>pyfla_app2 작업
pyfla_app1 의 파일을 pyfla_app2 디렉토리로 복사
=>pyfla_app3 작업
pyfla_app1 의 파일을 pyfla_app3 디렉토리로 복사
=>확인
python app.py 
docker build -t flaskapp .
docker run -dit -p 5000:5000 --name=flaskapp flaskapp
____
=>loadbalance 디렉토리에 docker-compose.yaml 파일을 만들고 작성
___
version: "3"
services:
  pyfla_app1:
    build: ./pyfla_app1
    ports:
      - "5001:5000"
  pyfla_app2:
    build: ./pyfla_app2
    ports:
      - "5002:5000"
  pyfla_app3:
    build: ./pyfla_app3
    ports:
      - "5003:5000"
  nginx:
    build: ./nginx_alb
    ports:
      - "8080:80"
    depends_on:
      - pyfla_app1
      - pyfla_app2
      - pyfla_app3
  • 브라우저에서 localhost:8080 를 입력해서 수행한 후 새로고침을 수행
profile
밀가루 귀여워요

0개의 댓글