Kubernetes( k8s )
了解k8s與使用
目錄
容器化技術-以docker舉例
為什麼需要容器化技術?
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
過去在部署應用程式時,經常是在同一台機器進行部署工作,但這樣做其實有一些缺點:
- 資源沒有進行隔離
- 函式庫共用
- 應用與主作業系統綁定
之後有人想到可以在主機上跑虛擬機器來將資源分開,不過這樣的做法其實成本很高,因為虛擬機器其實模擬的是整個電腦的執行環境。
再後來有人提出了容器化技術,在做資源分隔時,只要把各個容器所用的函式庫分隔就好,底層還是使用同一個作業系統,這樣帶來的好處有:
- 啟動速度快
- 快速地交付與部署
- 快速的遷移與擴展
容器的生命週期
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
關於docker的更多介紹
容器化技術
k8s簡介
什麼是Kubernetes?
Kubernetes 是一個協助我們自動化部署、擴張以及管理容器應用程式(containerized applications)的系統。
Kubernetes 可以幫我們做到以下幾件事情:
- 同時部署多個 containers 到一台機器上或是多台機器。
- 管理各個 container 的狀態。
- 將一台機器上所有的 containers 轉移到另外一台機器上。
- 提供機器高度擴張性。
為何使用Kubernetes?
相較於單體架構(Monolithic Architecture) 的服務,微服務(microservices)架構大大減少程式複雜度,將每個服務依照各自業務需求獨立出來,以 Rest API 互相構通。
然而微服務的概念導入之後,雖然解決的了單體架構的問題,但是因為將一個大服務切分為多個小服務,管理就會變得有難度了,要人工把各個環境建立起來除了費時,維護也很不容易,因為除了數量多,每個服務可能使用的環境都不盡相同,這時使用Kubernetes就很方便了。
Kubernetes 的優點
- 可以跑在任何地方 (Can run anywhere)
Kubernetes 可以運行在任何地方:不論是私有雲、公有雲(AWS, Google Cloud Platform )或是混合雲。
- 高度模組化 (High modular)
每個服務都被切成一個container ,不論是要做修改、擴張、甚至將服務遷移到另外一台機器,都可以快速被部署。
- 活躍的社群 (Open source & active community)
Kubernetes是開源的 ,受到社群的關注度也非常高。
- Google的背書 (Backed by Google)
最初版的 Kubernetes 是由 Google 內部 Borg team 的成員撰寫且現在仍在持續維護。Google 使用他們自身的系統 Borg 管理容器化應用長達十年多。Kubernetes 的目的即是將 Borg 最精華的部分取出來,使得開發者能夠更簡單、直接應用。
k8s基本元件與架構
Pod 是什麼
Kubernetes 上會運行很多個不同種類型的應用服務(applications),而一個 Pod 在Kubernetes世界中就相當於一個application。
Pod有以下特點,
- 每個 Pod 都有屬於自己的 yaml 檔
- 一個 Pod 裡面可以包含一個或多個 Docker Container
- 在同一個 Pod 裡面的 containers,可以用 local port numbers 來互相溝通
Node 是什麼
在 Kubernetes 中,Node 通常是指實體機、虛擬機。一個Node,可以是指 AWS的一台EC2 或 GCP上的一台computer engine ,也可以是你的筆電,甚至是一台 Raspberry Pi。只要他們上面裝有 Docker Engine ,足以跑起 Pod,就可以被加入 Kubernetes Cluster。
將 Node 加到 Kubernetes 中之後,Kubernetes 會建立一個Node 物件,並進行一連串檢查,包含網路連線,Pod 是否能被正常啟動等,若都通過則會將該Node物件的狀態設為 Ready,若是無法通過則會顯示 Not Ready。
Cluster 是什麼
那cluster的部分就是說,由多個Node組合而成(一個Master Node及多個Worker Node),Node之中又有很多很多的Pod,Pod之中又可能含有一個或以上的container,那這樣的一個組合就能說是一個cluster,也就是今天所要提供的一個完整服務。
用下面的圖片來說明Node中更詳細的元件說明
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
這邊首先會提到Master Node,那Master Node中有包含四個部分,API server, Scheduler, Controller-manager, etcd。
- API Server是一個非常重要的東西,今天不管是從外部給的指令,例如: kubectl create…,或是內部Node之間的構通,都會透過API Server來進行。
- Scheduler可以說是Pod的調度者,如果有新的Pod需要建立,Scheduler就會看就會依照現在每一個Node的運作狀況平均的去分配Pod給每一個Node。
- Controller-manager會管理每一個Controller,那Controller又是什麼呢?就是如果今天有Node因為需求需要多開一個,那這時候就有一個叫做Node controller的人會去完成這件事情;如果是因為一開始設定replication幾個Pod那replication controller就會去維護好。那回到Controller-manager,就是管理上述controller的管理中心。
- etcd的話就是一個備份的機制,他會一段時間備份整個cluster的資料,當今天如果master壞掉了,那透過etcd就能夠還原出當時的狀況。
提完Master的部分那就該來談談Worker Node,顧名思義他就像工人一樣,裡面放了很多很多Pod也就是放了很多很多的服務在裡面,如果要取用什麼服務那就要訪問那個Node。
他也有一些屬於自己才有的元件,有kubelet,proxy,iptable。
- kubelet就是一個Node中的管理員,會去看每一個Pod的狀況,並且回報給Master,這樣在分配新的Pod的時候,才能知道要分配給哪個Node最好。
- proxy的部分就是說今天如果有Pod被建立,同時也會有自己的IP,那就會被記錄到iptables中,這樣要訪問需要被使用的Pod的時候,就能知道他在哪裡。
volumn、configmap、secret
secret
Secrets 是 Kubernetes 提供開發者一種存放敏感資訊的方式。Kubernetes 本身也使用相同的機制( secrets mechanism) 存放 access token,限制 API 的存取權限,確保不會有外部服務隨意操作 Kubernetes API。
在 Kubernetes 存取敏感資料(sensitive data)有以下幾種常見的使用方式:
- 將 Secrets 當成 環境變數(environment variables) 使用
- 將 Secrets File 掛載(mount) 在 Pod 某個檔案路徑底下使用
- 將這些 sensitive data 統一存放在某一個 Docker Image 中,並將這個 Image 存放在私有的 Image Registry 中,透過 image pull 下載到 Kubernetes Cluster 中,讓其他 Pods 存取。
configmap
Configuration 泛指程式存取外部資源或是部署所需的資料,像是資料庫的所在 IP、管理者的帳號密碼,或是 Nginx 的設定檔等等。若是其他人不小心存取資源,導致資料庫被刪除,或被公開,都可能導致專案陷入危險之中,或是損害該應用服務的使用者的權益。
ConfigMap 有以下特點:
- 一個 ConfigMap 物件可以存入整個 configuration
像是 webserver config file, Nginx config file
- 無需修改 container 程式碼,可以替換不同環境的 Config
開發過程中,常因應不同的環境需配置不同的 configuration,像是 staging 與 production 存取的資料庫位址不一致等等。無需修改程式碼的特點,可以幫助我們更快部署到各個不同的環境中。
- 統一存放所有的 configuration
透過 kubectl get 指令快速查看目前系統所有的 ConfigMap。
volumn
Volumes 可以當成是 Kubernetes Cluster 中專門用來儲存資料的地方。不但能將 container 的資料儲存下來,也可以透過掛載(mounting)的方式,供許多個 Pods 同時存取。而 Kubernetes 也提供非常多種的 Volumes 類型,在 Kubernetes 官網中,對每個類型也都有非常詳細的介紹,若有興趣的讀者不妨參考看看。
四種常用的 Volume 類型:
- emptyDir
- hostPath
- Cloud Storage
- NFS (Network FileSystem)
Deploy and Horizontal Pod AutoScalling
Deployment
在說Deployment前,我想先說說Horizontal Scaling與Vertical Scaling:
可擴展性就是系統藉由增加資源(運算資源、硬體資源)來處理大量成長的工作
Scalability is the property of a system to handle a growing amount of work by adding resources to the system. - Wiki
Scaling可以分為兩種, Horizontal scaling 與 Vertical scaling 。橫向擴展(Horizontal scaling)代表,我們可以透過增加更多的機器節點,獲取更多資源,來分擔原有的工作內容。而縱向擴展(Vertical scaling)則表示我們可以在單一節點上,新增更多的 CPU,RAM 來獲得更多運作資源。
Deployment 可以幫我們達成以下幾件事情:
- 部署一個應用服務(application)
- 協助 applications 升級到某個特定版本
- 服務升級過程中做到無停機服務遷移(zero downtime deployment)
- 可以Rollback到先前版本
Horizontal Pod AutoScaling
在許多實際場景中,應用服務常常需因應不同流量而配置不同的資源。好比:原本的應用服務可能每天都只有 10 人使用,我們只需要架設一台小 server 即可應付這些流量;當有天應用服務因為某些因素使用人數上升到 10 萬人,可能我們原有的資源不足以回應這些流量,導致使用者無法連上該應用服務。如果這時候,系統能幫我們根據目前的資源使用率,決定是否自動調整資源(像是加開 server)來回應這些流量就太好了。
Sevice and DNS
介紹完 Replication Controller 以及 Deployment 對 Pod 物件的操作,讀者應該可以發現Pod 的生命週期是非常動態的。以應用程式升級(rollout) 為例,Deployment 會先創建新的 Pod 去取代現有的 Pod 物件,也因此,我們需要一個中間橋樑,來確保終端使用者(end user)或是其他應用服務,可以在該應用程式升級時,仍可以連到該應用程式中可用的Pod (available pods)。
Service
Pod的生命週期是十分動態的,雖然擁有cluster ip供其他服務連接,但在Deployment或Replication應用中,會有提供類似或相同服務重複的Pod(Scaling),也有Pod因為升級或故障被停止。為了能夠拿到Pod提供的服務,我們必須有一個中間橋樑能夠獲取想要的服務,k8s提供了service物件。
Service提供的不同種類服務:
- ClusterIP
- NodePort
- LoadBalancer
ClusterIp
ClusterIP是k8s默認的模式,只有在同一個Cluster底下的應用程式可以讀取。有個例外,使用k8s proxy就可以從外面使用此服務。
NodePort
NodePort可以將service綁定在所有node的某個port上,可以透過node的那個port存取該服務。
LoadBalancer
如果我們的Kubernetes Cluster是架在第三方雲端服務(cloud provider),例如 Amazon 或 Google Cloud Platform,我們可以透過這些 cloud provider 提供的 LoadBalancer ,幫我們分配流量到每個 Node 。
namespace
Namespaces 是什麼 ?
Kubernetes 提供了抽象的 Cluster (virtual cluster) 的概念,讓我們能根據專案不同、執行團隊不同,或是商業考量,將原本擁有實體資源的單一 Kubernetes Cluster ,劃分成幾個不同的抽象的 Cluster (virtual cluster),也就是 Namespaces。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- default
預設的 Namespaces 名稱為 default,過去我們產生的物件像是, Deployment, Services 等若沒特別指定 Namespace 都是存放在名稱為 default 的 namespaces 中。
- kube-system
在 Kubernetes 中,較特別的資源都會存放在 kube-system 這個 namespace。先前介紹的 kube-dns 或是 heapster 都是存放在該 namepsace 中。
- kube-public
kube-public 也是個特殊的 namespace,存放在裡面的物件可被所有的使用者讀取。
Namespaces 有以下幾個特點
- 在同一個 Kubernetes Cluster 中,每個 Namespaces 的名稱都是要獨特的
- 當一個 Namespaces 被刪除時,在該 Namespace 裡的所有物件也會被刪除
- 以透過 Resource Quotas 限制一個 Namespaces 所可以存取的資源
限制 Namespaces 的運算資源
- 運算資源(compute-quotas)
CPU 最多只有 1 core ,以及 memory 的使用被限制在 10Gi 以下

- 物件資源(object-quotas)
限制 hellospace 最多只能有 2 個 services 物件,且只能有 1 個 loadbalancer, secret, 以及 configmap。

minikube
Minikube 是由 Google 發布的一個輕量級工具。讓開發者可以在本機上輕易架設一個 Kubernetes Cluster,快速上手 Kubernetes 的指令與環境。Minikube 會在本機上跑起一個 virtual machine,並且在這 VM 裡建立一個 single-node Kubernetes Cluster,本身並不支援 HA (High availability),也不推薦在實際應用上運行。