1. 程式人生 > 其它 >整理k8s————k8s prod相關[三]

整理k8s————k8s prod相關[三]

前言

簡單整理k8s prod。

正文

prod 有兩種:

  1. 自主式prod

  2. 控制器管理的prod

在Kubernetes中,最小的管理元素不是一個個獨立的容器,而是Pod,Pod是最小的,管理,建立,計劃的最小單元.

一個Pod(就像一群鯨魚,或者一個豌豆夾)相當於一個共享context的配置組,在同一個context下,應用可能還會有獨立的cgroup隔離機制,一個Pod是一個容器環境下的“邏輯主機”,它可能包含一個或者多個緊密相連的應用,這些應用可能是在同一個物理主機或虛擬機器上。

Pod 的context可以理解成多個linux名稱空間的聯合:

  1. PID 名稱空間(同一個Pod中應用可以看到其它程序)

  2. 網路 名稱空間(同一個Pod的中的應用對相同的IP地址和埠有許可權)

  3. IPC 名稱空間(同一個Pod中的應用可以通過VPC或者POSIX進行通訊)

  4. UTS 名稱空間(同一個Pod中的應用共享一個主機名稱)

分別來理解這幾點。

pid 名稱空間和IPC 名稱空間,就是說在prod 中執行的多個容器,他們之間可以看到各自的程序,同樣可以互相通訊。

網路 名稱空間,比如說有一個php fprm 和 nginx,他們的埠一定不能相同,因為他們共享一個網路棧。

UTS 名稱空間,也可以說他們可以通過localhost 訪問各自物件。

然後rc,也就是replication controller 是控制副本數的,也就是說prod與rc 息息相關。

那麼需要看一下rc。

Replication Controller 保證了在所有時間內,都有特定數量的Pod副本正在執行,如果太多了,Replication Controller就殺死幾個,如果太少了,Replication Controller會新建幾個。

和直接建立的pod不同的是,Replication Controller會替換掉那些刪除的或者被終止的pod,不管刪除的原因是什麼(維護阿,更新啊,Replication Controller都不關心)。

基於這個理由,我們建議即使是隻建立一個pod,我們也要使用Replication Controller。Replication Controller 就像一個程序管理器,監管著不同node上的多個pod,而不是單單監控一個node上的pod,Replication Controller 會委派本地容器來啟動一些節點上服務(Kubelet ,Docker)。

注:

正如我們在pod的生命週期中討論的,Replication Controller只會對那些RestartPolicy = Always的Pod的生效,(RestartPolicy的預設值就是Always),Replication Controller 不會去管理那些有不同啟動策略pod

上面這個注表示了自主式prod是不受rc管理的。

Replication Controller永遠不會自己關閉,但是,我們並不希望Replication Controller成為一個長久存在的服務。

服務可能會有多個Pod組成,這些Pod又被多個Replication Controller控制著,我們希望Replication Controller 會在服務的生命週期中被刪除和新建(例如在這些pod中釋出一個更新),對於服務和使用者來說,Replication Controller是通過一種無形的方式來維持著服務的狀態.

然後很多時候我們會聽說一個rs這個概念,rs 就是replicaSet,這兩者作用沒有本質的區別,但是replicaset 支援集合式的selector。

ReplicaSet是下一代複本控制器。ReplicaSet和 Replication Controller之間的唯一區別是現在的選擇器支援。

Replication Controller只支援基於等式的selector(env=dev或environment!=qa),但ReplicaSet還支援新的,基於集合的selector(version in (v1.0, v2.0)或env notin (dev, qa))。在試用時官方推薦ReplicaSet。

雖然ReplicaSets可以獨立使用,但是今天它主要被 Deployments 作為協調pod建立,刪除和更新的機制。當您使用Deployments時,您不必擔心管理他們建立的ReplicaSets。Deployments擁有並管理其ReplicaSets。

大多數kubectl支援Replication Controller的命令也支援ReplicaSets。rolling-update命令有一個例外 。如果您想要滾動更新功能,請考慮使用Deployments。此外, rolling-update命令是必須的,而Deployments是宣告式的,因此我們建議通過rollout命令使用Deployments。

ReplicaSet可確保指定數量的pod“replicas”在任何設定的時間執行。然而,Deployments是一個更高層次的概念,它管理ReplicaSets,並提供對pod的宣告性更新以及許多其他的功能。因此,我們建議您使用Deployments而不是直接使用ReplicaSets,除非您需要自定義更新編排或根本不需要更新。

這實際上意味著您可能永遠不需要操作ReplicaSet物件:直接使用Deployments並在規範部分定義應用程式。

簡單介紹一下這個滾動更新。

加入一開始有一個deployment,然後有一個rc1,下面有3個prod。

