สัปดาห์นี้เป็นสัปดาห์ที่วุ่นวายอีกสัปดาห์ มีเคส DB2 TableSpace Drop Pending / และ Podman เอ๋อๆครับ เอาหละมาดูหัวข้อที่เรียนของวันนี้กันครับ
เพื่อความไม่ขาดช่วง มาดูของ Week ก่อนได้ครับ The Cloud Camp Week#06 (K8S Part1) | naiwaen@DebuggingSoft
Kubernetes Object
ตัว Object เป็นคำรวมๆที่เอาไว้อธิบาย ส่วนของ K8S (abstract รวบ เพื่อให้จัดกลุ่ม) เพื่อ
- กำหนดจัดการ (How to handle) เช่น replicaSet / namespace เป็นต้น
- อธิบาย (Describe) เช่น Pod Life Cycle / Self Healing / Image pull จาก registry ไหน เป็นต้น
ตัว Kubernetes Object ยังแบ่งมุมมองได้อีก 2 มุม
- Workload (ตามหน้าที่ ภาระ) - สิ่งที่ยุ่งเกี่ยวกับ Traffic + Container เดี๋ยวมีอธิบายหัวข้อต่อไป
- Infra - ส่วน Foundation เช่น
- การสื่อสารระหว่าง App
- Network + Security
- Node + Auto scale >> HPA
- การควบคุม Resource
นอกจากการจัด Object แล้ว ตอน Deploy Container ไปยังสามารถจัดกลุ่มด้วย namespace (แยก network) และ label
YAML File
ตัว K8S เราสามารถอธิบายสภาพของระบบว่ามีลักษณะอย่างไร (Desire State) ประกอบด้วย Kubernetes Object อะไรบ้าง หน้าที่ของ K8S มันจะทำข้อตกลง "record of intent" ตามที่เราระบุไป ตอนนี้ที่เห็นแล้วจะเป็นตัว replicaSet ที่มาช่วยให้ Pod อยู่ตามที่ตกลงไว้
การอธิบายไฟล์ที่กำหนดตัว Desire State จะมี 2 รูปแบบ YAML / JSON ตอนนี้จะอธิบายตัว YAML (key:value + เรื่อง indent) ก่อนว่ามีส่วนประกอบอะไรบ้าง
- apiVersion - บอก Version ของ K8S Object
ถ้า update node ของ K8S ต้อง แล้วมี apiVersion Update / Deprecate อาจจะเกิด Downtime - kind - object ที่ deploy เช่น pod / deployment
- metadata - ข้อมูลของ object ที่จะ deploy
- name ต้อง unique ถ้าทำเป็น replicaSet pattern ชื่อ จะเป็น [name]-[replicaSetKey]-[RunningNo] เช่น nginx-wear22359-ff158
- label
- namespace - spec ความสามารถของ object ตาม kind + apiVersion
สำหรับคำสั่งนอกจาก kubectl apply [-f FILENAME | -k DIRECTORY] มี kubectl create ด้วย
Ref: Kubectl Apply vs. Kubectl Create - What’s the Difference? (spacelift.io)
Workload Object
- ReplicaSet
- เป็นตัว Horizontal Scale แบบนึง แต่เป็น Manual นะ โดยหน้าที่ของมัน ทำยังไงก็ได้ให้มี Pod พร้อมตามที่กำหนดไว้ (ensure desire number of POD)
- Improve Availability - Deployment
- ในภาพผม มันเป็น docker compose ที่รวมไว้ ท้ายที่สุดแล้วตัว Application มีอะไรบ้าง มี lifecycle ยังไง
- ตอนนี้มีตัว ReplicaSet มาช่วยอยู่ โดยควบคุมจากตัว Deployment Strategy มีจดในหัวข้อถัดไป - StatefulSet
- คุมงานต้องเป็น Stateful มีลำดับขั้นตอน เช่น db / redis / queue / nosql
- ปกติจะได้ Fix IP
Note มันจะมี DB อีกแบบที่ไม่ใช้ Stateful เรียกว่า distribute database - DaemonSet
- ตัวที่ช่วยทำให้มั่นใจได้ว่า เมื่อมี node ใหม่ขึ้นมา รวมถึงตัว controlpane จะต้องมี Pod ที่จำเป็นขึ้นมาพร้อมใช้งานเสมอ ตามที่กำหนด
- งานที่ใช้งานหลักๆจะเป็นพวก monitor logging เช่น ถ้ามีขึ้น node ใหม่ ให้ขึ้น Pod ของ node-exporter ขึ้นมาด้วยเสมอ - Job
- ทำงานพวก batch (run one shot script) แล้วจบ เบื้องหลังสร้าง temporary pod ทำงาน เช่น Curl รวมถึงมี machanism การทำ Flow Retry / ทำซ้ำ - CronJob
- Job ที่ตั้งเวลาได้ - Pod
- เล็กสุด ปกติ 1 Container / Pod
- ถ้าเอาหลาย Container ทำเป็น Multiple Container ได้ แต่ Shared IP ปกติ 3-4 Pattern
=> Sidecar Pattern - เอามาจัด Log Format
=> Adapter
=> Ambassador
- Init Container
ตอนนี้ผมเข้าใจว่า StatefulSet / DaemonSet / Job / CronJob มัน คือ Deployment ที่มี Specific Purpose Deployment
ตัวอื่นๆ เผื่อมีในสัปดาห์ถัดไป What Are Objects Used for in Kubernetes? 11 Types of Objects Explained. (kodekloud.com)
Infra Object
- Configmap - เก็บข้อมูลเล็กๆ
- SecretMap - Configmap Encrypt Base64
- Service - ให้คุยกันโดยใช้ dns name ได้
- Ingress - เข้าจขากภายนอก
- Endpoint - Proof ว่า Service เชื่อมต่อกับ IP ได้ - CoreDNS + KubeProxy
Interacting with Kubernetes
Recap คำสั่งต่างที่ควรรู้ว่าจริงๆ มันมีอะไรลึกกว่านั้น
- kubectl --help
- kubectl api-resources : บอก Resource ที่ใช้งานงานได้บน K8S ที่เราติดตั้ง
- apiVersion
- kind
- namespace T = ใช้ได้ตามกำหนด / F = ClusterWide
- สร้าง resource เองก็ได้นะ - kubectl explain pod : man ใน linux อธิบาย command ได้ โดยเริ่มต้นจาก apiVersion / kind / metadata / spec / status ถ้าอยากได้อะไรเพิ่ม . ต่อท้ายไปเรื่อยๆ ตามรูปครับ
ปล. ดูในเว็บได้เหมือนกัน Kubernetes API | Kubernetes
นอกจาก kubectl มี Tools อื่นมาช่วยด้วย
- Open Source
- kubernetes/dashboard: General-purpose web UI for Kubernetes clusters (github.com)
- derailed/k9s: 🐶 Kubernetes CLI To Manage Your Clusters In Style! (github.com) //อันนี้แว๊บปแรกนึกถึง db2top
- vmware-archive/octant: Highly extensible platform for developers to better understand the complexity of Kubernetes clusters. (github.com) ไม่พัฒนาต่อแล้ว - Commercial
- Lens | The Kubernetes IDE (k8slens.dev)
- Kubernetic - The Kubernetes Desktop Client
พอเรามี Declarative File เยอะๆ พวก pod / deployment + Specific Purpose Deployment / service สามารถทำเป็นทำ Charts เป็น Package + Template โดยใช้ Helm จัดการ นอกจากนี้มันมีคนอื่นทำไว้ และแชร์ ไว้ใน Artifact Hub โดยเราสามารถใช้ตัว Helm ดึงออกมาใช้งานได้
Deployment Indepth
ไม่แน่ใจเหมือนกันว่าสัปดาห์หน้าจะลงรายละเอียด เพิ่มไหมนะ เพราะ Blog ตอนก่อนหน้ามีอธิบายไว้ระดับนึงแล้วครับ
- Intro มาจาก Week ก่อน
คำนิยามของ Infra ของเรา ว่าจะต้องมีอะไร (desired state) จะทำแบบ Imperative ใช้ command / declarative YAML คล้ายๆกับ docker compose file โดยหลักๆ มาคุมการทำงานของ pods และ ReplicaSet
ReplicaSet = ตัวควบคุมจำนวน pods ให้พร้อมใช้งาน ตามที่กำหนดใน Deployment หรือจะมองเป็น Environment
- เก็บได้ 10 revision ถ้ามีปัญหาเกิดขึ้น Rollback ได้ ปกติจะใช้ 2 - 3 revision
Strategy (spec.strategy.type)
- RollingUpdate - ทยอยสร้าง และลบ pods ตามเงื่อนไข ช่วยเรื่อง Zero Downtime ค่อยๆขยับที่ละ pod แล้วจึง Switch Traffic ของให้ User เข้ามา
- maxSurge: จำนวน pod ที่ถูก create ระหว่างการ update
//The number of pods that can be created above the desired amount of pods during an update
- maxUnavailable: จำนวนของ Pod ที่ใช้งานไม่ได้ (ถูก terminate) ระหว่างการ Update
//The number of pods that can be unavailable during the update process
จริงๆ 2 param นี้ ถ้ากำหนดค่าต่างกัน น่าจะทำได้หลายแบบ Blue/Green , Canary เป็นต้น - Recreate - ลบ pods ให้หมด แล้วสร้างใหม่
- YAML
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: euraka name: euraka spec: replicas: 2 revisionHistoryLimit: 3 #<< MAX 10 selector: matchLabels: app: euraka strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 2 #template = กำหนด spec ของ pod เอาจาก doc ของ pod มาใส่ได้เลย template: metadata: creationTimestamp: null labels: app: euraka spec: containers: - image: springcloud/euraka name: euraka resources: {} ports: - containerPort: 80
- Deployment Strategy Example
ขยายความจากที่ Intro ตอนต้น Strategy
Rolling Update ทยอยขึ้นที่ Pod ตามค่า maxSurge / maxUnavailable กำหนดได้แบบ % ที่ >=0 และจำนวนเต็ม >= 0 ตัวอย่าง เช่น
- maxSurge 25%
> ถ้ามี 5 Pod จะมี ยอมให้ Deploy ได้ทีละ 2 Pod (จริงๆได้ 1.25 แค่เศษปัดชึ้น) - maxUnavailable 25%
> ถ้ามี 5 Pod จะมี ยอมให้ Terminate ได้ทีละ 1 Pod (จริงๆได้ 1.25 แค่เศษปัดลง)
> best practice = 0 ไม่ให้ Terminate ลด Downtime
ขึ้นให้ครบ แล้ว switch traffic
maxSurge = ต้องดู Resource ของ Server ด้วยนะ ถ้ามี 1000 Pod กำหนด maxSurge 25% แสดงว่า มันจะสร้างอีก 250 ตัว ตัว Server มี Resource รองรับ Pod 1,250 ตัว
maxSurge / maxUnavailable มีค่า default ที่ 25%
Recreate
- มันเป็น Rolling ที่ maxSurge=100% / maxUnavailable=100%
- พอย้ายครบ Replica จะทำให้เกิดการ Keep Revision (อารมณ์ Blue/Green)
- ใช้กับพวก Stateful Set
เหมือนมีหลาย Pattern เลย 8 Kubernetes Deployment Strategies: Roll Out Like the Pros - Spot.io
- Deployment revisionHistoryLimit
- เป็น History ของ replicaSet โดยจะ Keep Revision เมื่อย้าย Pod ครบทุกตัวใน replicaSet
- เก็บได้สูงสุด 10 ตัว แต่ปกติ จะใช้ 3 revision หรือไม่ใช่เลยไปทำ GitOps แทน
- มี revision เยอะๆไม่ได้กินพื้นที่เยอะ มันเก็บ Config และ Restore กลับตามที่เราสั่ง ถ้าสั่งแล้ว มันจะดึง image จาก cache ใน k8s ถ้าไม่มีไปใช้ internet ไปดึงจาก registry
- Command
- Create Deployment
kubectl create deployment euraka --image=springcloud/euraka --dry-run=client -o yaml > euraka.yaml #List all files from current directory in your terminal: ls cat euraka.yaml
- Scale Replica จริงๆเข้าไปแก้ไฟล์ yaml ตรงๆได้
kubectl scale deployment euraka--replicas 2 #get the YAML (Server Side) of this deployment kubectl get deployment euraka -o yaml > euraka.yaml
- Set New Image Version
kubectl set image deployments euraka euraka=netflixoss/eureka:1.3.1
- Roll Out New Version
kubectl rollout status deployment euraka
Pod LifeCycle
Ref: K8S Pod Life Cycle (github.com)
Labels and Selectors
Labels ที่จัดกลุ่ม K8S Object โดยจะกำหนดไว้ในส่วน metadata ในรูปแบบ key-value pairs โดยเอาไปใช้ในการทำ Grouping หรือ อธิบายความหมาย (อารมณ์เหมือน Tags ของ Azure) ให้
- คน - monitor / ทำ Report ดู Cost
- K8S Object อื่นๆ Search เช่น ตัว replicaSet / deamonSet
ดังนั้นกำหนดชื่อให้สื่อความหมาย
นอกจากนี้ ยังมีตัว annotation ปกติจะใช้ส่วนของ ingress
Selector เอาไว้ใช้ Filter ตัว K8S Object
- command
#================================================== #Add Label with command kubectl run nginx --image=nginx --labels app=backend #================================================== #Change kubectl label pods nginx2 app=v2 --overwrite kubectl get pods --show-labels #================================================== #Remove kubectl label pods nginx1 nginx2 nginx3 app- #or kubectl label pods nginx{1..3} app- #or kubectl label pods -lapp app- #================================================== #Use kubectl get pods to get the pod with label app=backend : #Filter by Key kubectl get pods -l app #Filter by Key&Value kubectl get pods -l app=v2 #or kubectl get pods -l 'app in (v2)' #or kubectl get pods --selector=app=v2 #================================================== kubectl get pods --show-labels #Custom Column Name kubectl get pods -L app #or kubectl get pods --label-columns=app
Label แปะ Resource อื่นๆได้ด้วยนะ มันใช้ได้หมด เป็น metadata เท่านั้น
kubectl label deployments nginx-deployment project=demo --overwrite -n test-talos kubectl get deployments.apps --show-labels -n test-talos NAME READY UP-TO-DATE AVAILABLE AGE LABELS nginx-deployment 2/2 2 2 13d app=v2,project=demo
- ใน YAML อย่างในตัว Deployment จะมีตัว matchLabels เพื่อให้ตัว replicaSet มาใช้การจับ pod ที่สนใจ
selector: matchLabels: app: euraka
Labels vs Namespace
- ไม่คล้ายกัน เพราะตัว Namespace จะใช้แยกวง Network ด้วยส่วนตัว Label จัดกลุ่มได้ละเอียดกว่า เช่น แบ่งย่อยภายใน namespace และเพิ่มมุมมองการ Filter ได้ดีกว่า
Namespace = VPC / VNET
Labels = Tags
Service
Service = Software Defined Load Balance โดยที่จะ redirect traffic จาก selector จาก label หัวข้อตะกี้ โดย group pod ออกมาเป็น 1 endpoint เช่น มี microservice cart อยู่ 5 pod ตัว service จับกลุ่ม 5 pod มาเป็น 1 endpoint ชื่อ cart (service map ip / name ให้)
Service Type
- Cluster IP (Default)
- no external access
- mapping name + IP
headless
- expose ip ของ pod ออกไป ส่วนมาใช้กับ stateful ที่ต้องการ fixed ip
- nodePort เปิด port ของเครื่อง Node / VM จริงๆ แต่ไม่ได้เปิด Firewall ให้
- เปิดให้ External Service เข้าถึง Resource โดยถ้าไม่กำหนด port มันจะเป็นการ Random 30000-32767 มั้ง
- กำหนดเองในส่วน service.port.nodePorts //Lock Range ไว้สะดวกในการ Manage
- ส่วนมากใช้กับตัว Monitor Tools / DaemonSet และ Protocol อื่นๆ เช่น SRV
- security leak ถ้าคุมไม่ดี - loadBalancer
- ต่างกับ cluster IP ตรงที่มันจะ ontop nodePort และเปิดตัว Public IP - externalName
- เอาไว้ map external resource เช่น Database / 3rd Party API เป็น config กลางให้ทุก pod รู้จักได้ ลด Effort เวลา external resource เปลี่ยนชื่อ เช่น
external name อารมณ์ map2 ชั้น - เดิม app ต่อ db dns investment.abc - ใหม่ app ต่อ db inv.db external name service จะmap inv.db = investment.abc
apiVersion: v1 kind: Service metadata: name: external-google-access namespace: web spec: type: ExternalName externalName: google.com
curl external-google-access
Ref: Service | Kubernetes
Ingress
Forward request จาก domain มายัง service
ยังมีอีกตัว Ingress Controller != Ingress
- จับ kind ingress แล้วสร้าง LB Layer 7 ขึ้นมา เดี๋ยวต้องลองไปเล่น
- grpc เหมือนจะ Layer 7 ได้แล้ว
K8S Object หลายตัวควรแยกไฟล์นะ เดี๋ยวงง
Data Inter Change Concept
สำหรับวันเสาร์ มี workshop ให้ลองทำ 2 อัน
- Deployment + replica ได้เจอเคสแปลกๆเยอะครับ 555 แบบ Node เต็ม ตอนแรกลอง 12 replica ไม่ได้ ลด 8 ... 5 อย่างน้อยได้เห็น State จริงๆ อย่าง ContainerStatusUnknow ลองในคอมตัวเองไม่น่าจะเจอ
- อีกอันได้ลองเยอะเลย Ingress > Service > Deployment ผมได้ลอง 2 แบบ
- แบบแรก(V1) ไปปรับทาง App ให้ Controller รับหลาย path
- แบบสอง(V2) แยก App ออกมา มองว่าเป็น Microservice มี Path เดียว แต่แลกมาด้วย Service / Deployment กระจายออกมา
Reference
- Objects In Kubernetes | Kubernetes
- Deployments | Kubernetes
- Kubernetes Pod Lifecycle Explained For Beginners (devopscube.com)
- Kubernetes Rolling Update Configuration (bluematador.com) >> ดี
- Kubernetes Master Components: Etcd, API Server, Controller Manager, an (jorgeacetozi.com)
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.