Basic Kubernetes Part 4 - สร้าง Volume ให้ Pod ใช้
3 ตอนที่ผ่านมาเราได้เรียนรู้การสร้าง Pod สร้าง Network เข้าไปหา Pod สิ่งที่เรายังขาดคือการ Disk หรือ Volume ที่ให้ตัว Pod (Application) ของเราใช้งานในการเขียนไฟล์ อ่านไฟล์ วางไฟล์ config ตัวอย่างของ Pod (Application) ที่จำเป็นต้องใช้ Database ที่ต้องใช้ Disk หรือ Volume ในการเก็บข้อมูล
ตัวอย่างไฟล์ Configuration ทั้งหมดในตอนนี้อยู่ที่ Link
Persistent Volume : PV
Persistent Volume หรือเรียกสั้นๆว่า PV นั้นคือ Volume ที่เราแจ้งให้ k8s ทราบว่า k8s สามารถเอาไปใช้งานได้ เหมือนกับเราต้องการเอา Hard disk (สมัยนี้อาจจะเป็น SSD หมดแล้ว) มาใช้งาน เราก็ต้องแจ้งกับ OS ว่า Hard disk ของเราต่ออยู่กับช่องไหน
ลองสร้าง Persistent Volume กัน
ทำการสร้าง Folder ชื่อ nginx-volume จากนั้นสร้างไฟล์ index.html ขึ้นมา
1 |
|
สร้างเสร็จแล้วจะได้โครงสร้าง Folder แบบนี้
1 | . |
ออกมาจาก Folder nginx-volume จากนั้นสร้างไฟล์ basic-pv.yml
1 | apiVersion: v1 |
จากนั้นสั่ง apply ตัวไฟล์ basic-pv.yml จากนั้นสั่งด้านล่างเพื่อดูรายละเอียดของ Persistent Volume
1 | kubectl get pv |
อธิบายไฟล์ basic-pv.yml
ในส่วนของ apiVersion , kind , metadata ขอไม่อธิบายนะครับ เพราะเหมือนกับ pod , service , deployment จะขออธิบายในส่วนของ spec
storageClassName
ส่วนนี้เป็นการบอกว่า volume นี้อยู่ในประเภทไหน โดย storageClassName จะถูกเอาไปใช้ใน map เพื่อเอา volume ไปใช้งาน ซึ่งค่านี้สามารถตั้งเป็นอะไรก็ได้ ผมตั้งชื่อมันว่า nginx-volume
capacity
เป็นการบอกว่า Volume นี้มีขนาดเท่าไหร่ จากตัวอย่างของผมประกาศไว้ว่ามีขนาด 2 GB
accessModes
ส่วนนี้เป็นการบอกว่า Volume นี้สามารถเข้าถึงจาก Node ใน k8s cluster ( k8s สามารถทำให้มีหลายๆเครื่องทำงานร่วมกันได้ ดังนั้น 1 cluster สามารถมีหลายเครื่องทำงานร่วมกันได้ โดยเราจะเรียกเครื่องใน k8s cluster ว่า Node ) รูปใดบ้าง โดยตอนนี้มี 3 แบบ
ReadWriteOnce : สามารถอ่านเขียนได้จาก Node เดียวใน k8s cluster
ReadOnlyMany : สามารถอ่านได้อย่างเดียวจากทุก Node ใน k8s cluster
ReadWriteMany : สามารถอ่านเขียนได้จากทุก Node ใน k8s cluster
ตัวอย่างเรา Set เป็น ReadWriteOnce
hostPath
ส่วนนี้เป็นการบอกว่า Volume นี้เป็นแบบใช้ไฟล์บนเครื่อง Node นั้นโดยบอกว่า path บนเครื่องคือ path ไหน โดยในตัวอย่างของผมคือ /root/test-pod/part4/nginx-volume
Persistent Volume Cliam : PVC
ในส่วนของ Persistent Volume นั้นเป็นประกาศให้ k8s ทราบว่ามี Volume พร้อมให้ใช้งาน แต่คงมีปัญหาแน่นอนถ้ามีหลายที่พยายามใช้ Volume เดียวกัน เช่น Volume นี้ถูกใช้งานจาก MYSQL และ MongoDB ดังนั้นเพื่อให้ Volume ถูกเอาไปใช้งานและไม่เกิดแย่งกันจึงต้องมีการประกาศสิ่งที่เรียกว่า Persistent Volume Cliam เพื่อบอกว่า Volume ตรงนี้ชั้นจองไว้นะ
ลองสร้าง Persistent Volume Cliam : PVC
ทำการสร้างไฟล์ basic-pvc.yml
1 | apiVersion: v1 |
จากนั้นสั่ง apply ไฟล์ basic-pvc.yml และสั่งดูรายละเอียดของ Persistent Volume claim
1 | kubectl get pvc |
ลองสังเกตที่วงแดงไว้จะเห็นว่าตัว PVC นี้อยู่ในสถานะ Bound และส่วนตรง Volume มีค่าเป็น nginx-pv ซึ่งสองค่านี้เป็นการบอกว่า PVC ตัวนี้ทำการผูกกับตัว PV แล้ว
หากคุณลองสั่ง Describe ตัว nginx-pv จะเห็นว่ามีการเปลี่ยนไป โดยลองดูภาพด้านล่าง ซึ่งจะเป็นไปในทางเดียวกันคือ nginx-pv ถูก nginx-pvc ทำการเอาไปใช้แล้ว
อธิบายไฟล์ basic-pvc.yml
accessModes
ส่วนนี้เหมือนกับ PV เลย แต่แค่เปลี่ยนจาก PV เป็น PVC ซึ่งตัว PVC จะเอา accessModes นี้ไปหา PV ที่มี accessModes รองรับความต้องการ PVC
storageClassName
ส่วนนี้เป็นการบอกว่า PVC นี้จะใช้ storageClass ไหน
resources
ส่วนนี้เป็นการบอกว่า PVC ต้องการ Resource อะไรบ้าง จากตัวอย่างบอกว่าต้องการ Storage size 2Gi
ลองสร้าง PVC ที่หา PV ไม่ได้
ทำการสร้างไฟล์ unmatch-pvc.yml
1 | apiVersion: v1 |
จากนั้นทำการ apply file และ describe ดูตัว unmatch-pvc
จะเห็นว่าตัว unmatch-pvc นั้นไม่สามารถ Match ได้กับ PV ไหนได้ โดยด้านล่างจะมี message บอกว่าไม่สามารถหา storageClassName wasinee-volume ได้ ซึ่งก็แน่นอนอยู่แล้วเพราะเราไม่ได้สร้าง PV ที่มี storageClassName นี้ขึ้นมา
สร้าง Pod ที่ใช้งาน PVC
สร้างไฟล์ nginx-use-pvc.yml
1 | apiVersion: v1 |
สั่ง apply ไฟล์ nginx-use-pvc.yml จากนั้นลองเปิด browser แล้วไปที่ url : http://<ip เครื่องที่ run k8s>:32010 โดยของผมจะเป็น http://192.168.156.101:32010
จะเห็นว่า Browser แสดงหน้า Html ออกมาเป็นเหมือนไฟล์ index.html ที่เราสร้างในตอนต้น จากนั้นให้เราลองแก้ไฟล์ index.html ของเราเป็นอย่างอื่นดู อย่างของผมเปลี่ยนจาก HELLO WORLD เป็น HELLO WASINEE แล้วไปเปิด Browser ใหม่จะเห็นว่าจะแสดงผลเปลียนไป
จากการทดลองจะเห็นว่าตัว pod nginx ที่เราสร้างนั้นมีการใช้ไฟล์ index.html ที่เรา mount เข้าไปแล้ว ซึ่งเท่ากับว่าเราสามารถ Mount ตัว Volume ให้กับ Pod ได้เรียบร้อยแล้ว
อธิบายไฟล์ nginx-use-pvc.yml
ในส่วนของ service และ pod ที่ใช้ keyword เก่าจะไม่ขอพูดถึงนะครับ จะพูดถึงส่วนใหม่ที่เพิ่มเข้ามา
volumes
1 | spec: |
ตรง volumes นี้จะเป็นการบอกว่าตัว Pod นี้มี Volumes อะไรบ้าง (มีได้หลาย Volume) และ Volume แต่ละตัวนั้นไปเอามาจากไหน จากในตัวอย่างคือมี volume ชื่อ nginx-webpage โดย Volume นี้ไปเอามาจาก persistentVolumeClaim โดยมีชื่อว่า nginx-pvc
VolumeMounts
1 | containers: |
ตรง VolumeMounts ตรงนี้จะเป็นการบอกว่า container นี้จะทำการ Mount volumes อะไรบ้าง (ใส่ได้หลาย mount ) โดยจากตัวอย่างนั้นเราจะบอกว่าเราจะทำการ Mount volume เข้าไปใน container ที่ mountPath : /usr/share/nginx/html (Path นี้คือ Path ที่เอาไว้เอาไฟล์จำพวก web มาใส่เพื่อให้ตัว nginx ทำการแสดงผล) โดย map กับ Volume ของ Pod ที่ชื่อ nginx-webpage ซึ่ง nginx-webpage ไปเอา volume มาจาก pvc ชื่อ nginx-pvc ซึ่ง nginx-pvc นั้นคือ folder nginx-volume ที่เราสร้างกันตอนแรก
ลองลบ PVC กับ PV กัน
เมื่อสร้างแล้วก็ต้องลบได้ ดังนั้นเรามาลบ PVC กับ PV กัน โดยเราลองลบ PV กันก่อนโดยสั่ง
1 | kubectl delete pv nginx-pv |
โดยเมื่อกดสั่งจะเห็นว่ามันค้างไปและเมื่อ get pv มาดูจะพบว่ามันอยู่ในสถานะ Terminating (กำลังปิด) ซึ่งจะค้างอยู่อย่างนั้นไปเรื่อยๆ ซึ่งทำไมล่ะ ก็ง่ายๆครับเพราะ PV นี้มีคนใช้อยู่ ซึ่งนั่นก็คือ PVC : nginx-pvc นั่นเอง ก็เลยค้างอยู่อย่างนั้น
ดังนั้นเราก็ต้องไปลบ nginx-pvc ก่อน
1 | kubectl delete pvc nginx-pvc |
ซึ่งพอเราลบก็จะพบว่ามันค้างและเมื่อกดออกมาและมา get pvc ดูจะพบว่าติดสถานะ Terminating เหมือนกัน ซึ่งก็น่าจะเดากันได้ที่ติดอยู่ก็เพราะมี Pod สัก Pod กำลังใช้งาน pvc อยู่ ซึ่งนั่นก็คือ Pod : nginx-pod ดังนั้นถ้าเราจะลบ PVC ได้ก็ต้องลบ Pod ทิ้งก่อน
1 | kubectl delete -f nginx-use-pvc.yml |
ซึ่งเมื่อเราสั่งลบตัว nginx-pod ทิ้งไปแล้วไป get pv กับ pvc จะพบว่า nginx-pv และ nginx-pvc หายไป
ลองสร้าง Database : MariaDB ผ่าน Kube มาใช้งานกัน
เพื่อทดสอบความเข้าใจและดูว่ามันเอาไปใช้งานจริงยังไง เรามาลองสร้าง Database บน k8s กัน
สร้าง PV กับ PVC กัน
ในขั้นแรกให้สร้าง Folder ขั้นมาสัก Folder เพื่อเอาไว้ใช้เก็บข้อมูลของ database จากนั้นสร้าง PV กับ PVC ขั้นมา ลองทำเองกันดูครับ ของผมที่ทำจะได้แบบข้างล่าง
1 | apiVersion: v1 |
สร้าง MariaDB เพื่อใช้งาน
ขั้นต่อมาคือการทำการสร้างตัว Pod MariaDB ขึ้นมาและสร้าง Service ขึ้นมา ผมแนะนำให้ลองสร้างกันเองดูก่อน ส่วนของผมสร้างได้แบบข้างล่าง โดยผมใช้การสร้าง Pod ผ่าน Deployment (ในการใช้งานจริงเราจะสร้าง Pod ผ่าน Deployment กัน ที่ผมสร้าง Pod ตรงๆเพราะอยากให้เข้าใจง่าย) ในส่วนของการ Mount volume นั้น เรา Mount ที่ Path : /var/lib/mysql ซึ่งเป็น Path ที่ Mariadb ใช้ในการเก็บข้อมูล Database
สุดท้ายคือส่วนของ Service อันนี้ก็คือทำการเปิดช่องทาง Client สามารถติดต่อกับ Port ได้โดยยิงเข้ามาผ่าน IP เครื่อง + Port ที่กำหนดไว้ (ของผม IP : 192.168.156.101 Port : 32110)
1 | apiVersion: apps/v1 |
ลองใช้งานกัน
ให้ลองใช้ตัว SQL Query Browser ต่อเข้า Database ที่พึ่งสร้าง ของผมใช้ตัว dbeaver เพื่อทดสอบว่าสามารถเชื่อมต่อเข้ากับ Database ได้หรือไม่ ซึ่งผมสามารถติดต่อได้ดังภาพ
ลองไปดูที่ Path ที่ Mount volume
ลองไปดูที่ path ที่ Mount volume กันว่ามีไฟล์อะไรโผล่ขึ้นมาไหม ซึ่ง Path ที่ Mount volume ของผมคือ /root/k8s-data/database-volume ซึ่งเมื่อเข้าไปดูก็พบไฟล์มากมายที่เกิดจากตัว MariaDB
เราต้องสร้าง PV เองตลอดเลยไหม
ตัวอย่างที่ผมได้แสดงให้ดูเนี่ยจะเห็นว่าเราต้องสร้าง PV เองเสมอทุกครั้ง แต่ในโลกความเป็นจริงนั้น จะมีสิ่งที่เรียกว่า Dynamic Volume Provisioning คอยหา Volume มา Map กับ PVC ให้โดยอัตโนมัติ (ในการทดลองเราไม่มีเพราะต้อง Config เอง ยุ่งยากมาก) โดยเราแค่สร้างตัว PVC แล้วกำหนด storageClassName ให้ตรงกับที่ Dynamic Volume Provisioning กำหนดให้ พอสร้าง PVC ตัว Dynamic Volume Provisioning จะสร้าง Volume แล้ว Map ให้เอง
ตัวอย่างของ Dynamic Volume Provisioning
เรื่องที่ควรไปอ่านเพิ่ม
เนื่องจากบทความนี้เป็นบทความสอนใช้งานเบื้องต้น ถ้าลงรายละเอียดเยอะจะทำให้ยุ่งยากและคิดว่ามันเป็นเรื่องจากที่จะใช้ ดังนั้นผมจึงอธิบายแค่เรื่องง่ายๆกับทำยังไงให้สร้างสิ่งที่ต้องการและใช้งานได้ ซึ่งแน่นอนว่าในการใช้งานจริงระดับ Production ยังมีเรื่องที่ควรจะต้องเข้าไปอ่านทำความเข้าใจเพิ่ม โดยเรื่องที่แนะนำให้ไปอ่านเพิ่มคือ
Lifecycle of a volume and claim : ส่วนนี้จะพูดถึงสถานะต่างๆของ volume และ cliam ว่ามีอะไรบ้าง ถ้าลบ Cliam แล้วอยากใช้ Volume ต่อต้องทำอย่างไร มีแบบไหนบ้าง เป็นต้น
Dynamic Provisioning : อันนี้พูดถึงเรื่อง Dynamic Provisioning ว่าทำงานอย่างไร
Types of Persistent Volumes : ส่วนนี้เป็นชนิดของ Persistent Volumes ในตัวอย่างที่เราทำกันเราใช้ pv type : hostPart แต่จริงๆแล้วยังมี type อื่นอีกมากมายที่เราสามารถใช้ได้
สรุป
สำหรับตอนนี้เราได้รู้วิธีจะ Mount volume เข้าไปใน Pod ได้ยังไง ได้รู้ว่า Persistent Volume (PV) และ Persistent Volume (PVC) คืออะไร ได้ลองสร้าง Database : MariaDB ขึ้นมาใช้งาน ซึ่งถ้าคุณเข้าใจและได้ลองทำ คุณก็สามารถ Deploy Appplication ขึ้นไปใช้งานบน k8s ได้แล้ว ในตอนต่อไปเราจะมาพูดถึง ConfigMap และ Secret ของ k8s กันว่าคืออะไร