日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
創(chuàng)新互聯(lián)kubernetes教程:KubernetesStatefulSet基礎(chǔ)

StatefulSet 基礎(chǔ)

本教程介紹了如何使用 StatefulSet 來(lái)管理應(yīng)用。 演示了如何創(chuàng)建、刪除、擴(kuò)容/縮容和更新 StatefulSet 的 Pod。

創(chuàng)新互聯(lián)主打移動(dòng)網(wǎng)站、成都網(wǎng)站制作、做網(wǎng)站、網(wǎng)站改版、網(wǎng)絡(luò)推廣、網(wǎng)站維護(hù)、國(guó)際域名空間、等互聯(lián)網(wǎng)信息服務(wù),為各行業(yè)提供服務(wù)。在技術(shù)實(shí)力的保障下,我們?yōu)榭蛻舫兄Z穩(wěn)定,放心的服務(wù),根據(jù)網(wǎng)站的內(nèi)容與功能再?zèng)Q定采用什么樣的設(shè)計(jì)。最后,要實(shí)現(xiàn)符合網(wǎng)站需求的內(nèi)容、功能與設(shè)計(jì),我們還會(huì)規(guī)劃穩(wěn)定安全的技術(shù)方案做保障。

在開(kāi)始之前

在開(kāi)始本教程之前,你應(yīng)該熟悉以下 Kubernetes 的概念:

  • Pods
  • Cluster DNS
  • Headless Services
  • PersistentVolumes
  • PersistentVolume Provisioning
  • StatefulSets
  • kubectl 命令行工具

說(shuō)明:

本教程假設(shè)你的集群被配置為動(dòng)態(tài)制備 PersistentVolume 卷。 如果沒(méi)有這樣配置,在開(kāi)始本教程之前,你需要手動(dòng)準(zhǔn)備 2 個(gè) 1 GiB 的存儲(chǔ)卷。

教程目標(biāo)

StatefulSet 旨在與有狀態(tài)的應(yīng)用及分布式系統(tǒng)一起使用。然而在 Kubernetes 上管理有狀態(tài)應(yīng)用和分布式系統(tǒng)是一個(gè)寬泛而復(fù)雜的話題。 為了演示 StatefulSet 的基本特性,并且不使前后的主題混淆,你將會(huì)使用 StatefulSet 部署一個(gè)簡(jiǎn)單的 web 應(yīng)用。

在閱讀本教程后,你將熟悉以下內(nèi)容:

  • 如何創(chuàng)建 StatefulSet
  • StatefulSet 怎樣管理它的 Pod
  • 如何刪除 StatefulSet
  • 如何對(duì) StatefulSet 進(jìn)行擴(kuò)容/縮容
  • 如何更新一個(gè) StatefulSet 的 Pod

創(chuàng)建 StatefulSet

作為開(kāi)始,使用如下示例創(chuàng)建一個(gè) StatefulSet。它和 StatefulSet 概念中的示例相似。 它創(chuàng)建了一個(gè) Headless Service ?nginx ?用來(lái)發(fā)布 StatefulSet ?web ?中的 Pod 的 IP 地址。

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"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: K8S.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

下載上面的例子并保存為文件 ?web.yaml?。

你需要使用兩個(gè)終端窗口。在第一個(gè)終端中,使用 ?kubectl get? 來(lái)監(jiān)視 StatefulSet 的 Pod 的創(chuàng)建情況。

kubectl get pods -w -l app=nginx

在另一個(gè)終端中,使用 ?kubectl apply? 來(lái)創(chuàng)建定義在 ?web.yaml? 中的 Headless Service 和 StatefulSet。

kubectl apply -f web.yaml
service/nginx created
statefulset.apps/web created

上面的命令創(chuàng)建了兩個(gè) Pod,每個(gè)都運(yùn)行了一個(gè) NginX Web 服務(wù)器。 獲取 ?nginx ?Service:

kubectl get service nginx
NAME      TYPE         CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx     ClusterIP    None                 80/TCP    12s

然后獲取 ?web ?StatefulSet,以驗(yàn)證兩者均已成功創(chuàng)建:

kubectl get statefulset web
NAME      DESIRED   CURRENT   AGE
web       2         1         20s

順序創(chuàng)建 Pod 

對(duì)于一個(gè)擁有 n 個(gè)副本的 StatefulSet,Pod 被部署時(shí)是按照 {0..n-1} 的序號(hào)順序創(chuàng)建的。 在第一個(gè)終端中使用 ?kubectl get? 檢查輸出。這個(gè)輸出最終將看起來(lái)像下面的樣子。

kubectl get pods -w -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     0/1       Pending   0          0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         19s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         18s

