LFS258 [1/15]: Basics of Kubernetes
Tags: lfs258, kubernetes, docker
Published: 2020-01-15 07:59:09

# Introduction

**Kubernetes** เป็นชื่อของ application ที่ทำหน้าที่ในการ ควบคุม, ดูแล และ จัดการ containers

ถ้าใครอยากรู้ว่า containers คืออะไร ? ผมเขียนรายละเอียดไว้ในบทความเรื่อง [Containers Fundamentals](https://dev.to/peepeepopapapeepeepo/lfs253-containers-fundamentals-1595) เชิญเข้าไปอ่านกันได้ครับ 🤗

แต่ถ้าจะให้อธิบายคร่าวๆ containers ก็คือ application ที่ถูก pack ใส่กล่องพร้อมด้วย dependencies ของมัน ทำให้มันสามารถ run ได้ทุกที่ที่มี container runtime

โดย **Kubernetes** มาจากภาษากรีก κυβερνήτης แปลว่า pilot of the ship, helmsman หรือ captain หรือแปลเป็นไทยก็คือ **กัปตันเรือ** 

|![Captain](https://thepracticaldev.s3.amazonaws.com/i/8lin4gmpo7efc47ebqjy.jpg)|
|:--:|
|<center><sup><sub>Source: [framepool.com](http://footage.framepool.com/es/shot/781596544-rueda-del-timon-gobernalle-nautica-puente-barco)</sub></sup></center>|

ทำไมน่ะเหรอ... ลองนึกภาพ กัปตันเรือ กัปตันจะคอยถือพวกมาลัยเพื่ออควบคุมทิศทางของเรือ พร้อมกันนั้นก็คอยมองหน้าปัดที่แสดงสถานะต่างๆ ของเรือ ถ้าพบอะไรผิดปกติก็จะสั่งลูกเรือให้ไปจัดการ เมื่อจัดการเรียบร้อยลูกเรือก็จะรายงานกลับมา แล้วกัปตันก็ตรวจสอบสถานะต่างๆ ของเรือต่อไป

เช่นเดียวกับการทำงานของ Kubernetes ที่คอยตรวจสอบสถานะของ container และคอยทำให้มันอยู่ในสภาพที่ปกติเสมอ บางคนกล่าวว่า `"Kubernetes is the pilot of a ship of containers"`

> ด้วยความ Kubenetes เขียนก็ยาว ออกเสียงก็ยาก 
> บางครั้งเลยถูกย่อๆ เป็น **`k8s`** โดย 
> - `k` คือ อักษรตัวแรก
> - `s` คืออักษรตัวตัวสุดท้าย
> - `8` คือ จำนวนตัวอักษณระหว่าง `k` และ `s`

> นอกจากนั้นมันยังมีชื่อเล่นด้วยนะ นั่นคือ **`Kate's`** มาจากการออกเสียง kubernetes เร็วๆ ออกยังไง... ไปลองดูเอง

เราเรียกการควบคุมดูแลของ Kubenetes ว่า "orchestration" 

ลองนึกภาพวง orchestra ที่มี conductor เป็นคนค่อยควบคุมวงดนตรี ว่าตอนนี้ต้องเล่นอย่างไร ใครเน้น ใครผ่อน ต้องเล่นแบบเร้าใจ หรือว่าเนิบๆ เพื่อให้สอดคล้องเข้ากันของแต่ละเครื่องดนตรี (harmony) ในเพลง

|![Orchestra](https://thepracticaldev.s3.amazonaws.com/i/qy06u1b2so0ojc8nq2g1.jpg)|
|:--:|
|<center><sup><sub>Source: [seenandheard-international.com](https://seenandheard-international.com/2019/10/the-cleveland-orchestra-shows-its-mettle-in-mahlers-fifth-at-carnegie-hall/)</sub></sup></center>|


คำว่า "orchestration" ในความหมายของ Kubernetes เน้นไปที่ความสอดคล้องเข้ากัน (harmony) เช่นกัน แต่จะเป็นเรื่องของการ deploy resources ต่างๆ และการ clean up resources ที่ไม่ได้ถูกใช้งานแล้ว แบบอัตโนมัติ

การออกแบบ application ที่ run ใน kubernetes และตัว kubernertes เอง เน้นไปที่ 2 คำคือ
- **Decoupling** คือ ทุกๆ อย่างถูกออกแบบให้ ไม่จำเป็นต้องผูกติดอะไรเป็นพิเศษ
- **Transient** คือ ทุกๆ อย่างถูกออกแบบให้ สามารถเกิดและดับได้ และ สามารถทดแทนด้วยของที่เหมือนกันได้

> Decoupling อาจใกล้เคียงกับ "อุปาทาน" ส่วน Transient น่าจะใกล้เคียงกับคำว่า "อนิจจัง"

ผลที่ได้คือ application ที่มีลักษณะเป็น module ที่ run ได้ด้วยตัวตัวเอง นอกจากนั้นยังสามารถเพิ่มหรือลดความสามารถ ด้วยการเพิ่มหรือลด module เข้าไป หรือ เปลี่ยนเป็นของใหม่ที่เหมาะสมกว่าในขณะนั้นได้

---

# What's Kubernetes ?

> kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications<br/><sup><sub>Source: [kubernetes.io](https://kubernetes.io/)</sub></sup>

ทำหน้าที่ของ **kubernetes**
- จัดการ container ที่สามารถเชื่อมต่อไปได้ยังหลายๆ Host
- เพิ่มหรือลด (scale) containers เพื่อให้เหมาะสมกับ traffic
- จัดการ การ deploy application แบบไม่มี downtime
- ทำ service discovery ในหลากหลายมุมมอง ซึ่งบางครั้งยากเกินที่จะทำเองกับมือ

หัวใจสำคัญของ kubernetes คือ API ที่ open และ มีความยืดหยุ่น ที่เพิ่มเติมความสามารถเข้าไปได้ ทำให้ผู้ใช้ควบคุมและสั่งงานมันได้ตามความต้องการ

จุดเด่นของ Kubernetes คือ มันถูกสร้างมาจากประสบการณ์กว่า 15 ปีของ Google ในชื่อ project **"[Borg](https://www.gcppodcast.com/post/episode-46-borg-and-k8s-with-john-wilkes/)"**

---

# Components of Kubernetes

ในการใช้งาน Kubernetes ต้องมีการปรับตัวเล็กน้อย ทั้งในส่วนของการพัฒนา application และ การดูแลระบบ

ยกตัวอย่าง เช่น

สมัยก่อน เรา run application ใหญ่ๆ (monolithic application) ใน 1 เครื่อง แล้วเพิ่ม thread เพื่อให้รองรับ traffic ได้มากขึ้น จากนั้นก็เพิ่ม resource เช่น memory จนเราไม่เพิ่มอะไรต่อได้แล้ว เราก็ต้องย้ายไปเครื่องใหม่ที่ใหญ่กว่า

แต่ใน Kubernetes เราจะแบ่ง application ออกเป็น application เล็กๆ ทำงานแค่หน้าที่เดียว (microservice application) แล้วจับยัดใส่ containers ถ้า traffic เพิ่ม ก็เพิ่ม container เฉพาะในส่วนงานที่มีความต้องการใช้งานสูง ถ้ายังไม่ไหว เราก็เพิ่ม servers เข้าไปใน cluster เพื่อให้ Kubernetes เพิ่ม Containers ต่อไป

ในการทำงานแบบ microservice application แน่นอน การเชื่อมต่อระหว่าง container เป็นสิ่งที่จำเป็น Kubernetes ทำให้มันเกิดขึ้นได้ด้วย concept ของ **service** และ **API calls**

**service** จะเป็นตัวเชื่อมโยง container เข้าด้วยกัน มองคล้ายๆ load balancer ที่คอยแจก traffic ไปยัง containers ในกลุ่มงานนั้นๆ พร้อมทั้ง monitor การเพิ่มลดของ containers เพื่อให้ balance งาน ทำได้ถูกต้อง แม่นยำ

ส่วน **API calls** คือการที่ container ไม่ต้องผูกติดกันแบบตายตัว แต่เรียกใช้งานกันผ่านการ call API ระหว่างกัน ทำให้การเพิ่มลดของ containers เป็นไปได้ไม่ยาก

Configuration ของ Kubernetes เก็บเป็นรูปแบบ JSON แต่เรามักนิยมเขียนสั่งมันด้วย รูปแบบ YAML เพราะเข้าใจง่ายกว่า

Kubernetes ถูกเขียนด้วยภาษา Go

---

# Challenges

จาก motto ของ Docker คือ "Build, ship and run" 

container ช่วยให้การทำงานต่างๆ ง่ายขึ้น โดยเฉพาะ Docker เอง ที่ทำให้การ build application เป็น container ไม่ใช่เรื่อยยาก และการ share image ที่เราทำเสร็จแล้ว ผ่าน Docker Hub ก็ทำใช้ชีวิตของเราดีขึ้น

หากแต่ยังมีความท้าทายที่เราต้องพบเจอ หากเราจะมาใช้ Kubernetes อีก เช่น
- การดูแล และจัดการ container ไม่ว่าจะเป็นในแง่ของการ scale หรือ distributed architecture ตามหลัก microservice 
- การทำ CI/CD Pipeline, test และ verify image
- การ launch containers พร้อมทั้งดูแลในการทำ self-healing, การ rolling update, การ rollback ถ้ามีอะไรผิดพลาด รวมถึงการจัดการ resources ต่างๆ 
- networking และ storage ที่มีความยืดหยุ่น, scalable และ ใช้งานง่าย

นอกจากนั้น developer ยังต้องมีการแก้ code ให้เป็นแบบ Decoupling และ Transient จริงๆ ด้วย

---

# Other Solutions

- **[Docker Swarm](https://docs.docker.com/engine/swarm/)**: เป็นของ Docker เอง พัฒนาบนพื้นฐานของ swarmkit และ embedded มากับ Docker Engine
- **[Apache Mesos](http://mesos.apache.org/)**: เป็น data center scheduler ที่สามารถ orchestrate container ได้ด้วยการใช้ framework ที่ชื่อว่า [Marathon](https://mesosphere.github.io/marathon/)
- **[Nomad](https://www.nomadproject.io/)**: เป็นของ HashiCorp หลักการคือ การ schedule task ที่เป็น container ด้วยการ define jobs
- **[Rancher](https://rancher.com/)**: เป็น container orchestrator-agnostic system ที่ support ทั้ง Mesos, Swarm และ Kubernetes

---

# The Borg Heritage

Kubernetes สืบทอดเชื้อสายมาจาก Borg ซึ่งเป็น Tool ที่จัดการ workload ของ application ภายใน data center ของ Google อย่างเช่น Gmail, Apps และ GCE เป็นต้น มากว่า 15 ปี 

อาจพูดได้ว่าประสบการณ์ต่างๆ ที่ Google เคยเจอตลอด 15 ปี ถูกนำมาพัฒนา และเป็นพื้นฐานของ Borg และถูกส่งต่อมายัง Kubernetes 

ถ้าถามว่า จะเลือก software อะไรดีมา manage containers แน่นอน Kubernetes คือ ตัวเลือกที่ดีและปลอดภัยที่สุดในตอนนี้

REF: [Large-scale cluster management at Google](https://research.google/pubs/pub43438/)

นอกจาก Borg แล้ว Google ยัง contribute `cgroups` ให้กับ linux kernel ในปี 2007 ซึ่งมันกลายเป็น 1 ใน 2 หัวใจหลักของ containers หรือ แม้กระทั่ง Docker ที่ใช้ในปัจจุบันนี้

> หัวใจของ Container คือ **`cgroup`** และ **`namespaces`**

**[Mesos](http://mesos.apache.org/)** ของ Apache ก็ได้รับ inspiration จากการ discuss กับ Google ตั้งแต่สมัยที่ Borg ยังเป็นความลับ

Borg และ Kubernetes นั้นได้รับการพัฒนาตามหลัก [12 Factors application principles](https://12factor.net/) 

|![Cloud foundry](https://thepracticaldev.s3.amazonaws.com/i/w188c0r4eszbepbe8dz4.jpg)|
|:--:|
|<center><sup><sub>Source: [Cloud foundry: The Platform for Forging Cloud Native Applications](https://www.slideshare.net/chipchilders/cloud-foundry-the-platform-for-forging-cloud-native-applications)</sub></sup></center>|

---

# Kubernetes Architecture

|![kubernetes arch](https://thepracticaldev.s3.amazonaws.com/i/jtyfiwhgh0h3s69j88dt.png)|
|:--:|
|<center><sup><sub>Source: [Concepts Underlying the Cloud Controller Manager](https://kubernetes.io/docs/concepts/architecture/cloud-controller/)</sub></sup></center>|

Kubernetes ประกอบด้วย Master และ Worker
- **Master**: ทำหน้าที่ run 
  - **`kube-apiserver`**: expose API เพื่อใช้เป็นจุดศูนย์กลางในการสื่อการกับ cluster ทั้งจาก `kubectl`, `curl` หรือ `client library`
  - **`kube-scheduler`**: รับ request จาก API server มาเพื่อหา node ที่เหมาะสมในการ run container
  - **`etcd`**: อาจ run ใน cluster หรือนอก cluster ก็ได้ เป็น Storage ในการเก็บ stage ของ containers, cluster setting และ network configuration
- **Worker**: ทำหน้าที่ run 
  - **`kubelet`**: ทำหน้าที่รับ request ในการ run container (default คือ Docker), manage resources และ ตรวจสอบสถานะ container ในระดับ local node
  - **`kube-proxy`**: สร้างและจัดการ networking rules ที่จะให้ container คุยกับ network อื่นๆ ภายนอก

ด้วยการทำงานแบบ API-based เป็นผลให้ worker ที่ไม่ใช่ linux สามารถทำงานร่วมกับ cluster ที่เป็น linux ได้ โดยเราสามารถใช้ Windows server 2019 เป็น worker ของ kubernetes ได้ตั้งแต่ version 1.14 แต่อย่างไรก็ตาม Master ก็ยังต้องเป็น linux

---

# Terminology

- **Pod**: เป็นกลุ่มของ containers ที่มี IP, access storage และ namespaces เดียวกัน โดยใน 1 pod มีได้หลาย container แต่ปกติแล้วจะมี main container อันเดียวที่ทำ core logic ส่วน container อื่นๆ จะเป็น support application เช่น proxy หรือ logging
- **kube-controller-manager**: จะเป็น controllers ต่างๆ ที่คอย call ไปยัง `kube-apiserver` เพื่อตรวจสอบสถานะของ objects ในความรับผิดชอบ (watch-loop) และทำให้ objects นั้นๆ มี current state เหมือนกับ state ที่ declare ไว้
- **Controllers**:
  - **`Deployment`**: เป็น default controller และเป็น controller ที่ใหม่ที่สุดในตอนนี้ `Deployment` จะคอยตรวจสอบและทำให้ resources ที่ระบุไว้ใน `PodSpec` มีอยู่ครบ จากนั้นจึง deploy `ReplicaSet` (ก่อนหน้าที่จะเป็น `Deployment` default controller คือ `ReplicationController`)
  - **`ReplicaSet`**: ทำการ deploy `pod` และทำให้จำนวนของ `pod` เท่ากับ และ มี state เหมือนกับที่ declare ไว้ (นอกจากนั้นยังมี `Job` และ `CronJob` ที่ handle single หรือ recurring tasks ได้)
  - **`Labels`**: ใช้ในการกำหนด metadata เพื่อใช้ในการ manage `pod` จำนวนเยอะๆ ในครั้งเดียว โดยไม่ต้องสนใจ ID ของแต่ละ `pod`
  - **`Taints`**: เป็นการกำหนดข้อจำกัดของ node นั้นๆ ในการรองรับ `pod`
  - **`Toleration`**: เป็นการกำหนดข้อจำกัดของ `pod` ในการที่จะถูก schedule ไปยัง node
  - **`annotation`**: เป็น metadata เหมือนกัน แต่ `kubectl` ไม่ได้ใช้ 3<sup>th</sup> Party agent หรือ Tools อื่นๆ เป็นคนใช้

> ถ้า `pod` ยอมรับ (tolerate) taints ของ node ได้ ก็สามารถ schedule `pod` ไป run ใน node นั้นๆ ได้

---

# Tools

เนื่องจาก Kubernetes เป็น open-source จึงมี Tools ที่เกี่ยวข้องเกิดขึ้นและตายไปตลอดเวลา จะมี Tool ที่เด่นๆ ในช่วงนี้ได้แก่
- **[Minikube](https://github.com/kubernetes/minikube)**: เป็น community-recommended tool ในการ install single node kubernetes ที่ ใช้ VirtualBox เป็น hypervisor
- **[kubeadm](https://github.com/kubernetes/kubeadm)**: เป็น community-recommended tool ในการ install multi node kubenetes cluster
- **[kubectl](https://github.com/kubernetes/kubectl)**: เป็น command ที่ใช้ในการ manage kubernetes cluster
- **[Helm](https://helm.sh/)**: เป็น Tool ที่ใช้ในการ install software suit ต่างๆ ใน kubenetes cluster
- **[Kompose](https://github.com/kubernetes/kompose)**: เป็น Tool ที่ translate Docker compose file เป็น kubernetes object

---

# เพิ่มเติมเกี่ยวกับ Cloud Native Computing Foundation (CNCF)


- Kubenetes ใช้ [Apache-2.0 license](https://www.cncf.io/blog/2017/02/01/cncf-recommends-aslv2/)
- [Google donate Kubenetes ในเดือนกรกฎาคม 2015 เป็น v1.0](https://techcrunch.com/2015/07/21/as-kubernetes-hits-1-0-google-donates-technology-to-newly-formed-cloud-native-computing-foundation-with-ibm-intel-twitter-and-others/)
- CNCF ถือ copyright ของ Kubernetes
- ถ้าจะ contribute source code ให้ CNCF ต้อง sign CLA กับ CNCF