Create external database with PVC for Airflow Kubernetes

Burasakorn Sabyeying
Mils’ Blog
Published in
4 min readJan 3, 2022

Kubernetes series:
1. Setup Spark job and history server on K8s with GCS log
2. Setup Airflow on Kubernetes with remote logging to GCS
3. Create external database with PVC for Airflow Kubernetes

ข้อมูลที่เกิดขึ้นภายใน pod โดย default แล้วจะอยู่ได้ไม่ถาวร (ephemeral) หนึ่งคือเพราะหาก container มีการ crash ขึ้นมา แล้วเกิดขึ้นใหม่ ข้อมูลตรงนี้จะหายไปได้ และสองคือในบางกรณี เราอาจต้องการแชร์ไฟล์ระหว่าง pod อีกด้วย

ดังนั้นปัญหาตรงนี้สามารถแก้ด้วยการใช้ Persistent Volumes เพื่อจะมารับประกันว่า ต่อให้ pod ตุยเย่ไป เราจะมั่นใจได้ว่าข้อมูลนั้นยังจะคงอยู่

โดยใน concept ของ Kubernetes จะ provide อยู่ในรูปแบบของ API ที่เรียกว่า PV และ PVC

  • PV (Persistent Volume): storage ที่บ่งบอกว่าเป็น resource เหมือนที่ pod ต้องอาศัย node เป็น resource และ storage นี้ก็จะสามารถถูก provision ออกมาได้หลายแบบ เป็น NFS, หรือ cloud provider specific storage system ก็ได้
  • PVC (Persistent Volume Claim): ถ้าเปรียบ PV เป็น node, PVC ก็เหมือน pod โดยที่ user สามารถเลือกได้ว่าจะ consume resource นี้ในปริมาณเท่าไร เช่น PV มี 100 GiB ก็จะใช้ PVC ประมาณสัก 10 GiB อะไรแบบนี้

จบในส่วนของ PVC ไป ในขณะเดียวกัน Airflow production guide แนะนำว่า เราควรจะใช้ external database ดังนั้น ดังนั้นภารกิจวันนี้คือเราจะสร้าง database และใช้ PVC ไปพร้อมๆกัน

External database ที่จะใช้ เราสามารถเลือกได้ว่า เราจะใช้ database ที่เป็น

  • Managed service อาทิเช่น Cloud SQL, Cloud Bigtable etc.
  • Do-it-yourself on VM
  • Database ที่รันบน Kubernetes

ในรายละเอียดสามารถอ่านเพิ่มได้ที่ To run or not to run a database on Kubernetes: What to consider | Google Cloud Blog

ในบทความนี้เราจะมาติดตั้ง external database ที่รันบน K8s กัน เราจะ assume ว่าทุกคนมีได้ติดตั้งตัว Airflow จาก values.yaml แล้ว

$ helm upgrade --install airflow apache-airflow/airflow -n airflow-cluster -f values.yaml

เริ่มต้นจากสร้าง postgres ตัวใหม่ โดยเราจะใช้ helm chart จาก bitnami

$ helm repo add bitnami https://charts.bitnami.com/bitnami

ความจริงแล้วเราสามารถ install release ได้เลย แต่เราจะใช้วิธีที่ custom ดังนั้นเราจะไป download file values.yaml

โดยที่จะตั้งชื่อไฟล์นี้ใหม่ว่า db-values.yaml

และเราจะแก้ config ในส่วนของ username/password

global:
..
postgresql:
postgresqlDatabase: ""
postgresqlUsername: "mils"
existingSecret: ""
postgresqlPassword: "thisispassword"
servicePort: ""
replicationPassword: ""

และเราจะ install จากไฟล์ db-values.yaml

$ helm install postgres bitnami/postgresql -n airflow-cluster -f db-values.yaml

ผลที่ได้ เราจะเห็นว่ามี database pod ทั้ง 2 ตัว

step ถัดไป เราจะไปบอกให้ airflow ชี้ไปที่ database ตัวใหม่ที่เราสร้างขึ้นเอง

แต่ก่อนอื่น เราจะไปเอาชื่อ host ของ database ตัวใหม่ก่อน