請(qǐng)注意,直到 ?web-0? Pod 處于 Running 并 Ready 狀態(tài)后,?web-1? Pod 才會(huì)被啟動(dòng)。

StatefulSet 中的 Pod

StatefulSet 中的每個(gè) Pod 擁有一個(gè)唯一的順序索引和穩(wěn)定的網(wǎng)絡(luò)身份標(biāo)識(shí)。

檢查 Pod 的順序索引

獲取 StatefulSet 的 Pod:

kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          1m
web-1     1/1       Running   0          1m

如同 StatefulSet 概念中所提到的, StatefulSet 中的每個(gè) Pod 擁有一個(gè)具有黏性的、獨(dú)一無(wú)二的身份標(biāo)志。 這個(gè)標(biāo)志基于 StatefulSet 控制器分配給每個(gè) Pod 的唯一順序索引。 Pod 的名稱的形式為 ?-<序號(hào)索引>?。 ?web ?StatefulSet 擁有兩個(gè)副本,所以它創(chuàng)建了兩個(gè) Pod:?web-0? 和 ?web-1?。

使用穩(wěn)定的網(wǎng)絡(luò)身份標(biāo)識(shí)

每個(gè) Pod 都擁有一個(gè)基于其順序索引的穩(wěn)定的主機(jī)名。使用 ?kubectl exec? 在每個(gè) Pod 中執(zhí)行 ?hostname?:

for i in 0 1; do kubectl exec "web-$i" -- sh -c 'hostname'; done
web-0
web-1

使用 ?kubectl run? 運(yùn)行一個(gè)提供 ?nslookup ?命令的容器,該命令來(lái)自于 ?dnsutils ?包。 通過(guò)對(duì) Pod 的主機(jī)名執(zhí)行 ?nslookup?,你可以檢查他們?cè)诩簝?nèi)部的 DNS 地址:

kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm

這將啟動(dòng)一個(gè)新的 Shell。在新 Shell 中運(yùn)行:

# Run this in the dns-test container shell
nslookup web-0.nginx

輸出類似于:

Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.244.1.6

nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-1.nginx
Address 1: 10.244.2.6

(現(xiàn)在可以退出容器 Shell:?exit?)

headless service 的 CNAME 指向 SRV 記錄(記錄每個(gè) Running 和 Ready 狀態(tài)的 Pod)。 SRV 記錄指向一個(gè)包含 Pod IP 地址的記錄表項(xiàng)。

在一個(gè)終端中監(jiān)視 StatefulSet 的 Pod:

kubectl get pod -w -l app=nginx

在另一個(gè)終端中使用 ?kubectl delete? 刪除 StatefulSet 中所有的 Pod:

kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted

等待 StatefulSet 重啟它們,并且兩個(gè) Pod 都變成 Running 和 Ready 狀態(tài):

kubectl get pod -w -l app=nginx
NAME      READY     STATUS              RESTARTS   AGE
web-0     0/1       ContainerCreating   0          0s
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          2s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         34s

使用 ?kubectl exec? 和 ?kubectl run? 查看 Pod 的主機(jī)名和集群內(nèi)部的 DNS 表項(xiàng)。 首先,查看 Pod 的主機(jī)名:

for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1

然后,運(yùn)行:

kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm /bin/sh

這將啟動(dòng)一個(gè)新的 Shell。在新 Shell 中,運(yùn)行:

# Run this in the dns-test container shell
nslookup web-0.nginx

輸出類似于:

Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.244.1.7

nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-1.nginx
Address 1: 10.244.2.8

(現(xiàn)在可以退出容器 Shell:?exit?)

Pod 的序號(hào)、主機(jī)名、SRV 條目和記錄名稱沒(méi)有改變,但和 Pod 相關(guān)聯(lián)的 IP 地址可能發(fā)生了改變。 在本教程中使用的集群中它們就改變了。這就是為什么不要在其他應(yīng)用中使用 StatefulSet 中 Pod 的 IP 地址進(jìn)行連接,這點(diǎn)很重要。

如果你需要查找并連接一個(gè) StatefulSet 的活動(dòng)成員,你應(yīng)該查詢 Headless Service 的 CNAME。 和 CNAME 相關(guān)聯(lián)的 SRV 記錄只會(huì)包含 StatefulSet 中處于 Running 和 Ready 狀態(tài)的 Pod。

如果你的應(yīng)用已經(jīng)實(shí)現(xiàn)了用于測(cè)試是否已存活(liveness)并就緒(readiness)的連接邏輯, 你可以使用 Pod 的 SRV 記錄(?web-0.nginx.default.svc.cluster.local?、 ?web-1.nginx.default.svc.cluster.local?)。因?yàn)樗麄兪欠€(wěn)定的,并且當(dāng)你的 Pod 的狀態(tài)變?yōu)?nbsp;Running 和 Ready 時(shí),你的應(yīng)用就能夠發(fā)現(xiàn)它們的地址。

