Kubernetes全棧架構師(資源調度上)--學習筆記


目錄

  • Replication Controller和ReplicaSet
  • 無狀態服務Deployment概念
  • Deployment的創建
  • Deployment的更新
  • Deployment的回滾
  • Deployment擴容和縮容
  • Deployment更新暫停和恢復
  • Deployment更新注意事項
  • 有狀態應用管理StatefulSet概念
  • 創建一個StatefulSet應用

Replication Controller和ReplicaSet

Replication Controller(復制控制器,RC)和ReplicaSet(復制集,RS)是兩種簡單部署Pod的方式。在生產環境中,主要使用更高級的Deployment等方式進行Pod的管理和部署。

  • Replication Controller
  • ReplicaSet

Replication Controller

Replication Controller(簡稱RC)可確保Pod副本數達到期望值,也就是RC定義的數量。換句話說,Replication Controller可確保一個Pod或一組同類Pod總是可用。

如果存在的Pod大於設定的值,則Replication Controller將終止額外的Pod。如果太小,Replication Controller將啟動更多的Pod用於保證達到期望值。與手動創建Pod不同的是,用Replication Controller維護的Pod在失敗、刪除或終止時會自動替換。因此即使應用程序只需要一個Pod,也應該使用Replication Controller或其他方式管理。Replication Controller類似於進程管理程序,但是Replication Controller不是監視單個節點上的各個進程,而是監視多個節點上的多個Pod。

定義一個Replication Controller的示例如下。

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

ReplicaSet

ReplicaSet是支持基於集合的標簽選擇器的下一代Replication Controller,它主要用作Deployment協調創建、刪除和更新Pod,和Replication Controller唯一的區別是,ReplicaSet支持標簽選擇器。在實際應用中,雖然ReplicaSet可以單獨使用,但是一般建議使用Deployment來自動管理ReplicaSet,除非自定義的Pod不需要更新或有其他編排等。

定義一個ReplicaSet的示例如下:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
    matchExpressions:
      - {key: tier, operator: In, values: [frontend]}
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below.
          # value: env
        ports:
        - containerPort: 80

查看一下使用Deployment來自動管理ReplicaSet

[root@k8s-master01 ~]# kubectl get deploy -n kube-system
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
metrics-server            1/1     1            1           2d
[root@k8s-master01 ~]# kubectl get deploy -n kube-system metrics-server -oyaml
message: ReplicaSet "metrics-server-64c6c494dc" has successfully progressed.

查看ReplicaSet

[root@k8s-master01 ~]# kubectl get rs -n kube-system
NAME                                DESIRED   CURRENT   READY   AGE
metrics-server-64c6c494dc           1         1         1       2d

如果我們改動了一個參數,做了滾動升級,它就會重新生成一個rs,這個rs可以被回滾,而rc是不支持回滾的,我們一般使用高級的功能比如Deployment和DaemonSet去管理我們的rc或rs,再通過rs管理我們的pod

Replication Controller和ReplicaSet的創建刪除和Pod並無太大區別,Replication Controller目前幾乎已經不在生產環境中使用,ReplicaSet也很少單獨被使用,都是使用更高級的資源Deployment、DaemonSet、StatefulSet進行管理Pod。

無狀態服務Deployment概念

用於部署無狀態的服務,這個最常用的控制器。一般用於管理維護企業內部無狀態的微服務,比如configserver、zuul、springboot。他可以管理多個副本的Pod實現無縫遷移、自動擴容縮容、自動災難恢復、一鍵回滾等功能。

Deployment的創建

手動創建

[root@k8s-master01 ~]# kubectl create deployment nginx --image=nginx:1.15.2
deployment.apps/nginx created

導出到nginx-deploy.yaml

[root@k8s-master01 ~]# kubectl get deployment nginx -o yaml > nginx-deploy.yaml

查看nginx-deploy.yaml

