Dag 혹은 Task 코드를 Docker Image로 만들고 이를 독립된 공간 (Docker Container) 안에서 실행Scale Up, Scale Out, K8s와 같은 컨테이너 기술이 필요하다.K8s란 어떤 역할이 명확하게 정해지지는 않았지만 언제든지 사용할 수 있는 공용 서버 클러스터이다.태스크나 DAG 코드를 Docker Image로 만들어서 Docker Container 형태로 실행한다. 이렇게 되면 라이브러리/모듈 충돌을 방지할 수 있고, 개발 환경과 프로덕션 환경을 동일하게 유지할 수 있다.
Airflow Worker를 K8s에서 필요한 대로 동적으로 할당해서 사용한다. 전용 서버를 Airflow에 할당하지 않고 Container Orchestration 서비스를 통해 할당해서 사용하고 리턴한다.
Airflow에서 이를 해결하는 방법은?
KubernetesPodOperator 사용DockerOperator를 사용Airflow Executo로 아래를 사용✍ Airflow Executor는 무엇인가?
- Executor는 Task들을 관리하고 실행하는 역할을 수행한다.
- 이 타입에 따라 병렬 혹은 일렬 실행이나 어떤 worker로 실행할지 결정됨
- 다양한 수의 Executor 타입이 존재한다.
Sequential Executor: default. sqlite와 같은 싱글 스레드 DB에서만 사용 가능하다.Local Executor: task들을 Airflow 마스터 노드안에서 실행Celery Executor: 다수의 Worker 노드가 있는 경우 사용되며 Celery 큐를 사용해 task들을 worker 노드로 분산하여 실행Kubernetes Executor는 K8s 클러스터를 사용하여 task들을 독립된 환경에서 사용Local Kubernetes Executor와Celery Kubernetes Executor도 존재
내가 만든 프로그램이 다른 컴퓨터에서 안 돌아간다면?
설치 과정에서 중요한 파일이 빠지거나
사용하는 라이브러리의 버전이 안 맞거나
환경 설정이 안 맞을 때
이때 가장 쉬운 해결 방법이 Docker이기 때문에 Docker 사용
왜 Docker의 사용이 가장 쉬운 해결 방법인가?
✍ Docker Image와 Docker Container
- Docker Image: 독립적으로 완전하게 만들어진 패키지를 말한다.
- Docker Container: 이 Docker Image를 독립된 환경에서 실행한 것이다.

