K8S Deployment、ReplicaSet和Pod關係圖 新的問題又來了:如果都是為了管控Pod好好乾活,為什麼要設置Deployment和ReplicaSet兩個層級呢,直接讓Deployment來管理不可以嗎?
回答:不清楚,但是私以為是因為先有ReplicaSet,但是使用中發現ReplicaSet不夠滿足要求,於是又整了一個Deployment(有清楚Deployment和ReplicaSet聯繫和區別的小夥伴歡迎留言啊 )。
但是,從K8S使用者角度來看,用戶會直接操作Deployment部署服務,而當Deployment被部署的時候,K8S會自動生成要求的ReplicaSet和Pod。在K8S官方文檔中也指出用戶只需要關心Deployment而不操心ReplicaSet:
This actually means that you may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section.
這實際上意味著您可能永遠不需要操作ReplicaSet對象:直接使用Deployments並在規範部分定義應用程序。
補充說明:在K8S中還有一個對象 --- ReplicationController(簡稱RC) ,官方文檔對它的定義是:
ReplicationController 確保在任何時候都有特定數量的 Pod 副本處於運行狀態。 換句話說,ReplicationController 確保一個 Pod 或一組同類的 Pod 總是可用的。
怎麼樣,和ReplicaSet是不是很相近?在Deployments, ReplicaSets, and pods教程中說「ReplicationController是ReplicaSet的前身」,官方也推薦用Deployment取代ReplicationController來部署服務。
Service和Ingress
吐槽下K8S的概念/對象/資源是真的多啊!前文介紹的Deployment、ReplicationController和ReplicaSet主要管控Pod程序服務;那麼,Service和Ingress則負責管控Pod網路服務 。
我們先來看看官方文檔中Service的定義:
將運行在一組 Pods 上的應用程序公開為網路服務的抽象方法。
使用 Kubernetes,您無需修改應用程序即可使用不熟悉的服務發現機制。 Kubernetes 為 Pods 提供自己的 IP 地址,並為一組 Pod 提供相同的 DNS 名, 並且可以在它們之間進行負載均衡。
翻譯下:K8S中的服務(Service)並不是我們常說的「服務」的含義,而更像是網關層,是若干個Pod的流量入口、流量均衡器。
那麼,為什麼要Service呢 ?
私以為在這一點上,官方文檔講解地非常清楚:
Kubernetes Pod 是有生命周期的。 它們可以被創建,而且銷毀之後不會再啟動。 如果您使用 Deployment 來運行您的應用程序,則它可以動態創建和銷毀 Pod。
每個 Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一時刻運行的 Pod 集合可能與稍後運行該應用程序的 Pod 集合不同。
這導致了一個問題: 如果一組 Pod(稱為「後端」)為群集內的其他 Pod(稱為「前端」)提供功能, 那麼前端如何找出並跟蹤要連接的 IP 地址,以便前端可以使用工作量的後端部分?
補充說明:K8S集群的網路管理和拓撲也有特別的設計,以後會專門出一章節來詳細介紹K8S中的網路。這裡需要清楚一點:K8S集群內的每一個Pod都有自己的IP(是不是很類似一個Pod就是一台伺服器,然而事實上是多個Pod存在於一台伺服器上,只不過是K8S做了網路隔離),在K8S集群內部還有DNS等網路服務(一個K8S集群就如同管理了多區域的伺服器,可以做複雜的網路拓撲)。
此外,筆者推薦k8s外網如何訪問業務應用對於Service的介紹,不過對於新手而言,推薦閱讀前半部分對於service的介紹即可,後半部分就太複雜了。我這裡做了簡單的總結:
Service是K8S服務的核心,屏蔽了服務細節,統一對外暴露服務介面,真正做到了「微服務」 。舉個例子,我們的一個服務A,部署了3個備份,也就是3個Pod;對於用戶來說,只需要關注一個Service的入口就可以,而不需要操心究竟應該請求哪一個Pod。優勢非常明顯:一方面外部用戶不需要感知因為Pod上服務的意外崩潰、K8S重新拉起Pod而造成的IP變更,外部用戶也不需要感知因升級、變更服務帶來的Pod替換而造成的IP變化,另一方面,Service還可以做流量負載均衡 。
但是,Service主要負責K8S集群內部的網路拓撲。那麼集群外部怎麼訪問集群內部呢?這個時候就需要Ingress了,官方文檔中的解釋是:
Ingress 是對集群中服務的外部訪問進行管理的 API 對象,典型的訪問方式是 HTTP。
Ingress 可以提供負載均衡、SSL 終結和基於名稱的虛擬託管。
翻譯一下:Ingress是整個K8S集群的接入層,複雜集群內外通訊。
最後,筆者把Ingress和Service的關係繪製網路拓撲關係圖如下,希望對理解這兩個概念有所幫助:
K8S Ingress、Service和Pod關係圖
amespace 命名空間
和前文介紹的所有的概念都不一樣,namespace跟Pod沒有直接關係,而是K8S另一個維度的對象。或者說,前文提到的概念都是為了服務Pod的,而namespace則是為了服務整個K8S集群的。
那麼,namespace是什麼呢?
上官方文檔定義:
Kubernetes 支持多個虛擬集群,它們底層依賴於同一個物理集群。 這些虛擬集群被稱為名字空間。
翻譯一下:namespace是為了把一個K8S集群劃分為若干個資源不可共享的虛擬集群而誕生的 。
也就是說,可以通過在K8S集群內創建namespace來分隔資源和對象 。比如我有2個業務A和B,那麼我可以創建ns-a和ns-b分別部署業務A和B的服務,如在ns-a中部署了一個deployment,名字是hello,返回用戶的是「hello a」;在ns-b中也部署了一個deployment,名字恰巧也是hello,返回用戶的是「hello b」(要知道,在同一個namespace下deployment不能同名;但是不同namespace之間沒有影響)。前文提到的所有對象,都是在namespace下的;當然,也有一些對象是不隸屬於namespace的,而是在K8S集群內全局可見的,官方文檔提到的可以通過命令來查看,具體命令的使用辦法,筆者會出後續的實戰文章來介紹,先貼下命令:
# 位於名字空間中的資源
kubectl api-resources --namespaced=true
?
# 不在名字空間中的資源
kubectl api-resources --namespaced=false
不在namespace下的對象有:
在namespace下的對象有(部分):
一般做一件事情都是要有內驅力,或者工作需求。
所以,你直接問怎麼學k8s,這個會讓人難以回答的讓你可以執行。我拋幾個問題吧,在解決問題的過程中學習,才是最好的學習方法,要麼你就把k8s文檔一篇不少的全吸收完。
1. deployment, pod, job有什麼區別?什麼場景用他們?2. service是幹嘛的?可以解決些什麼問題?3. 我想部署一些有狀態的服務,比如MySQL,用k8s怎麼做?就這麼三個問題吧,其它的,等你有問題了再談。
首先得把所有的知識點好好捋一遍,官方文檔是個不錯的選擇,如果英文不好,還是買本書吧,現在也就只有kubernetes權威指南比較靠譜,知識點,概念都有解釋
本地建他五六個虛擬機,搭個k8s集群出來,知識點一個一個的實踐一下。國內有牆,注意鏡像的掛起狀態,多看日誌,有可能就是被牆了
在生產環境下,如果是暴露到了公網環境,安全問題就很重要了,節點,程序之間的加密通訊要著重掌握
去github上看k8s這個項目就能知道,幾小時內就能有好幾次提交,一周一個版本司空見慣,官方文檔都已經跟不上了,好多文檔上沒有的東西,就只能去代碼里看了
可以看看https://zhuanlan.zhihu.com/p/56159304
幫你頂帖,我也是運維,docker的方方面面基本上摸了一遍,一看k8s就感覺兩眼迷茫無從下手,很多文檔感覺都不系統,希望有大神出來指教一二
了解docker
了解kubernetes概念,坦白說還是很有門檻的
了解kubernetes的架構
學習kubernetes的安裝運維、網路存儲、日誌
劃重點:學習如何管理應用
kubernetes的擴展開發
官方文檔就可以了
推薦閱讀: