ลองใช้ 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 ประมาณรูปข้างล่างครับ

เลือก option เพื่อดาวโหลดและติดตั้ง Minikube

หลังจากนั้นก็รัน script ตามที่ทางเวปแนะนำไว้ได้เลย

1
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
2
sudo dpkg -i minikube_latest_amd64.deb

เมื่อติดตั้ง Minikube เรียบร้อยก็ทำการ start Minikube ได้เลย

1
minikube start

เท่านี้ก็เรียบร้อยครับ เราก็จะมี Minikube ไว้จำลองการใช้งานบนเครื่องของเราแล้ว :)

สำรวจ architecture ด้วย kubectl

kubectl เป็น command line interface ที่ช่วยในการติดต่อและส่งคำสั่งไปยัง Kube-Api-Server (อ่าน K8S concept เพื่อทำความเข้าใจเพิ่มเติม) โดยจะแปลงคำสั่งเป็น RESTFul request และนำผลลัพธ์มาแสดงที่หน้าจอ

ติดตั้ง kubectl

ก่อนอื่นให้ทำการติดตั้ง kubectl ตามเวปไซด์ official ของ Kubernetes ก่อนเลยครับ
สำหรับผมใช้ Ubuntu ก็จะทำการติดตั้ง kubectl ด้วยคำสั่งดังนี้

1
sudo snap install kubectl --classic

หลังติดตั้งเสร็จก็สามารถ verify version ด้วยคำสั่งข้างล่างได้เลย

1
kubectl --version

สำรวจ architecuture ของ Control Plane

หลังจากติดตั้งเครื่องมือเรียบร้อยเราก็พร้อมที่จะบริหารจัดการ Minikube หรือ Kubernestes ที่อยู่บนเครื่องของเราแล้ว
อันดับแรกเลยให้เราลอง list ดูว่าใน minikube มี namespace อะไรติดตั้งมาด้วยบ้าง

1
kubectl get namespaces

จากผลลัพธ์ เราควรจะเห็น 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 อะไรรันอยู่บ้าง ใช้คำสั่งข้างล่าง

1
kubectl get pod -n kube-system
components ต่างๆของ minikube master node

คำสั่งข้างบนเป็นการขอดู 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 ของเราก่อน

1
kubectl create namespace minikube-demo # เป็นการส่งคำสั่งเพื่อสร้าง namespace ที่ชื่อว่า minikube-demo
2
kubectl get namespaces # จะเห็นได้ว่าตอนนี้มี namespace ใหม่ที่เราสร้างขึ้นมาอยู่ใน minikube แล้ว
3
kubectl get pod -n minikube-demo # เป็นคำสั่งเพื่อดู pod ทั้งหมดใน namespace minikube-demo (ซึ่งตอนนี้ยังไม่มี pod ใดๆ)

สร้าง deployment ของ demo-v1

ในที่นี้เราจะทำการ deploy application แบบ declarative หรือเป็นการเขียน yaml ไฟล์และส่งขึ้นไปยัง k8s ให้เราสร้าง folder เพื่อทำการเก็บไฟล์ของเราก่อน

1
mkdir minikube-demo && cd minikube-demo

หลังจากนั้น สร้างไฟล์ชื่อ demo-v1-deployment.yaml และใส่เนื้อหาข้างล่างลงไป

1
apiVersion: apps/v1
2
kind: Deployment
3
metadata:
4
name: demo-v1-deployment
5
spec:
6
replicas: 2
7
selector:
8
matchLabels:
9
run: demo-v1-pod
10
template:
11
metadata:
12
labels:
13
run: demo-v1-pod
14
spec:
15
containers:
16
- name: demo-v1-container
17
image: ninenote/minikube-demo-node:v1
18
ports:
19
- containerPort: 8080
  • 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 ที่อยู่ใน Dockerhub
  • ports.containerPort: 8080 เป็นการกำหนด port ที่จะ expose ออกจาก container ในที่ 8080 คือพอร์ตที่กำหนดไว้ในตัวอย่าง demo application ของเรา

