ว่าด้วยเรื่อง Storage ใน Kubernetes ก็คงว่าด้วยเรื่องปัญหาที่ของข้อมูลที่อยู่ใน container ที่อยู่ใน Pod ที่อยู่เพียงชั่วคราว ถ้า Pod ถูกลบไป ข้อมูลใน container ที่ถูกเขียนโดย application ก็จะหายไปด้วย แต่ในบางครั้งผู้ใช้เองยังต้องการเก็บข้อมูลบางอย่างไว้ ไม่ต้องการให้ถูกลบไปพร้อม ๆ กับ Pod และอีกสถานการณ์ที่น่าสนใจก็คือ ถ้าใน Pod มีหลาย ๆ container และ แต่ละ container ต้องใช้ข้อมูลร่วมกัน ก็เป็นโจทย์ที่ Kubernetes ต้องจัดการให้ได้ ดังนั้นจึงมีการใช้งาน Volume ซึ่งเป็นการนำเอา stroage ชนิดต่าง ๆ อาจจะมาจาก network อาจจะมาจาก storage ของ Cloud Provider อาจจะมาจาก Enterprise Stroage อาจจะมาจาก storage ของ Platform มาใช้งานใน container ดังนั้นเวลา application ใน container เขียนข้อมูลลงไปที่ volume ข้อมูลก็จะถูกเก็บไว้ที่ volume ซึ่งก็หมายถึงการเขียนข้อมูลลงไปที่ storage ที่นำมาใช้งาน และข้อมูลไม่ถูกลบตามสถานะของ Pod ซึ่งโดยปกติ volume ที่ Pod จะนำไปใช้ จะถูกกำหนดให้ อ่านเขียน จาก storage ชนิดใดชนิดหนึ่งเท่านั้น เช่น เราจะสร้าง volume ชื่อว่า myvol1 ให้กำหนดให้อ่านเขียนข้อมูลที่ NFS server nfs.d8k.io ที่ path /data/project_a เพียงที่เดียวเท่านั้น เวลาถูกนำไปใช้งานใน container ก็จะถูก mount ไปที่ path ที่ต้องการ
Projected Volume
บทความนี้จะแนะนำให้รู้จักกับ volume ชนิดหนึ่งที่สามารถ กำหนดให้อ่านเขียนข้อมูลได้มากกว่า 1 แหล่งของข้อมูล ดังนั้นเวลาที่ถูกนำไปใช้งานใน container เวลาถูก mount ไปที่ path ก็จะเห็นว่า ที่ path นั้นสามารถอ่านเขียนข้อมูลจากแหล่งข้อมูลหลายที่ เรียก volume ชนิดนี้ว่า Projected Volume … แต่ว่าการใช้งาน Projected Volume มีข้อมูลจำกัดที่ว่า ไม่ได้รองรับ ชนิดของ storage ทุกชนิด Projected Volume สามารถใช้งานได้กับ stroage ชนิดต่าง ๆ ดังนี้
- secret
- downwardAPI
- configMap
- serviceAccountToken
และข้อจำกัดอีกอย่างหนึ่ง แหล่งข้อมูลที่ถูกรวบรวมมาใช้งานเป็น Projected Volume ต้องมาจาก namespace เดียวกับ Pod
ตัวอย่าง
ในตัวอย่าง จะสร้าง Pod ชื่อว่า prjvol-pod โดยที่มี volume ชื่อว่า appinfo โดยที่ appinfo จะกำหนดแหล่งของข้อมูลไปที่ Secret ชื่อว่า app-secret และ ConfigMap ชื่อว่า app-config จากนั้นก็นำ Volume appinfo ไปทำการ mount ให้กับ path /allinfo
- สร้าง Secret ชื่อว่า app-secret มีข้อมูลอยู่ 2 ชุดคือ username=admin และ password=mypassword และสร้าง ConfigMap ชื่อว่า app-config มีข้อมูล 1 ชุดคือ db_server=db.d8k.lo
- สร้าง Pod ชื่อว่า prjvol-pod โดยที่มี volume ชื่อว่า appinfo โดยที่ appinfo จะกำหนดแหล่งของข้อมูลไปที่ Secret ชื่อว่า app-secret และ ConfigMap ชื่อว่า app-config จากนั้นก็นำ Volume appinfo ไปทำการ mount ให้กับ path /allinfo
```
d8k-a2m2 ~ > kubectl apply -f projectedvol-pod.yaml
pod/prjvol-pod created
```
-
ตรวจไฟล์ที่ /allinfo ใน Pod prjvol-pod
d8k-a2m2 ~ > kubectl exec -it prjvol-pod -- bash -c "ls -la /allinfo/" total 4 drwxrwxrwt 3 root root 160 Jun 2 12:38 . drwxr-xr-x 1 root root 4096 Jun 2 12:38 .. drwxr-xr-x 2 root root 120 Jun 2 12:38 ..2023_06_02_12_38_23.1793077138 lrwxrwxrwx 1 root root 32 Jun 2 12:38 ..data -> ..2023_06_02_12_38_23.1793077138 lrwxrwxrwx 1 root root 20 Jun 2 12:38 app_db_server -> ..data/app_db_server lrwxrwxrwx 1 root root 19 Jun 2 12:38 app_password -> ..data/app_password lrwxrwxrwx 1 root root 19 Jun 2 12:38 app_username -> ..data/app_username lrwxrwxrwx 1 root root 16 Jun 2 12:38 cpu_limit -> ..data/cpu_limit
-
ตรวจดูข้อมูลในไฟล์ต่าง ๆ ด้วยการเรียนคำสั่ง
cat /allinfo/app_username;echo;cat /allinfo/app_db_server;echo;cat /allinfo/cpu_limit;echo;cat /allinfo/app_password;echo;
ใน containerd8k-a2m2 ~ > kubectl exec -it prjvol-pod -- bash -c "cat /allinfo/app_username;echo;cat /allinfo/app_db_server;echo;cat /allinfo/cpu_limit;echo;cat /allinfo/app_password;echo;" admin db.d8k.lo 4 mypassword
พบว่า ใน Pod มีการเรียกใช้งาน volume เพียง volume เดียวแต่ถูกรวบรวมจากแหล่งข้อมูล 3 แหล่งคือ Secret, ConfigMap และ Downward API