寫入穩(wěn)定的存儲(chǔ)

獲取 ?web-0? 和 ?web-1? 的 PersistentVolumeClaims:

kubectl get pvc -l app=nginx

輸出類似于:

NAME        STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE
www-web-0   Bound     pvc-15c268c7-b507-11e6-932f-42010a800002   1Gi        RWO           48s
www-web-1   Bound     pvc-15c79307-b507-11e6-932f-42010a800002   1Gi        RWO           48s

StatefulSet 控制器創(chuàng)建了兩個(gè) PersistentVolumeClaims, 綁定到兩個(gè) PersistentVolumes。

由于本教程使用的集群配置為動(dòng)態(tài)制備 PersistentVolume 卷,所有的 PersistentVolume 卷都是自動(dòng)創(chuàng)建和綁定的。

NginX Web 服務(wù)器默認(rèn)會(huì)加載位于 ?/usr/share/nginx/html/index.html? 的 index 文件。 StatefulSet ?spec ?中的 ?volumeMounts ?字段保證了 ?/usr/share/nginx/html? 文件夾由一個(gè) PersistentVolume 卷支持。

將 Pod 的主機(jī)名寫入它們的 ?index.html? 文件并驗(yàn)證 NginX Web 服務(wù)器使用該主機(jī)名提供服務(wù):

for i in 0 1; do kubectl exec "web-$i" -- sh -c 'echo "$(hostname)" > /usr/share/nginx/html/index.html'; done

for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1

說(shuō)明:

請(qǐng)注意,如果你看見(jiàn)上面的 curl 命令返回了 
403 Forbidden 的響應(yīng),你需要像這樣修復(fù)使用 ?
volumeMounts ?(原因歸咎于 使用 hostPath 卷時(shí)存在的缺陷) 掛載的目錄的權(quán)限 運(yùn)行:

?
for i in 0 1; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done?

在你重新嘗試上面的 ?
curl ?命令之前。

在一個(gè)終端監(jiān)視 StatefulSet 的 Pod:

kubectl get pod -w -l app=nginx

在另一個(gè)終端刪除 StatefulSet 所有的 Pod:

kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted

在第一個(gè)終端里檢查 ?kubectl get? 命令的輸出,等待所有 Pod 變成 Running 和 Ready 狀態(tài)。

kubectl get pod -w -l app=nginx
NAME      READY     STATUS              RESTARTS   AGE
web-0     0/1       ContainerCreating   0          0s
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          2s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         34s

驗(yàn)證所有 Web 服務(wù)器在繼續(xù)使用它們的主機(jī)名提供服務(wù):

for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1

雖然 ?web-0? 和 ?web-1? 被重新調(diào)度了,但它們?nèi)匀焕^續(xù)監(jiān)聽(tīng)各自的主機(jī)名,因?yàn)楹退鼈兊?nbsp;PersistentVolumeClaim 相關(guān)聯(lián)的 PersistentVolume 卷被重新掛載到了各自的 ?volumeMount ?上。 不管 ?web-0? 和 ?web-1? 被調(diào)度到了哪個(gè)節(jié)點(diǎn)上,它們的 PersistentVolume 卷將會(huì)被掛載到合適的掛載點(diǎn)上。

擴(kuò)容/縮容 StatefulSet

擴(kuò)容/縮容 StatefulSet 指增加或減少它的副本數(shù)。這通過(guò)更新 ?replicas ?字段完成。 你可以使用 ?kubectl scale? 或者 ?kubectl patch? 來(lái)擴(kuò)容/縮容一個(gè) StatefulSet。

擴(kuò)容

在一個(gè)終端窗口監(jiān)視 StatefulSet 的 Pod:

kubectl get pods -w -l app=nginx

在另一個(gè)終端窗口使用 ?kubectl scale? 擴(kuò)展副本數(shù)為 5:

kubectl scale sts web --replicas=5
statefulset.apps/web scaled

在第一個(gè) 終端中檢查 ?kubectl get? 命令的輸出,等待增加的 3 個(gè) Pod 的狀態(tài)變?yōu)?nbsp;Running 和 Ready。

kubectl get pods -w -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          2h
web-1     1/1       Running   0          2h
NAME      READY     STATUS    RESTARTS   AGE
web-2     0/1       Pending   0          0s
web-2     0/1       Pending   0         0s
web-2     0/1       ContainerCreating   0         0s
web-2     1/1       Running   0         19s
web-3     0/1       Pending   0         0s
web-3     0/1       Pending   0         0s
web-3     0/1       ContainerCreating   0         0s
web-3     1/1       Running   0         18s
web-4     0/1       Pending   0         0s
web-4     0/1       Pending   0         0s
web-4     0/1       ContainerCreating   0         0s
web-4     1/1       Running   0         19s

