Google Kubernetes Engine (GKE)에 helm 차트를 활용해서 airflow 배포를 하는 법에 대해서 포스팅하려고 합니다.
코드는 아래 github에서 확인할 수 있습니다.
https://github.com/mjs1995/muse-data-engineer/blob/main/blog/gcp/gke_airflow.md
helm차트를 활용한 Apache Airflow 배포
Google Kubernetes Engine (GKE)에 helm 차트를 활용해서 airflow 배포를 하는 법에 대해서 포스팅하려고 합니다.
- gcloud는 Google Cloud Platform(GCP) 리소스를 관리하고 조작하는 데 사용되는 커맨드 라인 인터페이스(CLI) 도구입니다. gcloud 명령어를 사용하면 GCP의 다양한 서비스와 리소스를 생성, 수정, 삭제 및 관리할 수 있습니다.
- 먼저 GCP의 기본 작업 프로젝트를 ggke-401900로 설정합니다.
$ gcloud config set project ggke-401900
"asia-northeast3" (서울) 지역에 gke-airflow라는 이름의 GKE 클러스터를 생성하며, 클러스터에는 e2-medium 머신 유형의 하나의 노드가 포함합니다.
$ gcloud container clusters create gke-airflow \
--machine-type e2-medium \
--num-nodes 1 \
--region "asia-northeast3" \
--enable-autoscaling \
--min-nodes 1 \
--max-nodes 3
gke 클러스터의 인증 정보를 가져와 로컬 시스템의 kubeconfig 파일에 저장합니다. 이때 kubeconfig 파일에 클러스터의 인증 정보가 추가되기 때문에 kubectl을 사용하여 클러스터 리소스를 생성, 수정, 삭제하는 등의 작업을 수행할 수 있게 됩니다.
$ gcloud container clusters get-credentials gke-airflow --region "asia-northeast3"
$ helm repo add apache-airflow https://airflow.apache.org
$ helm repo list
NAME URL
apache-airflow https://airflow.apache.org
airflow 네임스페이스를 생성해 줍니다.
$ kubectl create namespace airflow
Airflow를 GKE에 배포합니다.
$ helm upgrade --install airflow apache-airflow/airflow -n airflow --debug
You can get Fernet Key value by running the following:
echo Fernet Key: $(kubectl get secret --namespace airflow airflow-fernet-key -o jsonpath="{.data.fernet-key}" | base64 --decode)
###########################################################
# WARNING: You should set a static webserver secret key #
###########################################################
You are using a dynamically generated webserver secret key, which can lead to
unnecessary restarts of your Airflow components.
Information on how to set a static webserver secret key can be found here:
https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#webserver-secret-key
Airflow의 웹 UI에 접속합니다.
$ kubectl port-forward svc/airflow-webserver 8080:8080 --namespace airflow
Apache Airflow DAGs 동기화를 위한 git-sync 설정
helm 차트를 사용하여 gke 상에서 airflow를 배포하였습니다. 이제 Git 리포지터리에 저장된 DAGs를 Airflow와 연동하는 방법을 소개합니다.
SSH 키 쌍 생성 및 GitHub 등록
SSH 키 생성: 아래의 명령어를 사용하여 개인 저장소에 대한 SSH 키 쌍을 생성합니다
$ ssh-keygen -t rsa -b 4096 -C "{id}@{domain}.com"
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
The key's randomart image is:
+---[RSA 3072]----+
| . |
| . o |
| . + + .|
| . + = o .o|
| ..S O o oo.|
| oo..oE B.. |
| o+= ...Bo |
| ..*O. oo..o|
| .=*+=+ .o|
+----[SHA256]-----+
GitHub에 SSH 키 등록: 생성된 공개 키(.ssh/id_rsa.pub)를 GitHub 계정에 연결합니다.
- GitHub의 Settings → SSH and GPG keys → New SSH key로 이동합니다.
- 공개 키 내용을 붙여 넣고 저장합니다.
Kubernetes Secret 생성
비공개 SSH 키를 Kubernetes Secret으로 변환합니다. 이렇게 하면 git-sync가 Git 리포지터리에 안전하게 접근할 수 있습니다.
- SSH 인증을 위해 GitHub에 등록된 공개키(id_rsa.pub)와 함께 대응하는 개인키(id_rsa)가 필요합니다. GitHub는 공개키를 사용하여 인증 요청을 확인하고, git-sync와 같은 클라이언트는 대응하는 개인키를 사용하여 인증 요청을 서명합니다.
$ kubectl create secret generic airflow-gke-git-secret --from-file=gitSshKey=/home/mun_js/.ssh/id_rsa -n airflow
secret/git-ssh-key created
Kubernetes Secret이 잘 생성되었는지 확인합니다.
$ kubectl get secret -n airflow
NAME TYPE DATA AGE
airflow-broker-url Opaque 1 66m
airflow-fernet-key Opaque 1 66m
airflow-gke-git-secret Opaque 1 63m
airflow-metadata Opaque 1 66m
airflow-postgresql Opaque 1 66m
airflow-redis-password Opaque 1 66m
my-webserver-secret Opaque 1 44m
sh.helm.release.v1.airflow.v1 helm.sh/release.v1 1 66m
sh.helm.release.v1.airflow.v2 helm.sh/release.v1 1 62m
sh.helm.release.v1.airflow.v3 helm.sh/release.v1 1 42m
git-sync 설정 및 Kubernetes Pod 생성
- Git-Sync sidecar에 대해서 공식문서를 참고하였습니다.
- Helm 설정 값 추출: Airflow Helm 차트의 기본 설정 값을 가져옵니다.
$ helm show values apache-airflow/airflow > values.yaml
$ vi values.yaml
values.yaml 파일 수정: git-sync 설정을 활성화하고, 필요한 정보를 업데이트합니다.
gitSync:
enabled: True
repo: git@github.com:mjs1995/gcp-de-pipeline.git
branch: main
rev: HEAD
subPath: "terraform-airflow-gke/airflow"
sshKeySecret: airflow-gke-git-secret
수정된 values.yaml 파일을 사용하여 Helm 차트를 업데이트합니다.
helm upgrade airflow apache-airflow/airflow -f values.yaml -n airflow --debug
웹서버 시크릿 키를 설정
- 웹서버의 시크릿 키를 동적으로 생성하는 것에 대해 에러 메시지를 반환하고 있어 정적인 웹서버 시크릿 키를 설정합니다.
- Secret을 airflow 네임스페이스로 이동하기 위해서 먼저 Secret을 YAML 파일로 저장합니다.
$ kubectl create secret generic my-webserver-secret --from-literal="webserver-secret-key=$(python3 -c 'import secrets; print(secrets.token_hex(16))')"
$ kubectl get secret my-webserver-secret --namespace=default -o yaml > my-webserver-secret.yaml
$ ls
my-webserver-secret.yaml README-cloudshell.txt values.yaml
YAML 파일에서 네임스페이스 항목을 변경합니다.
$ sed -i 's/namespace: default/namespace: airflow/' my-webserver-secret.yaml
변경된 YAML 파일을 새로운 네임스페이스에 적용합니다.
$ kubectl apply -f my-webserver-secret.yaml
secret/my-webserver-secret created
Secret이 올바른 네임스페이스에 있는지 확인한 후, Helm 업그레이드를 다시 시도합니다.
$ helm upgrade airflow apache-airflow/airflow -n airflow --set webserverSecretKeySecretName=my-webserver-secret --debug
NOTES:
Thank you for installing Apache Airflow 2.7.1!
Your release is named airflow.
You can now access your dashboard(s) by executing the following command(s) and visiting the corresponding port at localhost in your browser:
Airflow Webserver: kubectl port-forward svc/airflow-webserver 8080:8080 --namespace airflow
Default Webserver (Airflow UI) Login credentials:
username: admin
password: admin
Default Postgres connection credentials:
username: postgres
password: postgres
port: 5432
You can get Fernet Key value by running the following:
echo Fernet Key: $(kubectl get secret --namespace airflow airflow-fernet-key -o jsonpath="{.data.fernet-key}" | base64 --decode)
이제 Airflow의 웹 UI에 접근할 수 있게 됩니다.
$ kubectl port-forward svc/airflow-webserver 8080:8080 --namespace airflow
helm 차트 배포 시 롤백을 할 경우에는 다음과 같은 방법으로 진행하면 됩니다.
먼저 롤백하고자 하는 릴리즈의 이전 버전들을 확인하기 위해서 helm history 명령어를 사용합니다
$ helm history airflow -n airflow
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Thu Oct 22 19:03:21 2023 deployed airflow-8.8.0 2.6.3 Install complete
2 Thu Oct 22 19:07:02 2023 failed airflow-1.11.0 2.7.1 Upgrade "airflow" failed: cannot patch "airflow-scheduler" with kind Deployment: Deployment.apps "airflow-scheduler" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"component":"scheduler", "release":"airflow", "tier":"airflow"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable && cannot patch "airflow-postgresql" with kind StatefulSet: StatefulSet.apps "airflow-postgresql" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'ordinals', 'template', 'updateStrategy', 'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden && cannot patch "airflow-worker" with kind StatefulSet: StatefulSet.apps "airflow-worker" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'ordinals', 'template', 'updateStrategy', 'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden
3 Thu Oct 22 19:12:48 2023 deployed airflow-8.8.0 2.6.3 Rollback to 1
이전 버전으로 롤백하려면 helm rollback 명령어를 사용합니다.
$ helm rollback airflow 1 -n airflow
Rollback was a success! Happy Helming!
'Cloud' 카테고리의 다른 글
[GKE] Trino를 사용하여 MinIO에 저장된 데이터 쿼리하기(1) - Hive Metastore MySQL로 구성 (1) | 2023.12.31 |
---|---|
[GCP] GKE의 Apache Airflow에 minio 연동하기 (1) | 2023.11.19 |
[GCP] GKE에서 Prometheus와 Grafana로 클러스터 모니터링 구축하기 (0) | 2023.11.12 |
[GCP] GKE의 Apache Airflow에 Slack 연동하기 (0) | 2023.11.05 |
[GCP] GKE에 Terraform을 활용한 Airflow 배포 (1) | 2023.10.30 |