假如我們現在有一個Pod
正在提供線上的服務,我們來想想一下我們可能會遇到的一些場景:
- 某次運營活動非常成功,網站訪問量突然暴增
- 運行當前
Pod
的節點發生故障了,Pod
不能正常提供服務了
第一種情況,可能比較好應對,一般活動之前我們會大概計算下會有多大的訪問量,提前多啟動幾個Pod
,活動結束后再把多余的Pod
殺掉,雖然有點麻煩,但是應該還是能夠應對這種情況的。
第二種情況,可能某天夜里收到大量報警說服務掛了,然后起來打開電腦在另外的節點上重新啟動一個新的Pod
,問題也很好的解決了。
如果我們都人工的去解決遇到的這些問題,似乎又回到了以前刀耕火種的時代了是吧,如果有一種工具能夠來幫助我們管理Pod
就好了,Pod
不夠了自動幫我新增一個,Pod
掛了自動幫我在合適的節點上重新啟動一個Pod
,這樣是不是遇到上面的問題我們都不需要手動去解決了。
幸運的是,Kubernetes
就為我們提供了這樣的資源對象:
- Replication Controller:用來部署、升級
Pod
- Replica Set:下一代的
Replication Controller
- Deployment:可以更加方便的管理
Pod
和Replica Set
Replication Controller(RC)
Replication Controller
簡稱RC
,RC
是Kubernetes
系統中的核心概念之一,簡單來說,RC
可以保證在任意時間運行Pod
的副本數量,能夠保證Pod
總是可用的。如果實際Pod
數量比指定的多那就結束掉多余的,如果實際數量比指定的少就新啟動一些Pod
,當Pod
失敗、被刪除或者掛掉后,RC
都會去自動創建新的Pod
來保證副本數量,所以即使只有一個Pod
,我們也應該使用RC
來管理我們的Pod
。
我們想想如果現在我們遇到上面的問題的話,可能除了第一個不能做到完全自動化,其余的我們是不是都不用擔心了,運行Pod
的節點掛了,RC
檢測到Pod
失敗了,就會去合適的節點重新啟動一個Pod
就行,不需要我們手動去新建一個Pod
了。如果是第一種情況的話在活動開始之前我們給Pod
指定10個副本,結束后將副本數量改成2,這樣是不是也遠比我們手動去啟動、手動去關閉要好得多,而且我們后面還會給大家介紹另外一種資源對象HPA
可以根據資源的使用情況來進行自動擴縮容,這樣以后遇到這種情況,我們就真的可以安心的去睡覺了。
現在我們來使用RC
來管理我們前面使用的Nginx
的Pod
,YAML
文件如下:
apiVersion: v1
kind: ReplicationController
metadata:
name: rc-demo
labels:
name: rc
spec:
replicas: 3
selector:
name: rc
template:
metadata:
labels:
name: rc
spec:
containers:
- name: nginx-demo
image: nginx
ports:
- containerPort: 80
上面的YAML
文件相對於我們之前的Pod
的格式:
- kind:
ReplicationController
- spec.replicas: 指定
Pod
副本數量,默認為1 - spec.selector:
RC
通過該屬性來篩選要控制的Pod
- spec.template: 這里就是我們之前的
Pod
的定義的模塊,但是不需要apiVersion
和kind
了 - spec.template.metadata.labels: 注意這里的
Pod
的labels
要和spec.selector
相同,這樣RC
就可以來控制當前這個Pod
了。
這個YAML
文件中的意思就是定義了一個RC
資源對象,它的名字叫rc-demo
,保證一直會有3個Pod
運行,Pod
的鏡像是nginx
鏡像。
注意
spec.selector
和spec.template.metadata.labels
這兩個字段必須相同,否則會創建失敗的,當然我們也可以不寫spec.selector
,這樣就默認與Pod
模板中的metadata.labels
相同了。所以為了避免不必要的錯誤的話,不寫為好。
然后我們來創建上面的RC
對象(保存為 rc-demo.yaml):
$ kubectl create -f rc-demo.yaml
查看RC
:
$ kubectl get rc
查看具體信息:
$ kubectl describe rc rc-demo
然后我們通過RC
來修改下Pod
的副本數量為2:
$ kubectl apply -f rc-demo.yaml
或者
$ kubectl edit rc rc-demo
而且我們還可以用RC
來進行滾動升級,比如我們將鏡像地址更改為nginx:1.7.9
:
$ kubectl rolling-update rc-demo --image=nginx:1.7.9
但是如果我們的Pod
中多個容器的話,就需要通過修改YAML
文件來進行修改了:
$ kubectl rolling-update rc-demo -f rc-demo.yaml
如果升級完成后出現了新的問題,想要一鍵回滾到上一個版本的話,使用RC
只能用同樣的方法把鏡像地址替換成之前的,然后重新滾動升級。
Replication Set(RS)
Replication Set
簡稱RS
,隨着Kubernetes
的高速發展,官方已經推薦我們使用RS
和Deployment
來代替RC
了,實際上RS
和RC
的功能基本一致,目前唯一的一個區別就是RC
只支持基於等式的selector
(env=dev或environment!=qa),但RS
還支持基於集合的selector
(version in (v1.0, v2.0)),這對復雜的運維管理就非常方便了。
kubectl
命令行工具中關於RC
的大部分命令同樣適用於我們的RS
資源對象。不過我們也很少會去單獨使用RS
,它主要被Deployment
這個更加高層的資源對象使用,除非用戶需要自定義升級功能或根本不需要升級Pod
,在一般情況下,我們推薦使用Deployment
而不直接使用Replica Set
。
最后我們總結下關於RC
/RS
的一些特性和作用吧:
- 大部分情況下,我們可以通過定義一個
RC
實現的Pod
的創建和副本數量的控制 RC
中包含一個完整的Pod
定義模塊(不包含apiversion
和kind
)RC
是通過label selector
機制來實現對Pod
副本的控制的- 通過改變
RC
里面的Pod
副本數量,可以實現Pod
的擴縮容功能 - 通過改變
RC
里面的Pod
模板中鏡像版本,可以實現Pod
的滾動升級功能(但是不支持一鍵回滾,需要用相同的方法去修改鏡像地址)
好,這節課我們就給大家介紹了使用RC
或者RS
來管理我們的Pod
,我們下節課來給大家介紹另外一種更加高級也是現在推薦使用的一個資源對象Deployment
。