StatefulSet 控制器擴(kuò)展了副本的數(shù)量。StatefulSet 按序號(hào)索引順序創(chuàng)建各個(gè) Pod,并且會(huì)等待前一個(gè) Pod 變?yōu)?nbsp;Running 和 Ready 才會(huì)啟動(dòng)下一個(gè) Pod。

縮容

在一個(gè)終端監(jiān)視 StatefulSet 的 Pod:

kubectl get pods -w -l app=nginx

在另一個(gè)終端使用 ?kubectl patch? 將 StatefulSet 縮容回三個(gè)副本:

kubectl patch sts web -p '{"spec":{"replicas":3}}'
statefulset.apps/web patched

等待 ?web-4? 和 ?web-3? 狀態(tài)變?yōu)?nbsp;Terminating。

kubectl get pods -w -l app=nginx
NAME      READY     STATUS              RESTARTS   AGE
web-0     1/1       Running             0          3h
web-1     1/1       Running             0          3h
web-2     1/1       Running             0          55s
web-3     1/1       Running             0          36s
web-4     0/1       ContainerCreating   0          18s
NAME      READY     STATUS    RESTARTS   AGE
web-4     1/1       Running   0          19s
web-4     1/1       Terminating   0         24s
web-4     1/1       Terminating   0         24s
web-3     1/1       Terminating   0         42s
web-3     1/1       Terminating   0         42s

順序終止 Pod

控制器會(huì)按照與 Pod 序號(hào)索引相反的順序每次刪除一個(gè) Pod。在刪除下一個(gè) Pod 前會(huì)等待上一個(gè)被完全關(guān)閉。

獲取 StatefulSet 的 PersistentVolumeClaims:

kubectl get pvc -l app=nginx
NAME        STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE
www-web-0   Bound     pvc-15c268c7-b507-11e6-932f-42010a800002   1Gi        RWO           13h
www-web-1   Bound     pvc-15c79307-b507-11e6-932f-42010a800002   1Gi        RWO           13h
www-web-2   Bound     pvc-e1125b27-b508-11e6-932f-42010a800002   1Gi        RWO           13h
www-web-3   Bound     pvc-e1176df6-b508-11e6-932f-42010a800002   1Gi        RWO           13h
www-web-4   Bound     pvc-e11bb5f8-b508-11e6-932f-42010a800002   1Gi        RWO           13h

五個(gè) PersistentVolumeClaims 和五個(gè) PersistentVolume 卷仍然存在。 查看 Pod 的穩(wěn)定存儲(chǔ),我們發(fā)現(xiàn)當(dāng)刪除 StatefulSet 的 Pod 時(shí),掛載到 StatefulSet 的 Pod 的 PersistentVolume 卷不會(huì)被刪除。 當(dāng)這種刪除行為是由 StatefulSet 縮容引起時(shí)也是一樣的。

更新 StatefulSet

從 Kubernetes 1.7 版本開(kāi)始,StatefulSet 控制器支持自動(dòng)更新。 更新策略由 StatefulSet API 對(duì)象的 ?spec.updateStrategy? 字段決定。這個(gè)特性能夠用來(lái)更新一個(gè) StatefulSet 中 Pod 的的容器鏡像、資源請(qǐng)求和限制、標(biāo)簽和注解。

?RollingUpdate ?更新策略是 StatefulSet 默認(rèn)策略。

滾動(dòng)更新

?RollingUpdate ?更新策略會(huì)更新一個(gè) StatefulSet 中的所有 Pod,采用與序號(hào)索引相反的順序并遵循 StatefulSet 的保證。

對(duì) ?web ?StatefulSet 應(yīng)用 Patch 操作來(lái)應(yīng)用 ?RollingUpdate ?更新策略:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'
statefulset.apps/web patched

在一個(gè)終端窗口中對(duì) ?web ?StatefulSet 執(zhí)行 patch 操作來(lái)再次改變?nèi)萜麋R像:

kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.8"}]'
statefulset.apps/web patched

在另一個(gè)終端監(jiān)控 StatefulSet 中的 Pod:

kubectl get pod -l app=nginx -w

輸出類似于:

NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          7m
web-1     1/1       Running   0          7m
web-2     1/1       Running   0          8m
web-2     1/1       Terminating   0         8m
web-2     1/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Pending   0         0s
web-2     0/1       Pending   0         0s
web-2     0/1       ContainerCreating   0         0s
web-2     1/1       Running   0         19s
web-1     1/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         6s
web-0     1/1       Terminating   0         7m
web-0     1/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Pending   0         0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         10s