當我們要替換prod的時候,首先建立另外一個rc2,然後當rc2建立一個新的prod,那麼舊的prod就會刪除一個。

當替換完畢後,rs1就會停用,當回滾的時候,rs1就又會啟動。

然後這種我們指定擴容的方式,還有一種自動擴容的方式,但是這種基本不用,為啥這樣說我們一般使用雲k8s,那麼其實買prod是要錢的,瞭解一下吧。

horizontal prod autoscaling:

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

StatefulSet:

StatefulSet是為了解決有狀態服務的問題(對應Deployments和ReplicaSets是為無狀態服務而設計),其應用場景包括:

  1. 穩定的持久化儲存,即Pod重新排程後還是能訪問到相同的持久化資料,基於PVC來實現

  2. 穩定的網路標誌,即Pod重新排程後其PodName和HostName不變,基於Headless Service(即沒有Cluster IP的Service)來實現

  3. 有序部署,有序擴充套件,即Pod是有順序的,在部署或者擴充套件的時候要依據定義的順序依次依次進行(即從0到N-1,在下一個Pod執行之前所有之前的Pod必須都是Running和Ready狀態),基於init containers來實現

  4. 有序收縮,有序刪除(即從N-1到0)

從上面的應用場景可以發現,StatefulSet由以下幾個部分組成:

  1. 用於定義網路標誌(DNS domain)的Headless Service

  2. 用於建立PersistentVolumes的volumeClaimTemplates

  3. 定義具體應用的StatefulSet

StatefulSet中每個Pod的DNS格式為statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中

  1. serviceName為Headless Service的名字

  2. 0..N-1為Pod所在的序號,從0開始到N-1

  3. statefulSetName為StatefulSet的名字

  4. namespace為服務所在的namespace,Headless Servic和StatefulSet必須在相同的namespace

  5. .cluster.local為Cluster Domain

DaemonSet:

DaemonSet保證在每個Node上都執行一個容器副本,常用來部署一些叢集的日誌、監控或者其他系統管理應用。典型的應用包括:

日誌收集,比如fluentd,logstash等

系統監控,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等

系統程式,比如kube-proxy, kube-dns, glusterd, ceph等

job:

Job負責批量處理短暫的一次性任務 (short lived one-off tasks),即僅執行一次的任務,它保證批處理任務的一個或多個Pod成功結束。

Kubernetes支援以下幾種Job:

非並行Job:通常建立一個Pod直至其成功結束

固定結束次數的Job:設定.spec.completions,建立多個Pod,直到.spec.completions個Pod成功結束

帶有工作佇列的並行Job:設定.spec.Parallelism但不設定.spec.completions,當所有Pod結束並且至少一個成功時,Job就認為是成功

根據.spec.completions和.spec.Parallelism的設定,可以將Job劃分為以下幾種pattern:

CronJob即定時任務,就類似於Linux系統的crontab,在指定的時間週期執行指定的任務。在Kubernetes 1.5,使用CronJob需要開啟batch/v2alpha1 API,即–runtime-config=batch/v2alpha1。

Services:

Kubernetes Pod是平凡的,它門會被建立,也會死掉(生老病死),並且他們是不可復活的。

ReplicationControllers動態的建立和銷燬Pods(比如規模擴大或者縮小,或者執行動態更新)。

每個pod都由自己的ip,這些IP也隨著時間的變化也不能持續依賴。這樣就引發了一個問題:如果一些Pods(讓我們叫它作後臺,後端)提供了一些功能供其它的Pod使用(讓我們叫作前臺),在kubernete叢集中是如何實現讓這些前臺能夠持續的追蹤到這些後臺的?

Kubernete Service 是一個定義了一組Pod的策略的抽象,我們也有時候叫做巨集觀服務。這些被服務標記的Pod都是(一般)通過label Selector決定的(下面我們會講到我們為什麼需要一個沒有label selector的服務)

舉個例子,我們假設後臺是一個圖形處理的後臺,並且由3個副本。這些副本是可以相互替代的,並且前臺並需要關心使用的哪一個後臺Pod,當這個承載前臺請求的pod發生變化時,前臺並不需要直到這些變化,或者追蹤後臺的這些副本,服務是這些去耦

對於Kubernete原生的應用,Kubernete提供了一個簡單的Endpoints API,這個Endpoints api的作用就是當一個服務中的pod發生變化時,Endpoints API隨之變化,對於哪些不是原生的程式,Kubernetes提供了一個基於虛擬IP的網橋的服務,這個服務會將請求轉發到對應的後臺pod

因為prod1 要呼叫prod2,所以呢,有這樣一個東西。

因為每次建立prod1的時候可能ip都不一樣,還有一個就是prod2要指定那個prod1是不現實的,那麼就有了服務發現這回事,服務發現是通過標籤發現的。

下一節網路通訊方式。