Try   HackMD

Kubernetes( k8s )

了解k8s與使用

tags: RD1
目錄

容器化技術-以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 →

過去在部署應用程式時,經常是在同一台機器進行部署工作,但這樣做其實有一些缺點:

  1. 資源沒有進行隔離
  2. 函式庫共用
  3. 應用與主作業系統綁定

之後有人想到可以在主機上跑虛擬機器來將資源分開,不過這樣的做法其實成本很高,因為虛擬機器其實模擬的是整個電腦的執行環境。

再後來有人提出了容器化技術,在做資源分隔時,只要把各個容器所用的函式庫分隔就好,底層還是使用同一個作業系統,這樣帶來的好處有:

  1. 啟動速度快
  2. 快速地交付與部署
  3. 快速的遷移與擴展

容器的生命週期

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提供的不同種類服務:

  1. ClusterIP
  2. NodePort
  3. 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),也不推薦在實際應用上運行。