StatefulSet 里的 Pod 采用和序號(hào)相反的順序更新。在更新下一個(gè) Pod 前,StatefulSet 控制器終止每個(gè) Pod 并等待它們變成 Running 和 Ready。 請(qǐng)注意,雖然在順序后繼者變成 Running 和 Ready 之前 StatefulSet 控制器不會(huì)更新下一個(gè) Pod,但它仍然會(huì)重建任何在更新過(guò)程中發(fā)生故障的 Pod,使用的是它們當(dāng)前的版本。

已經(jīng)接收到更新請(qǐng)求的 Pod 將會(huì)被恢復(fù)為更新的版本,沒(méi)有收到請(qǐng)求的 Pod 則會(huì)被恢復(fù)為之前的版本。 像這樣,控制器嘗試?yán)^續(xù)使應(yīng)用保持健康并在出現(xiàn)間歇性故障時(shí)保持更新的一致性。

獲取 Pod 來(lái)查看它們的容器鏡像:

for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
k8s.gcr.io/nginx-slim:0.8
k8s.gcr.io/nginx-slim:0.8
k8s.gcr.io/nginx-slim:0.8

StatefulSet 中的所有 Pod 現(xiàn)在都在運(yùn)行之前的容器鏡像。

說(shuō)明:

你還可以使用 ?
kubectl rollout status sts/<名稱>? 來(lái)查看 StatefulSet 的滾動(dòng)更新?tīng)顟B(tài)。

分段更新

你可以使用 ?RollingUpdate ?更新策略的 ?partition ?參數(shù)來(lái)分段更新一個(gè) StatefulSet。 分段的更新將會(huì)使 StatefulSet 中的其余所有 Pod 保持當(dāng)前版本的同時(shí)允許改變 StatefulSet 的 ?.spec.template?。

對(duì) ?web ?StatefulSet 執(zhí)行 Patch 操作以為 ?updateStrategy ?字段添加一個(gè)分區(qū):

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'
statefulset.apps/web patched

再次 Patch StatefulSet 來(lái)改變?nèi)萜麋R像:

kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"k8s.gcr.io/nginx-slim:0.7"}]'
statefulset.apps/web patched

刪除 StatefulSet 中的 Pod:

kubectl delete pod web-2
pod "web-2" deleted

等待 Pod 變成 Running 和 Ready。

kubectl get pod -l app=nginx -w
NAME      READY     STATUS              RESTARTS   AGE
web-0     1/1       Running             0          4m
web-1     1/1       Running             0          4m
web-2     0/1       ContainerCreating   0          11s
web-2     1/1       Running   0         18s

獲取 Pod 的容器鏡像:

kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
k8s.gcr.io/nginx-slim:0.8

請(qǐng)注意,雖然更新策略是 ?RollingUpdate?,StatefulSet 還是會(huì)使用原始的容器恢復(fù) Pod。 這是因?yàn)?nbsp;Pod 的序號(hào)比 ?updateStrategy ?指定的 ?partition ?更小。

金絲雀發(fā)布

你可以通過(guò)減少上文指定的 ?partition ?來(lái)進(jìn)行金絲雀發(fā)布,以此來(lái)測(cè)試你的程序的改動(dòng)。

通過(guò) patch 命令修改 StatefulSet 來(lái)減少分區(qū):

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":2}}}}'
statefulset.apps/web patched

等待 ?web-2? 變成 Running 和 Ready。

kubectl get pod -l app=nginx -w
NAME      READY     STATUS              RESTARTS   AGE
web-0     1/1       Running             0          4m
web-1     1/1       Running             0          4m
web-2     0/1       ContainerCreating   0          11s
web-2     1/1       Running   0         18s

獲取 Pod 的容器:

kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
k8s.gcr.io/nginx-slim:0.7

當(dāng)你改變 ?partition ?時(shí),StatefulSet 會(huì)自動(dòng)更新 ?web-2? Pod,這是因?yàn)?nbsp;Pod 的序號(hào)大于或等于 ?partition?。

刪除 ?web-1? Pod:

kubectl delete pod web-1
pod "web-1" deleted

等待 ?web-1? 變成 Running 和 Ready。

kubectl get pod -l app=nginx -w

輸出類似于:

NAME      READY     STATUS        RESTARTS   AGE
web-0     1/1       Running       0          6m
web-1     0/1       Terminating   0          6m
web-2     1/1       Running       0          2m
web-1     0/1       Terminating   0         6m
web-1     0/1       Terminating   0         6m
web-1     0/1       Terminating   0         6m
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         18s

獲取 ?web-1? Pod 的容器鏡像:

kubectl get pod web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
k8s.gcr.io/nginx-slim:0.8