เมื่อ declare ชุดคำสั่งเรียบร้อยแล้ว เราก็สามารถส่งไฟล์นี้เข้า kube-api-server เพื่อ deploy เข้า namespace ที่เราสร้างขึ้นด้วยคำสั่งข้างล่าง

1
kubectl apply -f demo-v1-deployment.yaml -n minikube-demo

หลังจาก deploy เสร็จสิ้นก็ให้เราตรวจสอบดูว่า pod เราถูกสร้างขึ้นตามจำนวน replicas ที่เรากำหนดไว้ได้เลย

1
kubectl get pod -n minikube-demo
application รันอยู่ใน minikube

เท่านี้ก็เรียบร้อยครับ เรามี 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 และใส่เนื้อหาด้านล่างเข้าไป

1
apiVersion: v1
2
kind: Service
3
metadata:
4
name: demo-v1-service
5
labels:
6
run: demo-v1-service
7
spec:
8
ports:
9
- port: 8080
10
protocol: TCP
11
targetPort: 8080
12
selector:
13
run: demo-v1-pod # service จะคอยมองหา pod ที่มี label "run: demo-v1-pod"

หลังจากนั้น apply ไฟล์เข้าไปยัง cluster

1
kubectl apply -f demo-v1-service.yaml -n minikube-demo

ติดตั้ง Nginx Ingress Controller

ก่อนที่จะเริ่มใช้งาน Nginx Ingress เราต้องทำการติดตั้งไปยัง cluster ของเราก่อนด้วยคำสั่งนี้

1
minikube addons enable ingress

หลังจากติดตั้งเรียบร้อยเราจะเห็นได้ว่ามี namespace ชื่อ ingress-nginx เพิ่มเข้ามาครับ

1
kubectl get namespace ingress-nginx

Route traffic มายัง demo-v1-service

ในขั้นตอนนี้เราจะทำการส่ง traffic มายัง demo-v1-service ที่สร้างขึ้นในขั้นตอนที่ผ่านมา สร้างไฟล์ชื่อ ingress.yaml แล้วใส่เนื้อหาด้านล่างลงไป

1
apiVersion: networking.k8s.io/v1
2
kind: Ingress
3
metadata:
4
name: demo-ingress
5
annotations:
6
nginx.ingress.kubernetes.io/rewrite-target: /
7
spec:
8
rules:
9
- http:
10
paths:
11
- path: /v1
12
pathType: Prefix
13
backend:
14
service:
15
name: demo-v1-service
16
port:
17
number: 8080
1
kubectl apply -f ingress.yaml -n minikube-demo

ตามด้านบนจะเป็นการกำหนดว่าให้ traffic ที่เข้ามายัง cluster ที่ path /v1 forward request ไปยัง service demo-v1-service เท่านี้ก็เรียบร้อยครับ app เราพร้อมจะรับ traffic จากภายนอกแล้ว หลังจากนี้ให้เราหาว่า IP address ของเราคืออะไรด้วยคำสั่ง

1
kubectl get ingress -n minikube-demo
Ingress ip address

หลังจากนั้นให้นำ ip ของ ingress ไปเปิดที่ browser ตามนี้ http://<ingress-ip>/v1 ก็จะเห็น app เรารันอยู่ใน browser

ตัวอย่าง application รันใน minikube

เรียบร้อบครับในบทความนี้เราได้เรียนรู้การใช้งาน k8s จริงผ่าน Minikube โดยที่เราทำการ deploy app ไปยัง pod ก่อนแล้วผูก service เข้ากับ pod นั้นๆ สุดท้ายเราก็ทำการ route traffic จากภายนอกผ่าน Nginx Ingress Controller ไม่ยากเลยใช่ไหม

สอบถาม ติชม เสนอแนะ ได้ที่ช่อง comment ด้านล่างเลยครับ

Copyright © 2024. All rights reserved - Ninenote.net