Virtual Machine은 Host 운영 체제가 존재하고, 그 위에 VM을 생성하고 관리하는 소프트웨어가 있어야 한다. Hypervisors, VMWare, Virtual Box 등.
docker build -t tag(이미지 이름과 버전 지정)FROM: 뭘 기반으로 시작되었는지. (Python, Linux 등)RUN: 어떤 프로그램을 설치할 것인지.ENTRYPOINT, CMD: 프로그램을 실행.ARG, ENV)docker run
FROM node:alpine #OS 종류를 적어 준다. Alpine은 경량 리눅스이고 데모 목적
COPY ./app # 코드 복사에 사용
WORKDIR /app # Working directory를 지정
CMD node app.js # 실행하는 명령 앞에 지정
RUN apt-get update && apt-get install -y curl (RUN 뒤에는 다양한 명령이 올 수 있다. 해당 명령도 &&을 사용해 두 개의 명령을 지정한 것이다.)docker run 명령을 쓰고 뒤에 docker image를 적어 docker image를 실행할 때 어떤 명령어를 실행할 것인지 적어 준다. CMD와 ENTRYPOINT를 두 번 쓰면 마지막 명령만 실행된다.CMD ["command1.sh"]
CMD ["command2.sh"]
#이런 경우 command2.sh만 실행됨
FROM debian:buster
COPY . /myproject
RUN apt-get update …
CMD ["./cmd1.sh"]
docker run my-image를 하면 cmd1.sh가 기본으로 실행되지만 docekr run my-image cmd2.sh를 실행하면 cmd2.sh가 실행된다.ENTRYPOINT가 우선 순위가 되는데 Best는 ENTRYPOINT는 최대한 쓰지 않고 CMD만 쓰는 게 일반적이다.FROM debian:buster
COPY . /myproject
RUN apt-get update …
ENTRYPOINT ["entrypoint1.sh"]
CMD ["param1", "param2"]
ENTRYPOINT가 명령이 되고 CMD가 파라미터를 제공하는 형식으로 쓰인다. #output
docker run my-image
=> entrypoint.sh param1 param2
docker run my-image cmd2
=> entrypoint.sh cmd2 #output
docker run --entrypoint="/cmd3.sh” my-image
docker image lsdocker tag hello-world-docker:latest dockerhub-repo:latest -> 현재 이미지의 repo 이름을 dockerhub repo로 별칭을 만들어 줌 (이름을 바꾸는 게 아니라 별칭)docker image lsdocker login --username=dockerhub docker push dockerhub 
Docker Hub에 Docker Image가 올라간 것을 볼 수 있다.docker version (docker 버전 확인)docker pull dockerhub-repo (접근 권한이 있다면 image가 다운로드가 될 것)docker image lsdocker run dockerhub-repo📌 빌드 시 오류 발생
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested exec /usr/local/bin/docker-entrypoint.sh: exec format error
이런 오류를 막기 위해 이미지 생성 시 --platform을 통해 platform을 지정해 주어야 한다.$ docker build --platform linux/amd64 -t hello-world-docker .
docker run은 새로 Container를 실행하는 것이다.docker exec는 실행된 Container에 작업하는 것이라 Container ID가 꼭 필요하다.Docker Image의 버전이나 변형을 나타내는 문자열Docker Image의 부가 정보를 나타냄 docker image ls에서 Repo에 해당된다.Repo이름:태그docker run ubuntu
ubuntu 이미지가 존재하지 않기 때문에 Docker Hub에서 ubuntu 이미지를 가지고 와 준다. docker ps를 쓰면 ubuntu의 Container가 보이지 않지만 docker ps -a를 쓰면 실행이 끝났던 Container도 보이게 된다.docker run -it ubuntu ubuntu는 그냥 시작하면 바로 끝나게 된다.apt install nano로 다시 설치를 해 주는데 다음과 같은 오류가 또 발생한다면 update를 해 주어야 한다.
apt update를 통해 update를 해 준다. 다양한 소프트웨어를 어디서 받을 수 있는지를 업데이트해 주는 것이다.
apt install nano를 설치하면 제대로 설치가 된다. 이때 nano는 편집기이다.apt remove nano를 해 주면 삭제된다.docker pull mysql/mysql-server:8.0docker run --name=mysql_container mysql/mysql-server:8.0--name=은 Docker Container의 아이디를 주어 ps로 아이디를 찾는 과정을 스킵할 수 있게 해 준다.docker logs mysql_container 2>&1 | grep GENERATEDdocker exec -it mysql_container mysql -uroot -p1. ENTRYPOINT를 사용하면 더 편해지는 경우
- 강의에서는 ENTRYPOINT를 꼭 사용해야 하는 경우는 존재하지 않고 최대한 CMD만 사용하라고 했지만 ENTRYPOINT를 사용하면 더 편해지는 경우가 존재한다고 했다. 그 부분이 궁금해서 조금 더 학습해 보기로 하였다.
- 인수 고정
ENTRYPOINT를 사용하면 Dockerfile에서 컨테이너에 대해 항상 실행되는 기본 실행 명령을 지정할 수 있다.- 예를 들어,
ENTRYPOINT ["java", "-jar", "myapp.jar"]와 같이ENTRYPOINT를 설정하면 컨테이너가 항상java -jar myapp.jar를 실행한다.- 컨테이너 실행 시에 추가 인수를 제공해도
ENTRYPOINT에서 정의한 명령은 변경되지 않고,ENTRYPOINT는 고정된 부분을 유지하며 컨테이너의 기본 실행 명령을 지정한다.- 하지만
CMD명령을 사용하면 default로 설정해 둔 명령이 overriding 된다.- 컨테이너 설정 초기화
ENTRYPOINT는 컨테이너가 시작될 때 설정을 초기화하는 데 사용된다.- 예를 들어, 환경 변수, 파일 복사, 네트워크 구성 등 초기화 작업을 ENTRYPOINT 스크립트에 포함시킬 수 있다.
- 이를 통해 컨테이너가 시작될 때마다 일관된 설정을 보장할 수 있다.
- 정리해 보면 명령어가 먼저 default 값을 설정하지만 상황에 따라 명령어가 달라질 여지가 있을 때는
CMD를 그렇지 않고 변경이 필요 없거나 꼭 실행되어야 하는 명령어일 경우ENTRYPOINT를 사용한다.
2. grep 명령어 Window에서는 어떻게 사용해야 할까?
- 실습 과정에서
docker logs mysql_container 2>&1 | grep GENERATED해당 명령어를 통해 log에서GENERATED라는 문장을 찾는 부분이 있었다.- 입력하니
'grep'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다.다음과 같은 오류가 발생했고 확인해 보니 window에서는grep명령어가 존재하지 않았다.- 대신 써 줄 수 있는 명령어는
findstr였다.findstr는 뒤에 무엇이 붙느냐에 따라 명령어가 조금 달라지게 되는데 기본적으로는 파일에서 문자열을 찾는 명령어이다.docker logs mysql_container 2>&1 | findstr GENERATED해 주니 원하는 결과인GENERATED ROOT PASSWORD: password가 나왔다.