?web-1? 被按照原來(lái)的配置恢復(fù),因?yàn)?nbsp;Pod 的序號(hào)小于分區(qū)。當(dāng)指定了分區(qū)時(shí),如果更新了 StatefulSet 的 ?.spec.template?,則所有序號(hào)大于或等于分區(qū)的 Pod 都將被更新。 如果一個(gè)序號(hào)小于分區(qū)的 Pod 被刪除或者終止,它將被按照原來(lái)的配置恢復(fù)。

分階段的發(fā)布

你可以使用類似金絲雀發(fā)布的方法執(zhí)行一次分階段的發(fā)布 (例如一次線性的、等比的或者指數(shù)形式的發(fā)布)。 要執(zhí)行一次分階段的發(fā)布,你需要設(shè)置 ?partition ?為希望控制器暫停更新的序號(hào)。

分區(qū)當(dāng)前為 2。請(qǐng)將分區(qū)設(shè)置為 0:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":0}}}}'
statefulset.apps/web patched

等待 StatefulSet 中的所有 Pod 變成 Running 和 Ready。

kubectl get pod -l app=nginx -w

輸出類似于:

NAME      READY     STATUS              RESTARTS   AGE
web-0     1/1       Running             0          3m
web-1     0/1       ContainerCreating   0          11s
web-2     1/1       Running             0          2m
web-1     1/1       Running   0         18s
web-0     1/1       Terminating   0         3m
web-0     1/1       Terminating   0         3m
web-0     0/1       Terminating   0         3m
web-0     0/1       Terminating   0         3m
web-0     0/1       Terminating   0         3m
web-0     0/1       Terminating   0         3m
web-0     0/1       Pending   0         0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         3s

獲取 StatefulSet 中 Pod 的容器鏡像詳細(xì)信息:

for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
k8s.gcr.io/nginx-slim:0.7
k8s.gcr.io/nginx-slim:0.7
k8s.gcr.io/nginx-slim:0.7

將 ?partition? 改變?yōu)?nbsp;0 以允許 StatefulSet 繼續(xù)更新過(guò)程。

OnDelete 策略

?OnDelete ?更新策略實(shí)現(xiàn)了傳統(tǒng)(1.7 之前)行為,它也是默認(rèn)的更新策略。 當(dāng)你選擇這個(gè)更新策略并修改 StatefulSet 的 ?.spec.template? 字段時(shí),StatefulSet 控制器將不會(huì)自動(dòng)更新 Pod。

刪除 StatefulSet

StatefulSet 同時(shí)支持級(jí)聯(lián)和非級(jí)聯(lián)刪除。使用非級(jí)聯(lián)方式刪除 StatefulSet 時(shí),StatefulSet 的 Pod 不會(huì)被刪除。使用級(jí)聯(lián)刪除時(shí),StatefulSet 和它的 Pod 都會(huì)被刪除。

非級(jí)聯(lián)刪除

在一個(gè)終端窗口監(jiān)視 StatefulSet 中的 Pod。

kubectl get pods -w -l app=nginx

使用 ?kubectl delete? 刪除 StatefulSet。請(qǐng)確保提供了 ?--cascade=orphan? 參數(shù)給命令。這個(gè)參數(shù)告訴 Kubernetes 只刪除 StatefulSet 而不要?jiǎng)h除它的任何 Pod。

kubectl delete statefulset web --cascade=orphan
statefulset.apps "web" deleted

獲取 Pod 來(lái)檢查它們的狀態(tài):

kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          6m
web-1     1/1       Running   0          7m
web-2     1/1       Running   0          5m

雖然 ?web ?已經(jīng)被刪除了,但所有 Pod 仍然處于 Running 和 Ready 狀態(tài)。 刪除 ?web-0?:

kubectl delete pod web-0
pod "web-0" deleted

獲取 StatefulSet 的 Pod:

kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-1     1/1       Running   0          10m
web-2     1/1       Running   0          7m

由于 ?web ?StatefulSet 已經(jīng)被刪除,?web-0? 沒(méi)有被重新啟動(dòng)。

在一個(gè)終端監(jiān)控 StatefulSet 的 Pod。

kubectl get pods -w -l app=nginx

在另一個(gè)終端里重新創(chuàng)建 StatefulSet。請(qǐng)注意,除非你刪除了 ?nginx ?Service(你不應(yīng)該這樣做),你將會(huì)看到一個(gè)錯(cuò)誤,提示 Service 已經(jīng)存在。

kubectl apply -f web.yaml
statefulset.apps/web created
service/nginx unchanged

請(qǐng)忽略這個(gè)錯(cuò)誤。它僅表示 kubernetes 進(jìn)行了一次創(chuàng)建 nginx headless Service 的嘗試,盡管那個(gè) Service 已經(jīng)存在。