$ kubectl get service -n airflow-cluster

เก็บชื่อ postgres-postgresql ไว้

ต่อไปในไฟล์ values.yaml ของ airflow

data:
...
# Otherwise pass connection values in
metadataConnection:
user: mils ## <<--- แก้เป็น user ที่เราใส่ใน db-values.yaml
pass: thisispassword ##<<--- แก้เป็น pw ที่เราใส่ใน db-values.yaml
protocol: postgresql
host: postgres-postgresql ##<<--- ใส่เป็นชื่อ service ของ db ตัวใหม่
port: 5432
db: postgres
sslmode: disable

และอีกส่วน แก้เพื่อบอกว่า เราจะไม่ใช้ db ตัว default แล้ว

# Configuration for postgresql subchart
# Not recommended for production
postgresql:
enabled: false. ##<--- ปรับเป็น false
postgresqlPassword: postgres
postgresqlUsername: postgres

แล้วเราก็ upgrade ตัว airflow ตัวนี้

$ helm upgrade --install airflow apache-airflow/airflow -n airflow-cluster -f values.yaml

เพิ่มเติมว่าถ้า airflow เราดูเอ๋อๆ ก็ uninstall และ install ใหม่ได้เลย

และเราก็สามารถให้ airflow ใช้ external database ได้เรียบร้อยแล้ว รวมถึง pod ตัวเก่าก็หายไปแล้วด้วย

มาถึงตรงนี้ เราสามารถเชื่อม Airflow กับ external database ได้แล้ว ซึ่ง db ปัจจุบัน ใช้ PVC ที่ bitnami provide ให้ ใน step ถัดไปจะเป็นการสร้าง custom PVC เอง ซึ่งสามารถ skip ไปสร้าง airflow init db เลยได้

Create custom PVC

ดังนั้นเราจะสร้างไฟล์ pvc.yaml ขึ้นมา โดยจะเซ็ตเอาไว้ที่ 8GiB ก่อน

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
storageClassName: standard
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi

แล้วรันคำสั่ง

$ kubectl apply -f pvc.yaml -n airflow-cluster
data-postgres-postgresql-0 คือ PVC ตัวที่ bitnami ให้มา จะเห็นว่า pod ใช้งานตัวนี้อยู่

เราใช้ program ที่ชื่อ Lens แต่ถ้าหากใครใช้ command line ก็ใช้คำสั่งนี้ดู PVC ได้

$ kubectl get pvc -n airflow-cluster

เราจะเห็นได้ว่ามี PVC ขึ้นมาแล้ว แต่ตอนนี้ pod ยังไม่เชื่อมกับตัวใหม่ จึงต้องกลับมาแก้ใน db-values.yaml

persistence:
enabled: true
existingClaim: "postgres-pvc" <<-- ใส่ชื่อ PVC

หลังแก้ชื่อ PVC แล้ว เราจะ uninstall แล้ว install ใหม่

$ helm uninstall postgres -n airflow-cluster
$ helm install postgres bitnami/postgresql -n airflow-cluster -f db-values.yaml
คราวนี้ pod เราก็ผูกกับ PVC ตัวที่เราสร้างแล้ว

Airflow init DB

เราจะ exec เข้าไปใน container เพื่อรันคำสั่ง init db ขึ้นมา หากเราไม่ทำ พวก default connnection หรือข้อมูลที่จะใช้อื่นๆจะไม่ถูกสร้าง

$ kubectl exec -it airflow-webserver-78c6946fbc-l88xz -n airflow-cluster -- bash
$ airflow db init

แต่คราวนี้ เราจะไม่มี default username/pass มาให้ ดังนั้น เราจะต้องสร้าง user เอง

$ airflow users create --role Admin --username admin --email admin --firstname admin --lastname admin --password admin

เราก็สามารถใช้งาน airflow ได้ปกติแล้ว โดยได้ทำการ setup external database พร้อมๆกับใช้ PVC ได้สำเร็จ

ref:

--

--

Burasakorn Sabyeying
Mils’ Blog

Data engineer at CJ Express. Women Techmakers Ambassador. GDG Cloud Bangkok team. Moved to Mesodiar.com