Kubernetes - 初識
起源
Kubernetes 源自於 google 內部的服務編排系統 - borg,誕生於2014年。它汲取了google 十五年生產環境的經驗積累,並融合了社群優秀的idea和實踐經驗。
名字
Kubernetes 這個名字,起源於古希臘,是舵手的意思,所以它的 logo 即像一張漁網又像一個羅盤,谷歌選擇這個名字還有一個深意:既然docker把自己比作一隻鯨魚,馱著集裝箱,在大海上遨遊,google 就要用Kubernetes去掌握大航海時代的話語權,去捕獲和指引著這條鯨魚按照主人設定的路線去巡遊。
核心
得益於 docker 的特性,服務的建立和銷燬變得非常快速、簡單。Kubernetes 正是以此為基礎,實現了叢集規模的管理、編排方案,使應用的釋出、重啟、擴縮容能夠自動化。
Kubernetes - 認知
叢集設計
Kubernetes 可以管理大規模的叢集,使叢集中的每一個節點彼此連線,能夠像控制一臺單一的計算機一樣控制整個叢集。
叢集有兩種角色,一種是 master ,一種是 Node(也叫worker)。 - master 是叢集的"大腦",負責管理整個叢集:像應用的排程、更新、擴縮容等。 - Node 就是具體"幹活"的,一個Node一般是一個虛擬機器或物理機,它上面事先執行著 docker 服務和 kubelet 服務( Kubernetes 的一個元件),當接收到 master 下發的"任務"後,Node 就要去完成任務(用 docker 執行一個指定的應用)
Deployment - 應用管理者
當我們擁有一個 Kubernetes 集群后,就可以在上面跑我們的應用了,前提是我們的應用必須支援在 docker 中執行,也就是我們要事先準備好docker映象。
有了映象之後,一般我們會通過Kubernetes的 Deployment 的配置檔案去描述應用,比如應用叫什麼名字、使用的映象名字、要執行幾個例項、需要多少的記憶體資源、cpu 資源等等。
有了配置檔案就可以通過Kubernetes提供的命令列客戶端 - kubectl 去管理這個應用了。kubectl 會跟 Kubernetes 的 master 通過RestAPI通訊,最終完成應用的管理。 比如我們剛才配置好的 Deployment 配置檔案叫 app.yaml,我們就可以通過 "kubectl create -f app.yaml" 來建立這個應用啦,之後就由 Kubernetes 來保證我們的應用處於執行狀態,當某個例項執行失敗了或者執行著應用的 Node 突然宕機了,Kubernetes 會自動發現並在新的 Node 上排程一個新的例項,保證我們的應用始終達到我們預期的結果。
Pod - Kubernetes最小排程單位
其實在上一步建立完 Deployment 之後,Kubernetes 的 Node 做的事情並不是簡單的docker run 一個容器。出於像易用性、靈活性、穩定性等的考慮,Kubernetes 提出了一個叫做 Pod 的東西,作為 Kubernetes 的最小排程單位。所以我們的應用在每個 Node 上執行的其實是一個 Pod。Pod 也只能執行在 Node 上。如下圖:
那麼什麼是 Pod 呢?Pod 是一組容器(當然也可以只有一個)。容器本身就是一個小盒子了,Pod 相當於在容器上又包了一層小盒子。這個盒子裡面的容器有什麼特點呢? - 可以直接通過 volume 共享儲存。 - 有相同的網路空間,通俗點說就是有一樣的ip地址,有一樣的網絡卡和網路設定。 - 多個容器之間可以“了解”對方,比如知道其他人的映象,知道別人定義的埠等。
至於這樣設計的好處呢,還是要大家深入學習後慢慢體會啦~
Service - 服務發現 - 找到每個Pod
上面的 Deployment 建立了,Pod 也執行起來了。如何才能訪問到我們的應用呢?
最直接想到的方法就是直接通過 Pod-ip+port 去訪問,但如果例項數很多呢?好,拿到所有的 Pod-ip 列表,配置到負載均衡器中,輪詢訪問。但上面我們說過,Pod 可能會死掉,甚至 Pod 所在的 Node 也可能宕機,Kubernetes 會自動幫我們重新建立新的Pod。再者每次更新服務的時候也會重建 Pod。而每個 Pod 都有自己的 ip。所以 Pod 的ip 是不穩定的,會經常變化的。
面對這種變化我們就要藉助另一個概念:Service。它就是來專門解決這個問題的。不管Deployment的Pod有多少個,不管它是更新、銷燬還是重建,Service總是能發現並維護好它的ip列表。Service對外也提供了多種入口: 1. ClusterIP:Service 在叢集內的唯一 ip 地址,我們可以通過這個 ip,均衡的訪問到後端的 Pod,而無須關心具體的 Pod。 2. NodePort:Service 會在叢集的每個 Node 上都啟動一個埠,我們可以通過任意Node 的這個埠來訪問到 Pod。 3. LoadBalancer:在 NodePort 的基礎上,藉助公有云環境建立一個外部的負載均衡器,並將請求轉發到 NodeIP:NodePort。 4. ExternalName:將服務通過 DNS CNAME 記錄方式轉發到指定的域名(通過 spec.externlName 設定)。
好,看似服務訪問的問題解決了。但大家有沒有想過,Service是如何知道它負責哪些 Pod 呢?是如何跟蹤這些 Pod 變化的?
最容易想到的方法是使用 Deployment 的名字。一個 Service 對應一個 Deployment 。當然這樣確實可以實現。但k ubernetes 使用了一個更加靈活、通用的設計 - Label 標籤,通過給 Pod 打標籤,Service 可以只負責一個 Deployment 的 Pod 也可以負責多個 Deployment 的 Pod 了。Deployment 和 Service 就可以通過 Label 解耦了。
RollingUpdate - 滾動升級
滾動升級是Kubernetes中最典型的服務升級方案,主要思路是一邊增加新版本應用的例項數,一邊減少舊版本應用的例項數,直到新版本的例項數達到預期,舊版本的例項數減少為0,滾動升級結束。在整個升級過程中,服務一直處於可用狀態。並且可以在任意時刻回滾到舊版本。
Kubernetes - 入門實踐Deployment 實踐
首先配置好 Deployment 的配置檔案(這裡用的是 tomcat 映象)
[ app.yaml ]
apiVersion: apps/v1kind: Deploymentmetadata: name: webspec: selector: matchLabels: app: web replicas: 2 template: metadata: labels: app: web spec: containers: - name: web image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine ports: - containerPort: 8080通過 kubectl 命令建立服務
# 建立應用$ kubectl create -f app.yamlDeployment.apps/web created# 等待一會後,檢視 Pod 排程、執行情況。# 我看可以看到 Pod 的名字、執行狀態、Pod 的 ip、還有所在Node的名字等資訊$ kubectl get Pods -o wideNAME READY STATUS RESTARTS AGE IP NODEweb-c486dd5c4-86fxm 1/1 Running 0 1m 172.24.3.13 node-01web-c486dd5c4-zxdbb 1/1 Running 0 1m 172.24.0.149 node-02Service 實踐
通過上面建立的 Deployment 我們還沒法合理的訪問到應用,下面我們就建立一個 service 作為我們訪問應用的入口。
首先建立service配置
[ service.yaml ]
apiVersion: v1kind: Servicemetadata: name: webspec: ports: - port: 80 # 服務埠 protocol: TCP targetPort: 8080 # 容器埠 selector: app: web # 標籤選擇器,這裡的app=web正是我們剛才建立app建立服務
# 建立$ kubectl create -f service.yamlservice/web created# 檢視$ kubectl get serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEweb ClusterIP 10.95.189.143 <none> 80/TCP 9s訪問服務
接下來就可以在任意節點通過ClusterIP負載均衡的訪問後端應用了
# 在任意 Node 上訪問tomcat服務$ curl -I 10.95.189.143HTTP/1.1 200 OKServer: Apache-Coyote/1.1Content-Type: text/html;charset=UTF-8Transfer-Encoding: chunkedOne More Thing
好啦~ 以上就是Kubernetes入門的全部內容,看懂這篇文章,你就整體上大概了解了Kubernetes。
想要更多、更深入的學習Kubernetes,去慕課網看我的實戰課吧!
https://coding.imooc.com/class/335.html