지난 주차에 docker기반 airflow설치에 대해 알아보았다면 이번 주차에는 docker는 물론, k8s에 대해 알아보고자 한다.
지난 주에 학습한 대로 dag는 무방향 무순환 그래프로서 태스크로 구성되었고 위상정렬과 유사한 형태를 띈 ETL 과정을 의미한다.
이러한 dag로부터 태스크대로 흘러 작업을 진행하게 되는데 dag 수가 1개이거나 몇 개인 경우, 작업하는데 있어 그렇게 오래 걸리진 않을 것이다. 그러나 만일 개수가 많아진다면 data quality와 lineage에 문제가 발생할 것이다.
이때 다수의 서버를 airflow에 할당해 운영하는 경우 발생할 수 있는 문제로는 아래와 같다.
문제에 대해 더 자세히 살펴보면 다음과 같다.
- library 충돌
- dag에 따라 실행에 필요한 모듈/라이브러리가 다름 (python, java 등등)
-> DAG, TASK별 별도의 독립공간 생성 필요. 즉, DAG 혹은 Task 코드를 docker image로 만들어 이를 docker container에서 실행하기.
- Worker 부족
- scale up, scale out, k8s(공용 서버 클러스터)와 같은 컨테이너 기술 사용해 온디맨드로 서버 요청해 처리
- 낮은 server utilization 이슈
- 서비스 별로 서버를 할당하기엔 별도로 capacity 관리 필요함.
-> k8s와 같은 컨테이너 기술 도입 필요💯 그렇다면 해결책은 ?
- DAG 혹은 Task 코드를 docker image로 만들어 이를 docker container에서 실행하기.
- airflow worker를 k8s에서 필요한 대로 동적으로 할당해 사용 (온디맨드 처리)
- Airflow에서 해결하는 방법
- KubernetesPodOperator 사용
- DockerOperator 사용
- Executor로 Kubernetes, CeleryKubernetes, LocalKubernetes 사용하기
-> Airflow Executor란 : 태스크를 관리하고 실행하는 역할 수행 (병렬, 직렬, 어느 worker에서 진행 등)- KubernetesExecutor : 모든 dag 코드가 image로 빌드되어 k8s에서 실행
- CeleryKubernetesExecutor : 소수의 task만 Isolation필요한 경우
- LocalKubernetesExecutor : Local, Kubernetes 동시 사용
목적 : 내 컴퓨터 환경을 그대로 패키징해 타인에게 전달하는 것
- docker image : 독립적으로 완전하게 만들어진 패키지
- docker container : docker image를 독립된 환경에서 실행한 것
< 위 그림은 docker flow를 잘 보여준 도표 >목표는 결국 SW를 일관되게 docker파일을 빌드하면 image가 생성되고 이후 container를 실행해 배포하기 위함이다.
🎈 VM
이전에 AWS를 학습하면서 EC2 인스턴스를 배우며 가상머신에 대해 학습을 진행했었다.
다시 간단히 정리를 해보면 VM이란 하드웨어를 추상화해 한 컴퓨터위에 가상 컴퓨터를 올리는 것을 의미한다. VM을 생성하고 관리하기 위한 SW로는 VMWare, VirtualBox, Hyper-v 등이 있다.
- 장점 : SW 실행을 위해 독립 공간 제공 및 다수의 SW를 각 VM level에서 독립적으로 실행 가능
- 단점 : 각 VM은 자신만의 OS 필요하며 자원을 많이 사용하기에 vm끼리 자원을 나누어 써야 한다.
🎈 docker container
현 시점 VM을 대체하는 것으로 VM과 비슷한 목적을 가지고 등장하였고 자체 파일 시스템 (Volume)을 가지고 있다.
- 장점 : VM에 비해 자원 소비가 적다는 점. 호스트 OS를 사용해 비용이 발생하지 않는 점, 서버 프로그램, 커맨드라인, 리눅스 기반 프로그램 개발 시 유용
- 단점 : container 수가 늘어나면 관리가 힘들고 CUI SW 개발에 부적합, Cross-platform compatibility 항상 지원 X
-> VM 과 Container를 디테일하게 비교해보면 다음과 같다.
- vm은 cpu, 자원 등 무게가 무거운 반면, container는 경량화된 VM이라고 보면 된다.
- 둘다 다수의 시스템을 올릴 수 있으나, VM은 docker에 비해 실행되는 개수가 적고 자체 OS를 갖지만 container는 docker engine만 있다면 호스트 OS위에서 작동하는 애플리케이션이다.
- MAC의 경우 경량화된 리눅스 docker가 동작한다.
🎈 HighLevel docker 사용 프로세스
- 다수의 component로 구성되는 SW라면 각각 docker image로 만들어야 함.
- docker image로 빌드하는 방법을 Dockerization이라 부름
- 이후 빌드된 image는 한 container안에서 실행된다.
🎈 docker hub
docker registry : docker image들의 보관소로 대표적인 예제로 docker hub 존재
-> 별도로 docker hub 설치해 image 공유하고 찾기 작업 가능public repo, private repo 존재해 협업 가능, 깃헙 연동을 위한 automated build 제공
- 도표로 확인하면 registry는 다음과 같다.
🎈 docker file command keyword
- ARG : image 생성 시 사용되는 변수 지정, 최종 이미지에 저장 X
- ENV : 컨테이너 실행 시 사용되는 환경변수로 최종 이미지에 저장됨
- USER : 컨테이너 실행 시 사용할 user ID
- EXPOSE : 서비스 사용 포트번호
- RUN : 빌드 시 실행되어야 하는 명령들이 지정
-> docker build, RUN apt-get update && apt-get install -y curl- cmd, entrypoint : container 시작할 때 실행되어야 하는 명령어 지정 시 사용 (docker run)
-> 둘다 한 docker file에서 여러 번 실행되면 각각 마지막 것만 사용되며 CMD만 사용하는 것이 best-practice임.
-> 단, ENTRYPOINT의 경우 --entrypoint옵션을 통해서만 덮어쓰기가 가능하고 entrypoint가 있으면 cmd값이 파라미터로 실행된다.docker 명령 요약
- docker version :
- docker build -t : image 이름 부여 (코론 사용 시 tag, version 정보까지 가능)
- docker push : image 업로드
- docker tag : 특정 이미지의 버전, 이름 변경
- docker pull : 타인이 작업한 파일 내 리포에 업로드
- docker run : 새로 container 실행 (p : port mapping, v : volume mapping)
- docker exec : 실행된 container에 작업하는 것
🎈 MySQL 8.0을 docker로 실행하기
- MySQL docker image 다운로드
-> $ docker pull mysql/mysql-server:8.0- 다운받은 이미지로 docker container 실행
-> $ docker run --name=mysql_container mysql/mysql-server:8.0- MySQL root 계정의 패스워드 찾기
-> $ docker logs mysql_container 2>&1 | grep GENERATED- 마지막으로 MySQL shell 실행하기
-> $ docker exec -it mysql_container mysql -uroot -p