# Kubernetes( k8s ) `了解k8s與使用` ###### tags: `RD1` :::spoiler 目錄 [TOC] ::: ## 容器化技術-以docker舉例 ### 為什麼需要容器化技術? ![](https://i.imgur.com/PAFMK0I.png) 過去在部署應用程式時,經常是在同一台機器進行部署工作,但這樣做其實有一些缺點: 1. 資源沒有進行隔離 2. 函式庫共用 3. 應用與主作業系統綁定 之後有人想到可以在主機上跑虛擬機器來將資源分開,不過這樣的做法其實成本很高,因為虛擬機器其實模擬的是整個電腦的執行環境。 再後來有人提出了容器化技術,在做資源分隔時,只要把各個容器所用的函式庫分隔就好,底層還是使用同一個作業系統,這樣帶來的好處有: 1. 啟動速度快 2. 快速地交付與部署 3. 快速的遷移與擴展 ### 容器的生命週期 ![](https://i.imgur.com/K66k8e2.png) ### 關於docker的更多介紹 [容器化技術](https://hackmd.io/1V-GypdvScGyoqA6-kU0Ug?view) ## 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中更詳細的元件說明 ![](https://i.imgur.com/ceHjoPO.png) 這邊首先會提到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。 <img src="https://github.com/zxcvbnius/k8s-30-day-sharing/blob/master/Day27/kubectl-get-namespaces.png?raw=true"> - 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 以下 ![](https://i.imgur.com/2AVW3Kg.png) - 物件資源(object-quotas) 限制 hellospace 最多只能有 2 個 services 物件,且只能有 1 個 loadbalancer, secret, 以及 configmap。 ![](https://i.imgur.com/6Tc1BrP.png) ## minikube Minikube 是由 Google 發布的一個輕量級工具。讓開發者可以在本機上輕易架設一個 Kubernetes Cluster,快速上手 Kubernetes 的指令與環境。Minikube 會在本機上跑起一個 virtual machine,並且在這 VM 裡建立一個 single-node Kubernetes Cluster,本身並不支援 HA (High availability),也不推薦在實際應用上運行。