[root@k8s-master01 ~]# vim nginx-deploy.yaml 

刪除status以下的內容,修改副本數

replicas: 2 #副本數

更新配置

[root@k8s-master01 ~]# kubectl replace -f nginx-deploy.yaml
deployment.apps/nginx replaced

查看副本數

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-66bbc9fdc5-vtk4n   1/1     Running   0          16m
nginx-66bbc9fdc5-x87z5   1/1     Running   0          34s

以上是使用文件的方式管理,也可以使用edit

[root@k8s-master01 ~]# kubectl edit deploy nginx
# 把副本數改回1
replicas: 1

查看副本數

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-66bbc9fdc5-vtk4n   1/1     Running   0          19m

查看文件

[root@k8s-master01 ~]# cat nginx-deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2021-07-22T08:50:24Z"
  generation: 1
  labels: # Deployment本身的labels
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "1439468"
  uid: f6659adb-7b49-48a5-8db6-fbafa6baa1d7
spec:
  progressDeadlineSeconds: 600
  replicas: 2 # 副本數
  revisionHistoryLimit: 10 # 歷史記錄保留的個數
  selector:
    matchLabels:
      app: nginx # 與下面pod的labels必須保持一致,不然管理不了pod,匹配rs,新版本創建之后不允許修改,修改之后產生新的rs,無法對應舊的label
  strategy:
    rollingUpdate:# 滾動升級的策略
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template: # pod的參數
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.2
        imagePullPolicy: IfNotPresent
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

查看deploy的labels

[root@k8s-master01 ~]# kubectl get deploy --show-labels
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   LABELS
nginx   1/1     1            1           22m   app=nginx

狀態解析

[root@k8s-master01 ~]# kubectl get deploy -owide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
nginx   1/1     1            1           40m   nginx        nginx:1.15.2   app=nginx
  • NAME: Deployment名稱
  • READY:Pod的狀態,已經Ready的個數
  • UP-TO-DATE:已經達到期望狀態的被更新的副本數
  • AVAILABLE:已經可以用的副本數
  • AGE:顯示應用程序運行的時間
  • CONTAINERS:容器名稱
  • IMAGES:容器的鏡像
  • SELECTOR:管理的Pod的標簽

Deployment的更新

修改spec里面的template才會觸發更新

查看鏡像版本

[root@k8s-master01 ~]# kubectl get deploy -oyaml | grep image
        - image: nginx:1.15.2
          imagePullPolicy: IfNotPresent

更改deployment的鏡像並記錄

[root@k8s-master01 ~]# kubectl set image deploy nginx nginx=nginx:1.15.3 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx image updated

查看滾動更新過程

[root@k8s-master01 ~]# kubectl rollout status deploy nginx
deployment "nginx" successfully rolled out

或者使用describe查看

[root@k8s-master01 ~]# kubectl describe deploy nginx
Events:
  Type    Reason             Age                   From                   Message
  ----    ------             ----                  ----                   -------
  Normal  ScalingReplicaSet  8m37s (x2 over 21h)   deployment-controller  Scaled up replica set nginx-66bbc9fdc5 to 1
  Normal  ScalingReplicaSet  8m35s                 deployment-controller  Scaled down replica set nginx-5dfc8689c6 to 0
  Normal  ScalingReplicaSet  7m41s (x2 over 165m)  deployment-controller  Scaled up replica set nginx-5dfc8689c6 to 1
  Normal  ScalingReplicaSet  7m39s (x2 over 165m)  deployment-controller  Scaled down replica set nginx-66bbc9fdc5 to 0

查看rs

[root@k8s-master01 ~]# kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
nginx-5dfc8689c6   1         1         1       165m
nginx-66bbc9fdc5   0         0         0       21h

滾動更新的策略是:先啟動一個新的rs,將副本數設置為1,再把舊的刪掉一個,然后再啟動一個新的

查看滾動更新策略配置