在第一個(gè)終端中運(yùn)行并檢查 ?kubectl get? 命令的輸出。

kubectl get pods -w -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-1     1/1       Running   0          16m
web-2     1/1       Running   0          2m
NAME      READY     STATUS    RESTARTS   AGE
web-0     0/1       Pending   0          0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         18s
web-2     1/1       Terminating   0         3m
web-2     0/1       Terminating   0         3m
web-2     0/1       Terminating   0         3m
web-2     0/1       Terminating   0         3m

當(dāng)重新創(chuàng)建 ?web ?StatefulSet 時(shí),?web-0? 被第一個(gè)重新啟動(dòng)。 由于 ?web-1? 已經(jīng)處于 Running 和 Ready 狀態(tài),當(dāng) ?web-0? 變成 Running 和 Ready 時(shí), StatefulSet 會(huì)接收這個(gè) Pod。由于你重新創(chuàng)建的 StatefulSet 的 ?replicas ?等于 2, 一旦 ?web-0? 被重新創(chuàng)建并且 ?web-1? 被認(rèn)為已經(jīng)處于 Running 和 Ready 狀態(tài)時(shí),?web-2? 將會(huì)被終止。

讓我們?cè)倏纯幢?Pod 的 Web 服務(wù)器加載的 ?index.html? 的內(nèi)容:

for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1

盡管你同時(shí)刪除了 StatefulSet 和 ?web-0? Pod,但它仍然使用最初寫入 ?index.html? 文件的主機(jī)名進(jìn)行服務(wù)。 這是因?yàn)?nbsp;StatefulSet 永遠(yuǎn)不會(huì)刪除和一個(gè) Pod 相關(guān)聯(lián)的 PersistentVolume 卷。 當(dāng)你重建這個(gè) StatefulSet 并且重新啟動(dòng)了 ?web-0? 時(shí),它原本的 PersistentVolume 卷會(huì)被重新掛載。

級(jí)聯(lián)刪除

在一個(gè)終端窗口監(jiān)視 StatefulSet 里的 Pod。

kubectl get pods -w -l app=nginx

在另一個(gè)窗口中再次刪除這個(gè) StatefulSet。這次省略 ?--cascade=orphan? 參數(shù)。

kubectl delete statefulset web
statefulset.apps "web" deleted

在第一個(gè)終端檢查 ?kubectl get? 命令的輸出,并等待所有的 Pod 變成 Terminating 狀態(tài)。

kubectl get pods -w -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          11m
web-1     1/1       Running   0          27m
NAME      READY     STATUS        RESTARTS   AGE
web-0     1/1       Terminating   0          12m
web-1     1/1       Terminating   0         29m
web-0     0/1       Terminating   0         12m
web-0     0/1       Terminating   0         12m
web-0     0/1       Terminating   0         12m
web-1     0/1       Terminating   0         29m
web-1     0/1       Terminating   0         29m
web-1     0/1       Terminating   0         29m

Pod 按照和他們序號(hào)索引相反的順序每次終止一個(gè)。 在終止一個(gè) Pod 前,StatefulSet 控制器會(huì)等待 Pod 后繼者被完全終止。

說(shuō)明:

盡管級(jí)聯(lián)刪除會(huì)刪除 StatefulSet 及其 Pod,但級(jí)聯(lián)不會(huì)刪除與 StatefulSet 關(guān)聯(lián)的 Headless Service。你必須手動(dòng)刪除 ?
nginx ?Service。

kubectl delete service nginx
service "nginx" deleted

再一次重新創(chuàng)建 StatefulSet 和 headless Service:

kubectl apply -f web.yaml
service/nginx created
statefulset.apps/web created

當(dāng) StatefulSet 所有的 Pod 變成 Running 和 Ready 時(shí),獲取它們的 ?index.html? 文件的內(nèi)容:

for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1

即使你已經(jīng)刪除了 StatefulSet 和它的全部 Pod,這些 Pod 將會(huì)被重新創(chuàng)建并掛載它們的 PersistentVolume 卷,并且 ?web-0? 和 ?web-1? 將繼續(xù)使用它的主機(jī)名提供服務(wù)。

最后刪除 ?nginx ?service

kubectl delete service nginx
service "nginx" deleted

并且刪除 ?web ?StatefulSet:

kubectl delete statefulset web
statefulset "web" deleted

Pod 管理策略 

對(duì)于某些分布式系統(tǒng)來(lái)說(shuō),StatefulSet 的順序性保證是不必要和/或者不應(yīng)該的。 這些系統(tǒng)僅僅要求唯一性和身份標(biāo)志。為了解決這個(gè)問(wèn)題,在 Kubernetes 1.7 中 我們針對(duì) StatefulSet API 對(duì)象引入了 ?.spec.podManagementPolicy?。 此選項(xiàng)僅影響擴(kuò)縮操作的行為。更新不受影響。

