ลองใช้ kubernetes บนเครื่อง localhost ด้วย Minikube
หลังจากได้เข้าใจ conceptโครงสร้างสถาปัตยกรรมของ Kubernetes ไปในบทความที่ผ่านมา ในบทความนี้เราจะมาลองทดลองใช้งานจริงโดยการลง Minikube บนเรื่องของเรากัน
Minikube คือ distro หนึ่งของ Kubernetes ซึ่งเป็น open source คล้ายๆกันกับที่เราใช้ Linux แล้วมีการแตกออกมาเป็น Redhat, Ubuntu, Mint ฯลฯ ซึ่งเจ้าตัว Minikube นี้ก็ตามชื่อเลย มีขนาดกระทัดรัดเพราะทำขึ้นมาเพื่อใช้งานในการทดลองรันบนเครื่อง local ครับ ไม่ควรนำไปใช้งานใน production จริงเนื่องจากมี node เพียงแค่โหนดเดียวเท่านั้น
ติดตั้ง Minikube
ว่าแล้วเราก็มาลองลง Minikube บนเครื่องเรากันเลย แต่ก่อนอื่นต้องแน่ใจว่าบนเครื่องเราได้ Install Docker เรียบร้อยก่อนนะครับ
ให้เราไปที่ เวปไซด์ official ของ Minikube เพื่อเลือกการติดตั้งที่เหมาะกับ local environment ของเรา สำหรับเครื่องผมใช้ Ubuntu ก็จะทำการเลือก options ประมาณรูปข้างล่างครับ
หลังจากนั้นก็รัน script ตามที่ทางเวปแนะนำไว้ได้เลย
1curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
2sudo dpkg -i minikube_latest_amd64.deb
เมื่อติดตั้ง Minikube เรียบร้อยก็ทำการ start Minikube ได้เลย
เท่านี้ก็เรียบร้อยครับ เราก็จะมี Minikube ไว้จำลองการใช้งานบนเครื่องของเราแล้ว :)
สำรวจ architecture ด้วย kubectl
kubectl
เป็น command line interface ที่ช่วยในการติดต่อและส่งคำสั่งไปยัง Kube-Api-Server (อ่าน K8S concept เพื่อทำความเข้าใจเพิ่มเติม) โดยจะแปลงคำสั่งเป็น RESTFul request และนำผลลัพธ์มาแสดงที่หน้าจอ
ติดตั้ง kubectl
ก่อนอื่นให้ทำการติดตั้ง kubectl ตามเวปไซด์ official ของ Kubernetes ก่อนเลยครับ
สำหรับผมใช้ Ubuntu ก็จะทำการติดตั้ง kubectl ด้วยคำสั่งดังนี้
1sudo snap install kubectl --classic
หลังติดตั้งเสร็จก็สามารถ verify version ด้วยคำสั่งข้างล่างได้เลย
สำรวจ architecuture ของ Control Plane
หลังจากติดตั้งเครื่องมือเรียบร้อยเราก็พร้อมที่จะบริหารจัดการ Minikube หรือ Kubernestes ที่อยู่บนเครื่องของเราแล้ว
อันดับแรกเลยให้เราลอง list ดูว่าใน minikube มี namespace อะไรติดตั้งมาด้วยบ้าง
จากผลลัพธ์ เราควรจะเห็น namespace อย่างน้อยสองอัน คือ kube-system
และ default
kube-system จะเป็น namespace ที่ minikube ติดตั้ง control plane ซึ่งเป็นสถาปัตยกรรมหลักของ Kubernetes ส่วน default จะเป็น namespace เปล่าๆที่เราสามารถ deploy application ลงไปได้ (หรือเราจะสร้าง namespace ขึ้นมาเองเพื่อ deploy application ก็ได้)
namespace คือเครื่องมือที่ช่วยจัดกลุ่ม services ของ Kubernetes ซึ่งจะช่วยให้เราจำแนกได้ว่า resources ต่างๆมีที่มาจากไหน
ทีนี้มาลองดูกันว่าใน kube-system
มี pod อะไรรันอยู่บ้าง ใช้คำสั่งข้างล่าง
1kubectl get pod -n kube-system
คำสั่งข้างบนเป็นการขอดู pod ทั้งหมดที่รันอยู่ใน namespace kube-system เราจะเห็นได้ว่ามี component ที่เป็นส่วนประกอบของ Control plane อยู่ในนี้ ตัวอย่างเช่น apiserver
etcd
scheduler
controller-manager
ฯลฯ
Deploy application ขึ้น Minikube
ในขั้นตอนนี้เราก็จะทำการทดลอง application ขึ้น Minikube กันนะครับ โดยผมได้ทำการสร้าง NodeJs application ง่ายๆและ push image ไปที่ Dockerhub เตรียมไว้แล้ว ซึ่งเราจะใช้ app นี้ทำการทดลองในบทความนี้
สร้าง namespace
ก่อนอื่นเลย สร้าง namespace เพื่อที่จะเอาไว้ deploy application ของเราก่อน
1kubectl create namespace minikube-demo
3kubectl get pod -n minikube-demo
สร้าง deployment ของ demo-v1
ในที่นี้เราจะทำการ deploy application แบบ declarative หรือเป็นการเขียน yaml ไฟล์และส่งขึ้นไปยัง k8s ให้เราสร้าง folder เพื่อทำการเก็บไฟล์ของเราก่อน
1mkdir minikube-demo && cd minikube-demo
หลังจากนั้น สร้างไฟล์ชื่อ demo-v1-deployment.yaml
และใส่เนื้อหาข้างล่างลงไป
4 name: demo-v1-deployment
16 - name: demo-v1-container
17 image: ninenote/minikube-demo-node:v1
apiVersion.apps
เป็นการกำหนดว่าเราจะใช้ API spec apps/v1 ของ kube-api-server (สามารถอ้างอิงที่ official document ของ Kubernetes)metadata.name
เพื่อกำหนดชื่อให้ deployment สำหรับอ้างอิงspec.replicas
เป็นการกำหนด replica set ของการ deploy ครั้งนี้ นี้ตัวอย่างจะกำหนดเป็น 2 หมายความว่าถ้ามี pod ตัวใดตัวนึงพังไปก็ยังมีอีกตัวที่เหลือไว้คอยรองรับselector.matchLabels
เป็นการกำหนดว่าใน deployment นี้จะเลือก pod ที่มี lable run: demo-v1-pod
template.metadata.labels
เป็นการกำหนด label ของ pod ที่จะสร้างขึ้น (จะเห็นได้ว่าเรากำหนดให้มี label run: demo-v1-pod
ซึ่งตรงกับ label ของ deployment ที่กำหนดไว้ด้านบนspec.containers.image
เป็นการกำหนดว่าเราจะใช้ image จากไหนมา deploy pod ในที่นี้คือ ninenote/minikube-demo-node:v1 ที่อยู่ใน Dockerhubports.containerPort: 8080
เป็นการกำหนด port ที่จะ expose ออกจาก container ในที่ 8080 คือพอร์ตที่กำหนดไว้ในตัวอย่าง demo application ของเรา
เมื่อ declare ชุดคำสั่งเรียบร้อยแล้ว เราก็สามารถส่งไฟล์นี้เข้า kube-api-server เพื่อ deploy เข้า namespace ที่เราสร้างขึ้นด้วยคำสั่งข้างล่าง
1kubectl apply -f demo-v1-deployment.yaml -n minikube-demo
หลังจาก deploy เสร็จสิ้นก็ให้เราตรวจสอบดูว่า pod เราถูกสร้างขึ้นตามจำนวน replicas ที่เรากำหนดไว้ได้เลย
1kubectl get pod -n minikube-demo
เท่านี้ก็เรียบร้อยครับ เรามี application รันอยู่ใน cluster Minikube ของเราแล้ว
เปิดพอร์ตสู่ภายนอกด้วย Nginx Ingress Controller
ถึงแม้ว่าเราจะมี application run อยู่ใน cluster แล้วก็ตามแต่การที่จะอนุญาตให้โลกภายนอกส่ง request มายัง app ของเราได้เราจะต้องทำการ expose service ก่อน ในที่นี้เราจะใช้ Nginx Ingress Controller ในการบริหารจัดการ traffic ที่เข้ามายัง cluster ของเราครับ
นอกจากใช้ Ingress Controller แล้วยังมีอีกสองวิธีที่ช่วยให้เรารับ traffic จากภายนอกซึ่งก็คือ NodePort
ซึ่งไม่เสถียรเนื่องจาก port สามารถเปลี่ยนแปลงได้ตลอดเวลาหากมีการ deploy ใหม่ หรืออีกวิธีก็คือการใช้ LoadBalancer
ซึ่งก็ไม่ใช่วิธีที่ดีที่สุดอีกเช่นกันเนื่องจากเราต้องคอยสร้าง LoadBalancer ใหม่ทุกครั้งที่มีการ deploy app ใหม่ขึ้นมา
กำหนด service เพื่อเป็นตัวกลางไปยัง pod
เนื่องจาก pod ที่เรา deploy ไปนั้นจะถูกลบหรือสร้างขึ้นใหม่ได้ตลอดเวลา ดังนั้นเราจึงต้องมีตัวกลางคือ service เพื่อช่วยชี้ไปยัง pod ที่ active ล่าสุดอยู่เสมอ
อันดับแรกสร้างไฟล์ชื่อ demo-v1-service.yaml
และใส่เนื้อหาด้านล่างเข้าไป
หลังจากนั้น apply ไฟล์เข้าไปยัง cluster
1kubectl apply -f demo-v1-service.yaml -n minikube-demo
ติดตั้ง Nginx Ingress Controller
ก่อนที่จะเริ่มใช้งาน Nginx Ingress เราต้องทำการติดตั้งไปยัง cluster ของเราก่อนด้วยคำสั่งนี้
1minikube addons enable ingress
หลังจากติดตั้งเรียบร้อยเราจะเห็นได้ว่ามี namespace ชื่อ ingress-nginx
เพิ่มเข้ามาครับ
1kubectl get namespace ingress-nginx
Route traffic มายัง demo-v1-service
ในขั้นตอนนี้เราจะทำการส่ง traffic มายัง demo-v1-service ที่สร้างขึ้นในขั้นตอนที่ผ่านมา สร้างไฟล์ชื่อ ingress.yaml
แล้วใส่เนื้อหาด้านล่างลงไป
1apiVersion: networking.k8s.io/v1
6 nginx.ingress.kubernetes.io/rewrite-target: /
1kubectl apply -f ingress.yaml -n minikube-demo
ตามด้านบนจะเป็นการกำหนดว่าให้ traffic ที่เข้ามายัง cluster ที่ path /v1
forward request ไปยัง service demo-v1-service
เท่านี้ก็เรียบร้อยครับ app เราพร้อมจะรับ traffic จากภายนอกแล้ว
หลังจากนี้ให้เราหาว่า IP address ของเราคืออะไรด้วยคำสั่ง
1kubectl get ingress -n minikube-demo
หลังจากนั้นให้นำ ip ของ ingress ไปเปิดที่ browser ตามนี้ http://<ingress-ip>/v1 ก็จะเห็น app เรารันอยู่ใน browser
เรียบร้อบครับในบทความนี้เราได้เรียนรู้การใช้งาน k8s จริงผ่าน Minikube โดยที่เราทำการ deploy app ไปยัง pod ก่อนแล้วผูก service เข้ากับ pod นั้นๆ สุดท้ายเราก็ทำการ route traffic จากภายนอกผ่าน Nginx Ingress Controller ไม่ยากเลยใช่ไหม
สอบถาม ติชม เสนอแนะ ได้ที่ช่อง comment ด้านล่างเลยครับ