[root@k8s-master01 ~]# vim nginx-deploy.yaml 
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdat

Deployment的回滾

更新deploy鏡像

[root@k8s-master01 ~]# kubectl set image deploy nginx nginx=nginx:787977da --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx image updated

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS         RESTARTS   AGE
nginx-5dfc8689c6-ww9v4   1/1     Running        0          17m
nginx-7d79b96f68-m94sh   0/1     ErrImagePull   0          12s

查看歷史版本

[root@k8s-master01 ~]# kubectl rollout history deploy nginx
deployment.apps/nginx 
REVISION  CHANGE-CAUSE
3         kubectl set image deploy nginx nginx=nginx:1.15.3 --record=true
4         kubectl set image deploy nginx nginx=nginx:1.15.3 --record=true
5         kubectl set image deploy nginx nginx=nginx:787977da --record=true

回滾到上一個版本

[root@k8s-master01 ~]# kubectl rollout undo deploy nginx
deployment.apps/nginx rolled back

查看pod,可以看到只剩一個

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-5dfc8689c6-ww9v4   1/1     Running   0          20m

進行多次更新

[root@k8s-master01 ~]# kubectl set image deploy nginx nginx=nginx:787977da --record
deployment.apps/nginx image updated
[root@k8s-master01 ~]# kubectl set image deploy nginx nginx=nginx:787977dadaa --record
deployment.apps/nginx image updated
[root@k8s-master01 ~]# kubectl set image deploy nginx nginx=nginx:787977xxxxxdadaa --record
deployment.apps/nginx image updated

查看歷史記錄

[root@k8s-master01 ~]# kubectl rollout history deploy nginx
deployment.apps/nginx 
REVISION  CHANGE-CAUSE
3         kubectl set image deploy nginx nginx=nginx:1.15.3 --record=true
6         kubectl set image deploy nginx nginx=nginx:1.15.3 --record=true
7         kubectl set image deploy nginx nginx=nginx:787977da --record=true
8         kubectl set image deploy nginx nginx=nginx:787977dadaa --record=true
9         kubectl set image deploy nginx nginx=nginx:787977xxxxxdadaa --record=true

查看指定版本的詳細信息

[root@k8s-master01 ~]# kubectl rollout history deploy nginx --revision=6
deployment.apps/nginx with revision #6
Pod Template:
  Labels:	app=nginx
	pod-template-hash=5dfc8689c6
  Annotations:	kubernetes.io/change-cause: kubectl set image deploy nginx nginx=nginx:1.15.3 --record=true
  Containers:
   nginx:
    Image:	nginx:1.15.3
    Port:	<none>
    Host Port:	<none>
    Environment:	<none>
    Mounts:	<none>
  Volumes:	<none>

回滾到執行的版本

[root@k8s-master01 ~]# kubectl rollout undo deploy nginx --to-revision=6
deployment.apps/nginx rolled back

查看deploy狀態

[root@k8s-master01 ~]# kubectl get deploy -oyaml

Deployment擴容和縮容

擴容

[root@k8s-master01 ~]# kubectl scale --replicas=3 deploy nginx
deployment.apps/nginx scaled

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-5dfc8689c6-nhplc   1/1     Running   0          41s
nginx-5dfc8689c6-ww9v4   1/1     Running   0          72m
nginx-5dfc8689c6-xh9l6   1/1     Running   0          41s

縮容

[root@k8s-master01 ~]# kubectl scale --replicas=2 deploy nginx
deployment.apps/nginx scaled

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS        RESTARTS   AGE
nginx-5dfc8689c6-nhplc   1/1     Running       0          2m1s
nginx-5dfc8689c6-ww9v4   1/1     Running       0          73m
nginx-5dfc8689c6-xh9l6   0/1     Terminating   0          2m1s

NAME                     READY   STATUS    RESTARTS   AGE
nginx-5dfc8689c6-nhplc   1/1     Running   0          2m17s
nginx-5dfc8689c6-ww9v4   1/1     Running   0          73m

Deployment更新暫停和恢復

使用edit命令可以修改多個配置,再一次性更新,但是通過set命令,每次都會觸發更新,那么該如何做呢?可以使用Deployment更新暫停功能

[root@k8s-master01 ~]# kubectl rollout pause deployment nginx
deployment.apps/nginx paused

使用set命令修改配置

[root@k8s-master01 ~]# kubectl set image deploy nginx nginx=nginx:1.15.3 --record
Flag --record has been deprecated, --record will be removed in the future

# 進行第二次配置變更,添加內存CPU配置
[root@k8s-master01 ~]# kubectl set resources deploy nginx -c nginx --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi
deployment.apps/nginx resource requirements updated

查看deploy

[root@k8s-master01 ~]# kubectl get deploy nginx -oyaml
        resources:
          limits:# 容器最大的CPU和內容容量
            cpu: 200m
            memory: 128Mi
          requests: # 容器啟動最小的CPU和內容容量
            cpu: 10m
            memory: 16Mi

查看pod是否被更新

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-5dfc8689c6-nhplc   1/1     Running   0          22m
nginx-5dfc8689c6-ww9v4   1/1     Running   0          93m

可以看到pod沒有更新

更新恢復

[root@k8s-master01 ~]# kubectl rollout resume deploy nginx
deployment.apps/nginx resumed

查看rs

[root@k8s-master01 ~]# kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
nginx-5475c49ffb   0         0         0       71m
nginx-5dfc8689c6   0         0         0       4h12m
nginx-66bbc9fdc5   0         0         0       23h
nginx-68db656dd8   2         2         2       32s
nginx-799b8478d4   0         0         0       71m
nginx-7d79b96f68   0         0         0       77m

可以看到32s前新增了nginx的rs,更新被恢復就可以創建新的容器了

Deployment更新注意事項

查看deploy

[root@k8s-master01 ~]# kubectl get deploy nginx -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "11"
    kubernetes.io/change-cause: kubectl set image deploy nginx nginx=nginx:1.15.3
      --record=true
  creationTimestamp: "2021-07-22T08:50:24Z"
  generation: 20
  labels:
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "1588198"
  uid: f6659adb-7b49-48a5-8db6-fbafa6baa1d7
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10 # 設置保留RS舊的revision的個數,設置為0的話,不保留歷史數據
  selector:
    matchLabels:
      app: nginx
  strategy: # 滾動更新的策略
    rollingUpdate:
      maxSurge: 25% # 可以超過期望值的最大Pod數,可選字段,默認為25%,可以設置成數字或百分比,如果該值為0,那么maxUnavailable不能為0
      maxUnavailable: 25% # 指定在回滾或更新時最大不可用的Pod的數量,可選字段,默認25%,可以設置成數字或百分比,如果該值為0,那么maxSurge就不能0
    type: RollingUpdate # 更新deployment的方式,默認是RollingUpdate,滾動更新,可以指定maxSurge和maxUnavailable
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.3
        imagePullPolicy: IfNotPresent
        name: nginx
        resources:
          limits:
            cpu: 200m
            memory: 128Mi
          requests:
            cpu: 10m
            memory: 16Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 2
  conditions:
  - lastTransitionTime: "2021-07-23T07:48:01Z"
    lastUpdateTime: "2021-07-23T07:48:01Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2021-07-23T08:10:50Z"
    lastUpdateTime: "2021-07-23T08:10:53Z"
    message: ReplicaSet "nginx-68db656dd8" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 20
  readyReplicas: 2
  replicas: 2
  updatedReplicas: 2

.spec.minReadySeconds:可選參數,指定新創建的Pod在沒有任何容器崩潰的情況下視為Ready最小的秒數,默認為0,即一旦被創建就視為可用。

