k8s 實戰 4----副本集

王若伊_恩赐解脱發表於2024-12-10

副本集是什麼?
我們在前文中講過什麼是pod,簡單來說pod就是k8s直接操作的基本單位。
不瞭解的同學可以參考前文:

k8s 實戰 1 ---- 初識 (https://www.cnblogs.com/jilodream/p/18245222)
k8s 實戰 2 ---- pod 基礎 (https://www.cnblogs.com/jilodream/p/18284282)
k8s 實戰 3 ---- 標籤(https://www.cnblogs.com/jilodream/p/18293278 )

如果只是有pod,基本是可以滿足我們普通開發學習的,但是這和我們直接使用docker容器區別就不是很大了,要知道k8s要做的事情就是提供一整套的管理部署系統,如果僅僅就是操作幾個pod,就有點大材小用了。
因此我們必須要學習一些更高階的資源,才能利用到k8s提供的各種能力。比如副本集 ReplicaSet,部署Deployment等。
今天我們來學習和使用下副本集 ReplicaSet
replica 美[ˈreplɪkə] 複製品;仿製品;

ReplcaSet字面意思就是複製品的集合,我們一般譯作副本集。
通常來說,為了高可用,我們會對每個微服務建立多個例項,
為了管理方便,每個例項通常對應一個容器,(防盜連線:本文首發自http://www.cnblogs.com/jilodream/ )每個容器又常常對應一個pod,多個例項實際上對應的就是多個pod。在此基礎上,k8s定義了一種更高階的資源稱之為ReplicaSet,為的就是管理這個pod集合(副本集合)。
比如我們要建立3個kuard服務的副本集,我們應該如何透過副本集建立呢?
和直接定義pod一樣,我們可以直接定義一個yaml模板,透過模板來宣告我們要定義的副本集的各項特性
如下:

 1 apiVersion: apps/v1
 2 kind: ReplicaSet
 3 metadata:
 4   name: kuardrs
 5 spec:
 6   replicas: 2
 7   selector:
 8     matchLabels:
 9       appRs: kuardrs
10   template:
11     metadata:
12       labels:
13         appRs: kuardrs
14         version: "2"
15     spec:
16       containers:
17         - ports:
18             - containerPort: 80
19           name: kuardpod1
20           image: "docker.io/library/kuard-amd64:blue"

這就是一個標準的ReplicaSet 模板。

和pod模板一樣,我們依次來看每個鍵的含義:
首先是apiVersion 表示當前選定的版本
kind 表示型別,我們的型別是ReplicaSet,也就是副本集
metadata 表示後設資料,在這裡我們定義新建的副本集名稱叫:kuardrs
spec 表示特性,在這裡我們定義副本集的一些內部特性資訊:
spec.replicas 表示副本集中副本的個數
spec.selector 表示副本集匹配的標籤,也稱之為標籤選擇器。這個需要詳細說說。在前一節中,我們已經知道了什麼是標籤,它可以理解為定義到資源上邊的一系列kv值,我們可以用標籤進行匹配和篩選資源。
而我們建立的副本集和pod,或者說未來的Deployment和副本集之間,都是松耦合的,並不是直接依賴的關係。換句話說建立好副本集之後,你可以隨便增刪pod,副本集本身是不會受影響的。但是副本集會透過標籤,感知到當前所管理的pod是否符合自己的要求,
當它發現多出來了匹配的pod,就會嘗試刪除pod。當它發現匹配到的pod,少於自己要求的pod時,就會嘗試新增pod。因此直接說副本集是pod的一個集合其實並不貼切,更準確的說法應該是,副本集是用來定義和規範pod集合的一個更高維度的資源。
而我們平常發現某一個pod執行的有一些問題時,又不想直接刪除pod,又不想生產環境繼續持有一個有問題的pod,我們就可以直接修改pod的標籤,將pod從副本集管理範圍中,剝離出來。然後再圍繞有問題的pod進一步研究。
而這些pod對於副本集來說,都是無狀態的,替換誰都可以,只要符合副本集的標籤匹配要求就可以。就像下邊這個樣子:

在本示例中,selector所匹配的資源就是符合標籤:appRs: kuardrs 的pod。注意這裡用matchLabels進行了匹配。
spec.template是pod的模板定義,其中我們分別有pod後設資料以及pod特性等節點。
我們在pod的metadata節點中定義了pod要持有的兩個標籤(防盜連線:本文首發自http://www.cnblogs.com/jilodream/ ):
appRs: kuardrs
version: "2"

在pod的spec特性節點中定義了pod中容器的映象、名稱、埠等。
template中pod的定義和前文中宣告pod基本類似,有興趣的同學一定要看下前文,這裡就不過多的贅述了。
總而言之定義好的pod,包含容器、標籤等資訊,而我們定好的副本集又指定了要篩選的標籤的資訊,兩者就透過標籤很鬆散的連線到了一起。

定義好了副本集的yaml檔案之後,我們來看看副本集的常規操作
建立副本集

kubectl apply -f xxx.yaml xxx.yaml檔案是副本集的宣告檔案
執行效果如下:

[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl apply -f kuard-rs.yaml 
replicaset.apps/kuardrs created

檢視副本集

kubectl get replicaset ,注意replicaset也可以是replicasets/rs (以下不再重複),
執行效果如下,這裡查到的副本集就是剛剛建立的副本集:

[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl get replicaset
NAME      DESIRED   CURRENT   READY   AGE
kuardrs   2         2         2       57s

檢視副本集詳情

k describe replicasets xxx xxx 是副本集名稱
執行效果如下:

[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl describe replicaset kuardrs
Name:         kuardrs
Namespace:    default
Selector:     appRs=kuardrs
Labels:       <none>
Annotations:  <none>
Replicas:     2 current / 2 desired
Pods Status:  2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  appRs=kuardrs
           version=2
  Containers:
   kuardpod1:
    Image:        docker.io/library/kuard-amd64:blue
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  3m30s  replicaset-controller  Created pod: kuardrs-q8ghw
  Normal  SuccessfulCreate  3m30s  replicaset-controller  Created pod: kuardrs-wd29m

我們可以從詳情中看到副本集定義的各種屬性和模板。以及關聯出的pod的一些相關資訊。

有時我們還需要根據pod反向的找到它屬於哪個副本集,此時可以透過pod 中的yaml 檔案查詢到對應建立的副本集

在鍵ownerReferences下邊可以看到,如下:

[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl get pod
NAME            READY   STATUS    RESTARTS   AGE
kuardrs-q8ghw   1/1     Running   0          4m23s
kuardrs-wd29m   1/1     Running   0          4m23s
[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl get pod kuardrs-q8ghw  -o yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/containerID: 619b5de35bedd683352ce58bab8e6efd03e79fa4495a8ae89bae85f93ac7ed3f
    cni.projectcalico.org/podIP: 192.168.240.165/32
    cni.projectcalico.org/podIPs: 192.168.240.165/32
  creationTimestamp: "2024-12-10T07:13:15Z"
  generateName: kuardrs-
  labels:
    appRs: kuardrs
    version: "2"
  name: kuardrs-q8ghw
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: kuardrs
    uid: 8a91c42a-864a-4172-8653-373210a59eaa
  resourceVersion: "28299737"
  uid: 587be9bd-2d0a-402b-a3a4-72edbc3170db
spec:
  containers:
  - image: docker.io/library/kuard-amd64:blue
    imagePullPolicy: IfNotPresent
....省略....

如果我們想調整副本的數量或者其他屬性

我們可以透過
(1)k edit rs xxx , xxx是副本集的名稱
(2)k apply -f xxx.yaml ,xxx.yaml檔案是副本集的宣告檔案
(3)k scale rs xxx --replicas=新副本數量 ,xxx是副本集名稱

我們直接展示最後一種(防盜連線:本文首發自http://www.cnblogs.com/jilodream/ )執行效果:

[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl get pod 
NAME            READY   STATUS    RESTARTS   AGE
kuardrs-q8ghw   1/1     Running   0          9m19s
kuardrs-wd29m   1/1     Running   0          9m19s
[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl scale rs kuardrs --replicas=3
replicaset.apps/kuardrs scaled
[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl get pod 
NAME            READY   STATUS    RESTARTS   AGE
kuardrs-lhgtc   1/1     Running   0          8s
kuardrs-q8ghw   1/1     Running   0          10m
kuardrs-wd29m   1/1     Running   0          10m

刪除副本集

k delete rs xxx ,xxx是副本集的名稱

[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl get rs
NAME      DESIRED   CURRENT   READY   AGE
kuardrs   3         3         3       29m
[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl delete rs kuardrs
replicaset.apps "kuardrs" deleted
[root@iZ2ze3bpa0o5cw6gp42ry2Z learnRs]# kubectl get rs
No resources found in default namespace.

相關文章