--- title: Kubernetes 簡介與安裝 langs: zh tags: Kubernetes, k8s image: https://raw.githubusercontent.com/cncf/artwork/master/projects/kubernetes/icon/color/kubernetes-icon-color.svg?sanitize=true --- # Kubernetes Intro  **Kubernetes**(常簡稱為**K8s**)是用於自動部署、擴展和管理「容器化(containerized)應用程式」的開源系統。該系統由 Google 設計並捐贈給 Cloud Native Computing Foundation(今屬 Linux 基金會)來使用。 它旨在提供「跨主機集群的自動部署、擴展以及運行應用程式容器的平台」。它支持一系列容器工具,包括 Docker 等。 ## Kubernetes 概覽 ### 應用程式演化  - **傳統部署時期**:早期,應用程式執行於實體伺服器(physical server)上。此種方式無法為實體伺服器中的應用程式規定資源使用量,因此會導致資源分配問題。 - **虛擬化部署時期**:作為解決方法,虛擬化被引入了。它能讓你在一台實體伺服器的CPU上同時運行多個虛擬機器(Virtual machines)。虛擬化能讓應用程式在不同的虛擬機之間隔離,並提供安全層級,因為一個應用程式的資訊不能被另一個應用程式任意存取。 虛擬化在實體伺服器中能有更好的資源使用和較佳的擴展性,因為應用程式可以簡單地被新增或更新、減少硬體消耗......。 - **容器部署時期**:容器類似於虛擬機,但它們擁有開放的(relaxed)隔離屬性,在應用程式間共享作業系統(OS)。因此容器被認為是輕量的。和虛擬機類似,容器擁有自己的檔案系統、CPU、記憶體、執行空間......等。由於他們與底層基礎架構分離,因此能夠跨雲端和作業系統分發進行移植。 ### 為什麼需要 Kubernetes 和它能做什麼 Kubernetes 提供一種框架去彈性地執行分散式系統。它負責應用程式的擴展和故障轉移(failover),提供部署模式(patterns)等。 Kubernetes 提供: - 服務發現(Service discovery)和負載平衡 K8s可以使用DNS名稱或使用自己的IP位址公開(expose)容器。如果容器流量很高,K8s能夠負載平衡並分散網路流量來使此部署穩定。 - 儲存協作(Orchestration) K8s允許你自動掛載(mount)你選擇的儲存系統,像是本地儲存,公開的雲端供應商...等。 - 自動推出(rollouts)和回滾(rollbacks) 你可以利用K8s描述已部署容器的所需狀態,並且可以已受控的速率將實際狀態改變為所需狀態。例如:你可以自動化 Kubernetes 為了你的部署去建立新容器,移除現存的容器並將他們所有的資源用於新容器。 - 自動包裹包裝(Automatic bin packing) 你提供K8s一個可用於運行容器化任務的節點集群(cluster)。你告訴K8s每個容器需要多少CPU和記憶體(RAM)。K8s可以將容器安裝到你的節點上,以充分利用你的資源。 - 自我修復(Self-healing) K8s重啟失效的容器、替換容器、終止(kills)不回應用戶定義的狀況檢查的容器,在準備好服務之前不會將它們通知給客戶端。 - 機密(Secret)和組態管理 K8s讓你儲存和管理敏感資訊,像是密碼、開放授權代幣(OAuth token)和SSH密鑰。你可以部署和更新機密和應用程式組態而不需要重建你的容器映像(images),也不用在堆疊組態(stack configuration)中暴露你的機密。 ## Kubernetes 元件  當你部署 Kubernetes 時,你會得到一個**叢集(cluster)**。 一個 Kubernetes cluster 由一組執行容器化的應用程式的工作機器,稱作**節點(nodes)** 所組成。每個 cluster 至少有一個**工作節點(worker node)**。 工作節點託管(host)作為應用程式工作負載的組件 - **pod**。**控制平面(Control Plane)** 管理 cluster 中的 worker nodes 和 pods。在生產環境中,Control Plane 通常在多台電腦間運行,而 cluster 通常運行多個 node,以提供容錯和高可用性。  ### Control Plane Components > Control Plane 的元件對 cluster 進行全局決策(例如:排程),並偵測和回應 cluster 事件(例如:當部署的 `replicas` 欄位不滿足時,啟動新的 pod)。 > [color=#0b67b4] > Control Plane 元件可以被任何同一 cluster 中的機器執行。然而,為了簡單起見,設置腳本(set up scripts)通常在同一台機器上啟動所有 Control Plane 元件,且不會在該機器上運行使用者容器(user containers)。 可以將其看成 cluster 中的主節點(master node) #### kube-apiserver > API server 是 Kubernetes control plane 元件,它會公開 Kubernetes API。API server 是 Kubernetes control plane 的前端(front end)。 主要用途為管理整個K8s所需API的接口(Endpoint),像是從命令列下 `kubectl` 指令,就會把指令送到這。 #### etcd > 一致和高可用的鍵值存儲用作給所有 cluster 數據的 Kubernetes 的備用存儲。 #### kube-scheduler > Control Plane 元件,該元件監看新建的且未被分配給 node 的 pods,並選擇一個要在其上運行的 node 給它們。 > > 排程決定需要考慮的因素包括個體和集體的資源需求、軟/硬體/策略約束...等。 Pods 調度員 #### kube-controller-manager > 執行 controller[^1]程序的 Control Plane 元件。 > - Node Controller: 負責注意和回應當nodes下線 > - Replication Controller: 負責為系統中的每個複製控制器物件維護正確數量的pods > - Endpoints Contorller: 自動生產端點物件(即是,加入Services & Pods) > - Service Account & Token Controllers: 建立預設帳戶和API存取tokens給新命名空間。 簡單來說 controller 就是 Kubernetes 中,一個負責監視 cluster 狀態的 process #### cloud-controller-manager cloud-contorller-manager 運行與底層雲端提供者互動的控制器。 ### Node Components Node 元件運行在每個節點上,維護運行的 pods 和提供 Kubernetes 運行環境。 #### kubelet > 在 cluster 中執行在每個節點的代理者。它確保容器皆運行於pod之中。 > > kubelet 包含通過各種機制提供的一組 PodSpec,並確保這些在 PodSpec 中描述的容器運作正常。kubelet 並不管理不是由 Kubernetes 建立的容器。 該 Node 的管理員,負責與 control plane 溝通。 #### kube-proxy kube-proxy 是一個運行在 cluster 內的每個 node 上的網絡代理,實作了部分 Kubernetes Service 概念。 #### Container Runtime 是真正在節點中執行容器的軟體。 Kubernetes 支援多種 container runtime。一般預設為 [Docker](https://www.docker.com/) ## 基本運作流程  > 接下來我們用一個簡單的問題「Kubernetes 是如何建立一個 Pod?」來複習整體 Kubernetes 的架構。上圖為一個簡易的 Kubernetes Cluster,通常一個 Cluster 中其實會有多個 Master 作為備援,但為了簡化我們只顯示一個。 > > 當使用者要部署一個新的 Pod 到 Kubernetes Cluster 時,使用者要先透過 User Command(kubectl)輸入建立 Pod 的對應指令(下面會在解說如何實際動手操作來建立一個 Pod)。此時指令會經過一層確認使用者身份的認證後,傳遞到 Master Node 中的 API Server,API Server 會把指令備份到 etcd 。 > > 接下來 controller-manager 會從 API Server 收到需要創建一個新的 Pod 的訊息,並檢查如果資源許可,就會建立一個新的 Pod。最後 Scheduler 在定期訪問 API Server 時,會詢問 controller-manager 是否有建置新的 Pod,如果發現新建立的 Pod 時,Scheduler 就會負責把 Pod 配送到最適合的一個 Node 上面。 > >雖然上面的基本運作看似複雜,但實際上我們在操作時,只要輸入一行指令後 Kubernetes 就會自動幫我們完成後續的動作。 > [name=[胡程維](https://medium.com/@C.W.Hu/kubernetes-basic-concept-tutorial-e033e3504ec0)] [color=#4f70d4] # 安裝與執行 Kubernetes :::info 以下皆於 macOS 操作 ::: ## 安裝K8s ### 學習環境 想在本地端使用 Kubernetes 必須安裝以下三個套件: 1. **kubectl**:Kuberbetes command-line 工具,能讓你對 Kubernetes cluster 執行指令。 :::spoiler 雖然有另一種儀表板(Dashboard)UI 介面可供操作,但本章只使用指令控制K8s。 ::: 安裝方式請參考:[Install and Set Up kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl) 2. **虛擬機監視器**(此處使用免費的 **VirtualBox**): 於[下載頁面](https://www.virtualbox.org/wiki/Downloads)選擇對應的作業系統並安裝 3. **Minikube**:能夠在PC上的虛擬機運行單一節點(single-node) Kubernetes cluster 的工具。 安裝方式請參考:[Installing minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) ### 生產環境 請參閱 [Production environment](https://kubernetes.io/docs/setup/#production-environment) ## Kubernetes 基礎運行 確認皆安裝完畢後,開啟命令列即可開始第一次的測試 1. 啟動 Minikube 和建立 cluster ``` minikube start ``` 2. 現在,你可以利用 `kubectl` 與你的 cluster 互動了。讓我們利用現存的 image `echoserver` 建立一個 Kubernetes Deployment,它是一個簡單的 HTTP 伺服器以及利用 `--port` 將8080埠公開。 ```shell kubectl create deployment hello-minikub --image=k8s.gcr.io/echoserver:1.10 ``` 3. 為了要能夠存取 `hello-minikube` Deployment,將它公開為一項 Service ```shell kubectl expose deployment hello-minikube --type=NodePort --port=8080 ``` 選項 `--type=NodePort` 規定 Service 的類型 4. `hello-minikube` Pod 現在已經啟動了,但你必須在利用公開的 Service 存取它之前等待該 Pod 上線。 確認 Pod 是否上線並運行: ```shell kubectl get pod ``` 如果輸出顯示 `STATUS` 為 `ContainerCreating`,則 Pod 正在建立中;如果輸出顯示 `STATUS` 為 `Running`,則表示該 Pod 正在線上並運行。 5. 取得公開的 Service 的 URL 檢視 Service 詳細資料: ```shell minikube service hello-minikube --url ``` 6. 為了查看本地的 cluster 的詳細資料,複製並貼上你從輸出畫面得到的 URL 在瀏覽器上。 輸出應該像這樣: ``` Hostname: hello-minikube-7c77b68cff-8wdzq Pod Information: -no pod information available- Server values: server_version=nginx: 1.13.3 - lua: 10008 Request Information: client_address=172.17.0.1 method=GET real path=/ query= request_version=1.1 request_scheme=http request_uri=http://192.168.99.100:8080/ Request Headers: accept=*/* host=192.168.99.100:30674 user-agent=curl/7.47.0 Request Body: -no body in request- ``` 如果你不想 Service 和 cluster 繼續運行,你可以刪除它們。 7. 刪除 `hello-minikube` Service: ```shell kubectl delete services hello-minikube ``` 8. 刪除 `hello-minikube` Deployment ```shell kubectl delete deployment hello-minikube ``` 9. 停止本地 Minikube cluster: ```shell minikube stop ``` 10. 刪除本地 Minikube cluster ```shell minikube delete ``` ### 額外運行 [額外物件教學](https://medium.com/@C.W.Hu/kubernetes-implement-ingress-deployment-tutorial-7431c5f96c3e) ## [Kubernetes Objects](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) *Kubernetes objects* 是在 K8s 系統內的永久實體。K8s 使用這些實體來表示 cluster 的狀態。具體來說,它們描述: - 正在運行哪些容器化應用程式(和在哪個節點上) - 那些應用程式可用的資源 - 那些應用程式的行為政策,像是重啟政策、升級和容錯 ### Object Spec and Status 幾乎所有 Kubernetes object 都會包含兩個監管物件組態的巢狀物件欄位:`spec` 和 `status`。如果物件含有 `spec`,你必須在建立此物件時設定它,提供你希望你的資源擁有什麼樣的特性的描述:他的理想狀態。 ## 附件 基礎物件: - Pod - Service - Volume - Namespace higher-level abstractions: - Deployment - DaemonSet - StatefulSet - ReplicaSet - Job [Source](https://kubernetes.io/docs/concepts/#kubernetes-objects) [^1]: controller: A control loop that watches the shared state of the cluster through the apiserver and makes changes attempting to move the current state towards the desired state. *[CNCF]: Cloud Native Computing Foundation *[K8s]: Kubernetes
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.