.spec.strategy.type Recreate:重建,先刪除舊的Pod,在創建新的Pod

有狀態應用管理StatefulSet概念

  • StatefulSet的基本概念
  • StatefulSet注意事項

StatefulSet(有狀態集,縮寫為sts)常用於部署有狀態的且需要有序啟動的應用程序,比如在進行SpringCloud項目容器化時,Eureka的部署是比較適合用StatefulSet部署方式的,可以給每個Eureka實例創建一個唯一且固定的標識符,並且每個Eureka實例無需配置多余的Service,其余Spring Boot應用可以直接通過Eureka的Headless Service即可進行注冊。

  • Eureka的statefulset的資源名稱是eureka,eureka-0 eureka-1 eureka-2
  • Service:headless service,沒有ClusterIP eureka-svc
  • Eureka-0.eureka-svc.NAMESPACE_NAME eureka-1.eureka-svc …

StatefulSet的基本概念

StatefulSet主要用於管理有狀態應用程序的工作負載API對象。比如在生產環境中,可以部署ElasticSearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、Kafka集群和ZooKeeper集群等。

和Deployment類似,一個StatefulSet也同樣管理着基於相同容器規范的Pod。不同的是,StatefulSet為每個Pod維護了一個粘性標識。這些Pod是根據相同的規范創建的,但是不可互換,每個Pod都有一個持久的標識符,在重新調度時也會保留,一般格式為StatefulSetName-Number。比如定義一個名字是Redis-Sentinel的StatefulSet,指定創建三個Pod,那么創建出來的Pod名字就為Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。而StatefulSet創建的Pod一般使用Headless Service(無頭服務)進行通信,和普通的Service的區別在於Headless Service沒有ClusterIP,它使用的是Endpoint進行互相通信,Headless一般的格式為:

statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
  • serviceName為Headless Service的名字,創建StatefulSet時,必須指定Headless Service名稱;
  • 0..N-1為Pod所在的序號,從0開始到N-1;
  • statefulSetName為StatefulSet的名字;
  • namespace為服務所在的命名空間;
  • .cluster.local為Cluster Domain(集群域)。

假如公司某個項目需要在Kubernetes中部署一個主從模式的Redis,此時使用StatefulSet部署就極為合適,因為StatefulSet啟動時,只有當前一個容器完全啟動時,后一個容器才會被調度,並且每個容器的標識符是固定的,那么就可以通過標識符來斷定當前Pod的角色。

比如用一個名為redis-ms的StatefulSet部署主從架構的Redis,第一個容器啟動時,它的標識符為redis-ms-0,並且Pod內主機名也為redis-ms-0,此時就可以根據主機名來判斷,當主機名為redis-ms-0的容器作為Redis的主節點,其余從節點,那么Slave連接Master主機配置就可以使用不會更改的Master的Headless Service,此時Redis從節點(Slave)配置文件如下:

port 6379
slaveof redis-ms-0.redis-ms.public-service.svc.cluster.local 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
……

其中redis-ms-0.redis-ms.public-service.svc.cluster.local是Redis Master的Headless Service,在同一命名空間下只需要寫redis-ms-0.redis-ms即可,后面的public-service.svc.cluster.local可以省略。

StatefulSet注意事項

一般StatefulSet用於有以下一個或者多個需求的應用程序:

  • 需要穩定的獨一無二的網絡標識符。
  • 需要持久化數據。
  • 需要有序的、優雅的部署和擴展。
  • 需要有序的自動滾動更新。

如果應用程序不需要任何穩定的標識符或者有序的部署、刪除或者擴展,應該使用無狀態的控制器部署應用程序,比如Deployment或者ReplicaSet。

StatefulSet是Kubernetes 1.9版本之前的beta資源,在1.5版本之前的任何Kubernetes版本都沒有。

Pod所用的存儲必須由PersistentVolume Provisioner(持久化卷配置器)根據請求配置StorageClass,或者由管理員預先配置,當然也可以不配置存儲。

