Create external database with PVC for Airflow Kubernetes
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 productionpostgresql:
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
เราใช้ 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
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:
- https://kubernetes.io/docs/concepts/storage/volumes/
- https://kubernetes.io/docs/concepts/storage/persistent-volumes/
- https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#database
- https://stackoverflow.com/a/64276435/13113697
- https://cloud.google.com/blog/products/databases/to-run-or-not-to-run-a-database-on-kubernetes-what-to-consider