OrderedReady Pod 管理策略

?OrderedReady ?Pod 管理策略是 StatefulSet 的默認(rèn)選項(xiàng)。它告訴 StatefulSet 控制器遵循上文展示的順序性保證。

Parallel Pod 管理策略

?Parallel ?Pod 管理策略告訴 StatefulSet 控制器并行的終止所有 Pod, 在啟動(dòng)或終止另一個(gè) Pod 前,不必等待這些 Pod 變成 Running 和 Ready 或者完全終止?fàn)顟B(tài)。

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"
  podManagementPolicy: "Parallel"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

下載上面的例子并保存為 ?web-parallel.yaml?。

這份清單和你在上文下載的完全一樣,只是 ?web? StatefulSet 的 ?.spec.podManagementPolicy ?設(shè)置成了 ?Parallel?。

在一個(gè)終端窗口監(jiān)視 StatefulSet 中的 Pod。

kubectl get pod -l app=nginx -w

在另一個(gè)終端窗口創(chuàng)建清單中的 StatefulSet 和 Service:

kubectl apply -f web-parallel.yaml
service/nginx created
statefulset.apps/web created

查看你在第一個(gè)終端中運(yùn)行的 ?kubectl get? 命令的輸出。

kubectl get pod -l app=nginx -w
NAME      READY     STATUS    RESTARTS   AGE
web-0     0/1       Pending   0          0s
web-0     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-1     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         10s
web-1     1/1       Running   0         10s

StatefulSet 控制器同時(shí)啟動(dòng)了 ?web-0? 和 ?web-1?。

保持第二個(gè)終端打開(kāi),并在另一個(gè)終端窗口中擴(kuò)容 StatefulSet:

kubectl scale statefulset/web --replicas=4
statefulset.apps/web scaled

在 ?kubectl get? 命令運(yùn)行的終端里檢查它的輸出。

web-3     0/1       Pending   0         0s
web-3     0/1       Pending   0         0s
web-3     0/1       Pending   0         7s
web-3     0/1       ContainerCreating   0         7s
web-2     1/1       Running   0         10s
web-3     1/1       Running   0         26s

StatefulSet 啟動(dòng)了兩個(gè)新的 Pod,而且在啟動(dòng)第二個(gè)之前并沒(méi)有等待第一個(gè)變成 Running 和 Ready 狀態(tài)。

清理

你應(yīng)該打開(kāi)兩個(gè)終端,準(zhǔn)備在清理過(guò)程中運(yùn)行 ?kubectl ?命令。

kubectl delete sts web
# sts is an abbreviation for statefulset

你可以監(jiān)視 ?kubectl get? 來(lái)查看那些 Pod 被刪除

kubectl get pod -l app=nginx -w
web-3     1/1       Terminating   0         9m
web-2     1/1       Terminating   0         9m
web-3     1/1       Terminating   0         9m
web-2     1/1       Terminating   0         9m
web-1     1/1       Terminating   0         44m
web-0     1/1       Terminating   0         44m
web-0     0/1       Terminating   0         44m
web-3     0/1       Terminating   0         9m
web-2     0/1       Terminating   0         9m
web-1     0/1       Terminating   0         44m
web-0     0/1       Terminating   0         44m
web-2     0/1       Terminating   0         9m
web-2     0/1       Terminating   0         9m
web-2     0/1       Terminating   0         9m
web-1     0/1       Terminating   0         44m
web-1     0/1       Terminating   0         44m
web-1     0/1       Terminating   0         44m
web-0     0/1       Terminating   0         44m
web-0     0/1       Terminating   0         44m
web-0     0/1       Terminating   0         44m
web-3     0/1       Terminating   0         9m
web-3     0/1       Terminating   0         9m
web-3     0/1       Terminating   0         9m

在刪除過(guò)程中,StatefulSet 將并發(fā)的刪除所有 Pod,在刪除一個(gè) Pod 前不會(huì)等待它的順序后繼者終止。

關(guān)閉 ?kubectl get? 命令運(yùn)行的終端并刪除 ?nginx ?Service:

kubectl delete svc nginx

說(shuō)明:

你需要?jiǎng)h除本教程中用到的 PersistentVolume 卷的持久化存儲(chǔ)介質(zhì)。

基于你的環(huán)境、存儲(chǔ)配置和制備方式,按照必須的步驟保證回收所有的存儲(chǔ)。


本文題目:創(chuàng)新互聯(lián)kubernetes教程:KubernetesStatefulSet基礎(chǔ)
分享URL:http://m.5511xx.com/article/dppjepo.html