為了確保數據安全,刪除和縮放StatefulSet不會刪除與StatefulSet關聯的卷,可以手動選擇性地刪除PVC和PV

StatefulSet目前使用Headless Service(無頭服務)負責Pod的網絡身份和通信,需要提前創建此服務。

刪除一個StatefulSet時,不保證對Pod的終止,要在StatefulSet中實現Pod的有序和正常終止,可以在刪除之前將StatefulSet的副本縮減為0。

創建一個StatefulSet應用

  • 定義一個StatefulSet資源文件
  • 創建一個StatefulSet

定義一個StatefulSet資源文件

[root@k8s-master01 ~]# vim nginx-sts.yaml
# 添加以下內容
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx" # StatefulSet必須配置一個serviceName,它指向已經存在的service,上面定義
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.2
        ports:
        - containerPort: 80
          name: web
  • kind: Service定義了一個名字為Nginx的Headless Service,創建的Service格式為nginx-0.nginx.default.svc.cluster.local,其他的類似,因為沒有指定Namespace(命名空間),所以默認部署在default。
  • kind: StatefulSet定義了一個名字為web的StatefulSet,replicas表示部署Pod的副本數,本實例為2。

在StatefulSet中必須設置Pod選擇器(.spec.selector)用來匹配其標簽(.spec.template.metadata.labels)。在1.8版本之前,如果未配置該字段(.spec.selector),將被設置為默認值,在1.8版本之后,如果未指定匹配Pod Selector,則會導致StatefulSet創建錯誤。

當StatefulSet控制器創建Pod時,它會添加一個標簽statefulset.kubernetes.io/pod-name,該標簽的值為Pod的名稱,用於匹配Service。

創建一個StatefulSet

[root@k8s-master01 ~]# kubectl create -f nginx-sts.yaml
service/nginx created
statefulset.apps/web created

查看pod

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
web-0                    1/1     Running   0          5s
web-1                    1/1     Running   0          3s

查看service

[root@k8s-master01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   14d
nginx        ClusterIP   None         <none>        80/TCP    52s

擴容sts

[root@k8s-master01 ~]# kubectl scale --replicas=3 sts web
statefulset.apps/web scaled

查看pod

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
web-0                    1/1     Running   0          2m21s
web-1                    1/1     Running   0          2m19s
web-2                    1/1     Running   0          14s

新增busybox,解析無頭service

cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
EOF

驗證StatefulSet

[root@k8s-master01 ~]# kubectl exec -ti busybox -- sh
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # nslookup web-0.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 172.25.244.242 web-0.nginx.default.svc.cluster.local
/ # exit

獲取pod的IP

[root@k8s-master01 ~]# kubectl get po -owide
NAME                     READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
busybox                  1/1     Running   0          3m34s   172.25.244.245   k8s-master01   <none>           <none>
nginx-68db656dd8-2dv8l   1/1     Running   0          106m    172.25.244.241   k8s-master01   <none>           <none>
nginx-68db656dd8-8lcrk   1/1     Running   0          106m    172.25.244.240   k8s-master01   <none>           <none>
web-0                    1/1     Running   0          9m3s    172.25.244.242   k8s-master01   <none>           <none>
web-1                    1/1     Running   0          9m1s    172.25.244.243   k8s-master01   <none>           <none>
web-2                    1/1     Running   0          6m56s   172.25.244.244   k8s-master01   <none>           <none>

可以看到它直接把service地址解析成pod的IP,不通過service訪問,直接通過IP訪問,減少了一層代理,性能更高,所以不需要配置clusterIP

  clusterIP: None

課程鏈接

http://www.kubeasy.com/

知識共享許可協議

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。

歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含鏈接: http://www.cnblogs.com/MingsonZheng/ ),不得用於商業目的,基於本文修改后的作品務必以相同的許可發布。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM