日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

目錄
  • 正文
  • StatefulSet 的設(shè)計(jì)理解
    • Service 如何被訪問(wèn)
    • Headless Service 對(duì)應(yīng)的 YAML文件
    • StatefulSet 的 YAML 文件
  • 解析一下 Pod 對(duì)應(yīng)的 Headless Service

    正文

    Deployment認(rèn)為,一個(gè)應(yīng)用的所有 Pod,是完全一樣的。所以,它們互相之間沒(méi)有順序,也無(wú)所謂運(yùn)行在哪臺(tái)宿主機(jī)上。需要的時(shí)候,Deployment 就可以通過(guò) Pod 模板創(chuàng)建新的 Pod;不需要的時(shí)候,Deployment 就可以“殺掉”任意一個(gè) Pod。

    但是,在實(shí)際的場(chǎng)景中,并不是所有的應(yīng)用都可以滿足這樣的要求。

    尤其是分布式應(yīng)用,它的多個(gè)實(shí)例之間,往往有依賴關(guān)系,比如:主從關(guān)系、主備關(guān)系。

    還有就是數(shù)據(jù)存儲(chǔ)類應(yīng)用,它的多個(gè)實(shí)例,往往都會(huì)在本地磁盤上保存一份數(shù)據(jù)。而這些實(shí)例一旦被殺掉,即便重建出來(lái),實(shí)例與數(shù)據(jù)之間的對(duì)應(yīng)關(guān)系也已經(jīng)丟失,從而導(dǎo)致應(yīng)用失敗。

    所以,這種實(shí)例之間有不對(duì)等關(guān)系,以及實(shí)例對(duì)外部數(shù)據(jù)有依賴關(guān)系的應(yīng)用,就被稱為“有狀態(tài)應(yīng)用”(Stateful Application)。

    容器技術(shù)誕生后,大家很快發(fā)現(xiàn),它用來(lái)封裝“無(wú)狀態(tài)應(yīng)用”(Stateless Application),尤其是 Web 服務(wù),非常好用。但是,一旦你想要用容器運(yùn)行“有狀態(tài)應(yīng)用”,其困難程度就會(huì)直線上升。而且,這個(gè)問(wèn)題解決起來(lái),單純依靠容器技術(shù)本身已經(jīng)無(wú)能為力,這也就導(dǎo)致了很長(zhǎng)一段時(shí)間內(nèi),“有狀態(tài)應(yīng)用”幾乎成了容器技術(shù)圈子的“忌諱”,大家一聽(tīng)到這個(gè)詞,就紛紛搖頭。

    得益于“控制器模式”的設(shè)計(jì)思想,Kubernetes 項(xiàng)目很早就在 Deployment 的基礎(chǔ)上,擴(kuò)展出了對(duì)“有狀態(tài)應(yīng)用”的初步支持。這個(gè)編排功能,就是:StatefulSet。

    StatefulSet 的設(shè)計(jì)理解

    StatefulSet 的設(shè)計(jì)其實(shí)非常容易理解。它把真實(shí)世界里的應(yīng)用狀態(tài),抽象為了兩種情況:

    • 拓?fù)錉顟B(tài)。這種情況意味著,應(yīng)用的多個(gè)實(shí)例之間不是完全對(duì)等的關(guān)系。這些應(yīng)用實(shí)例,必須按照某些順序啟動(dòng),比如應(yīng)用的主節(jié)點(diǎn) A 要先于從節(jié)點(diǎn) B 啟動(dòng)。而如果你把 A 和 B 兩個(gè) Pod 刪除掉,它們?cè)俅伪粍?chuàng)建出來(lái)時(shí)也必須嚴(yán)格按照這個(gè)順序才行。并且,新創(chuàng)建出來(lái)的 Pod,必須和原來(lái) Pod 的網(wǎng)絡(luò)標(biāo)識(shí)一樣,這樣原先的訪問(wèn)者才能使用同樣的方法,訪問(wèn)到這個(gè)新 Pod。
    • 存儲(chǔ)狀態(tài)。這種情況意味著,應(yīng)用的多個(gè)實(shí)例分別綁定了不同的存儲(chǔ)數(shù)據(jù)。對(duì)于這些應(yīng)用實(shí)例來(lái)說(shuō),Pod A 第一次讀取到的數(shù)據(jù),和隔了十分鐘之后再次讀取到的數(shù)據(jù),應(yīng)該是同一份,哪怕在此期間 Pod A 被重新創(chuàng)建過(guò)。這種情況最典型的例子,就是一個(gè)數(shù)據(jù)庫(kù)應(yīng)用的多個(gè)存儲(chǔ)實(shí)例。

    所以,StatefulSet 的核心功能,就是通過(guò)某種方式記錄這些狀態(tài),然后在 Pod 被重新創(chuàng)建時(shí),能夠?yàn)樾?Pod 恢復(fù)這些狀態(tài)。

    在開(kāi)始講述 StatefulSet 的工作原理之前,我就必須先為你講解一個(gè) Kubernetes 項(xiàng)目中非常實(shí)用的概念:Headless Service。

    我在和你一起討論 Kubernetes 架構(gòu)的時(shí)候就曾介紹過(guò),Service 是 Kubernetes 項(xiàng)目中用來(lái)將一組 Pod 暴露給外界訪問(wèn)的一種機(jī)制。比如,一個(gè) Deployment 有 3 個(gè) Pod,那么我就可以定義一個(gè) Service。然后,用戶只要能訪問(wèn)到這個(gè) Service,它就能訪問(wèn)到某個(gè)具體的 Pod。

    Service 如何被訪問(wèn)

    那么,這個(gè) Service 又是如何被訪問(wèn)的呢?

    第一種方式,是以 Service 的 VIP(Virtual IP,即:虛擬 IP)方式。比如:當(dāng)我訪問(wèn) 10.0.23.1 這個(gè) Service 的 IP 地址時(shí),10.0.23.1 其實(shí)就是一個(gè) VIP,它會(huì)把請(qǐng)求轉(zhuǎn)發(fā)到該 Service 所代理的某一個(gè) Pod 上。這里的具體原理,我會(huì)在后續(xù)的 Service 章節(jié)中進(jìn)行詳細(xì)介紹。

    第二種方式,就是以 Service 的 DNS 方式。比如:這時(shí)候,只要我訪問(wèn)“my-svc.my-namespace.svc.cluster.local”這條 DNS 記錄,就可以訪問(wèn)到名叫 my-svc 的 Service 所代理的某一個(gè) Pod。

    而在第二種 Service DNS 的方式下,具體還可以分為兩種處理方法:

    第一種處理方法,是 Normal Service。這種情況下,你訪問(wèn)“my-svc.my-namespace.svc.cluster.local”解析到的,正是 my-svc 這個(gè) Service 的 VIP,后面的流程就跟 VIP 方式一致了。

    而第二種處理方法,正是 Headless Service。這種情況下,你訪問(wèn)“my-svc.my-namespace.svc.cluster.local”解析到的,直接就是 my-svc 代理的某一個(gè) Pod 的 IP 地址。可以看到,這里的區(qū)別在于,Headless Service 不需要分配一個(gè) VIP,而是可以直接以 DNS 記錄的方式解析出被代理 Pod 的 IP 地址。

    那么,這樣的設(shè)計(jì)又有什么作用呢? 想要回答這個(gè)問(wèn)題,我們需要從 Headless Service 的定義方式看起。

    Headless Service 對(duì)應(yīng)的 YAML文件

    下面是一個(gè)標(biāo)準(zhǔn)的 Headless Service 對(duì)應(yīng)的 YAML 文件:

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx
    

    可以看到,所謂的 Headless Service,其實(shí)仍是一個(gè)標(biāo)準(zhǔn) Service 的 YAML 文件。只不過(guò),它的 clusterIP 字段的值是:None,即:這個(gè) Service,沒(méi)有一個(gè) VIP 作為“頭”。這也就是 Headless 的含義。所以,這個(gè) Service 被創(chuàng)建后并不會(huì)被分配一個(gè) VIP,而是會(huì)以 DNS 記錄的方式暴露出它所代理的 Pod。

    而它所代理的 Pod,依然是采用 Label Selector 機(jī)制選擇出來(lái)的,即:所有攜帶了 app=nginx 標(biāo)簽的 Pod,都會(huì)被這個(gè) Service 代理起來(lái)。

    當(dāng)你按照這樣的方式創(chuàng)建了一個(gè) Headless Service 之后,它所代理的所有 Pod 的 IP 地址,都會(huì)被綁定一個(gè)這樣格式的 DNS 記錄,如下所示:<pod-name>.<svc-name>.<namespace>.svc.cluster.local

    這個(gè) DNS 記錄,正是 Kubernetes 項(xiàng)目為 Pod 分配的唯一的“可解析身份”(Resolvable Identity)。

    有了這個(gè)“可解析身份”,只要你知道了一個(gè) Pod 的名字,以及它對(duì)應(yīng)的 Service 的名字,你就可以非常確定地通過(guò)這條 DNS 記錄訪問(wèn)到 Pod 的 IP 地址。

    那么,StatefulSet 又是如何使用這個(gè) DNS 記錄來(lái)維持 Pod 的拓?fù)錉顟B(tài)的呢?

    StatefulSet 的 YAML 文件

    為了回答這個(gè)問(wèn)題,現(xiàn)在我們就來(lái)編寫一個(gè) StatefulSet 的 YAML 文件,如下所示:

    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: nginx:1.9.1
            ports:
            - containerPort: 80
              name: web
    

    這個(gè) YAML 文件,和我們?cè)谇懊嫖恼轮杏玫降?nginx-deployment 的唯一區(qū)別,就是多了一個(gè) serviceName=nginx 字段。

    這個(gè)字段的作用,就是告訴 StatefulSet 控制器,在執(zhí)行控制循環(huán)(Control Loop)的時(shí)候,請(qǐng)使用 nginx 這個(gè) Headless Service 來(lái)保證 Pod 的“可解析身份”。

    所以,當(dāng)你通過(guò) kubectl create 創(chuàng)建了上面這個(gè) Service 和 StatefulSet 之后,就會(huì)看到如下兩個(gè)對(duì)象:

    $ kubectl create -f svc.yaml
    $ kubectl get service nginx
    NAME      TYPE         CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    nginx     ClusterIP    None         <none>        80/TCP    10s
    $ kubectl create -f statefulset.yaml
    $ kubectl get statefulset web
    NAME      DESIRED   CURRENT   AGE
    web       2         1         19s
    

    查看StatefulSet 的 Events 這些信息

    $ 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         20s
    

    通過(guò)上面這個(gè) Pod 的創(chuàng)建過(guò)程,我們不難看到,StatefulSet 給它所管理的所有 Pod 的名字,進(jìn)行了編號(hào),編號(hào)規(guī)則是:-。

    而且這些編號(hào)都是從 0 開(kāi)始累加,與 StatefulSet 的每個(gè) Pod 實(shí)例一一對(duì)應(yīng),絕不重復(fù)。

    更重要的是,這些 Pod 的創(chuàng)建,也是嚴(yán)格按照編號(hào)順序進(jìn)行的。比如,在 web-0 進(jìn)入到 Running 狀態(tài)、并且細(xì)分狀態(tài)(Conditions)成為 Ready 之前,web-1 會(huì)一直處于 Pending 狀態(tài)。

    當(dāng)這兩個(gè) Pod 都進(jìn)入了 Running 狀態(tài)之后,你就可以查看到它們各自唯一的“網(wǎng)絡(luò)身份”了。

    我們使用 kubectl exec 命令進(jìn)入到容器中查看它們的 hostname:

    $ kubectl exec web-0 -- sh -c 'hostname'
    web-0
    $ kubectl exec web-1 -- sh -c 'hostname'
    web-1
    

    可以看到,這兩個(gè) Pod 的 hostname 與 Pod 名字是一致的,都被分配了對(duì)應(yīng)的編號(hào)。接下來(lái),我們?cè)僭囍?DNS 的方式,訪問(wèn)一下這個(gè) Headless Service:

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

    解析一下 Pod 對(duì)應(yīng)的 Headless Service

    通過(guò)這條命令,我們啟動(dòng)了一個(gè)一次性的 Pod,因?yàn)?ndash;rm 意味著 Pod 退出后就會(huì)被刪除掉。然后,在這個(gè) Pod 的容器里面,我們嘗試用 nslookup 命令,解析一下 Pod 對(duì)應(yīng)的 Headless Service:

    $ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
    $ 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.7
    

    從 nslookup 命令的輸出結(jié)果中,我們可以看到,在訪問(wèn) web-0.nginx 的時(shí)候,最后解析到的,正是 web-0 這個(gè) Pod 的 IP 地址;而當(dāng)訪問(wèn) web-1.nginx 的時(shí)候,解析到的則是 web-1 的 IP 地址。

    這時(shí)候,如果你在另外一個(gè) Terminal 里把這兩個(gè)“有狀態(tài)應(yīng)用”的 Pod 刪掉,然后,再在當(dāng)前 Terminal 里 Watch 一下這兩個(gè) Pod 的狀態(tài)變化,就會(huì)發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象

    $ 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       ContainerCreating   0         0s
    web-1     1/1       Running   0         32s
    

    可以看到,當(dāng)我們把這兩個(gè) Pod 刪除之后,Kubernetes 會(huì)按照原先編號(hào)的順序,創(chuàng)建出了兩個(gè)新的 Pod。并且,Kubernetes 依然為它們分配了與原來(lái)相同的“網(wǎng)絡(luò)身份”:web-0.nginx 和 web-1.nginx。

    通過(guò)這種嚴(yán)格的對(duì)應(yīng)規(guī)則,StatefulSet 就保證了 Pod 網(wǎng)絡(luò)標(biāo)識(shí)的穩(wěn)定性。

    比如,如果 web-0 是一個(gè)需要先啟動(dòng)的主節(jié)點(diǎn),web-1 是一個(gè)后啟動(dòng)的從節(jié)點(diǎn),那么只要這個(gè) StatefulSet 不被刪除,你訪問(wèn) web-0.nginx 時(shí)始終都會(huì)落在主節(jié)點(diǎn)上,訪問(wèn) web-1.nginx 時(shí),則始終都會(huì)落在從節(jié)點(diǎn)上,這個(gè)關(guān)系絕對(duì)不會(huì)發(fā)生任何變化。

    所以,如果我們?cè)儆?nslookup 命令,查看一下這個(gè)新 Pod 對(duì)應(yīng)的 Headless Service 的話:

    $ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh 
    $ 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.8
    $ 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
    

    我們可以看到,在這個(gè) StatefulSet 中,這兩個(gè)新 Pod 的“網(wǎng)絡(luò)標(biāo)識(shí)”(比如:web-0.nginx 和 web-1.nginx),再次解析到了正確的 IP 地址(比如:web-0 Pod 的 IP 地址 10.244.1.8)。

    通過(guò)這種方法,Kubernetes 就成功地將 Pod 的拓?fù)錉顟B(tài)(比如:哪個(gè)節(jié)點(diǎn)先啟動(dòng),哪個(gè)節(jié)點(diǎn)后啟動(dòng)),按照 Pod 的“名字 + 編號(hào)”的方式固定了下來(lái)。此外,Kubernetes 還為每一個(gè) Pod 提供了一個(gè)固定并且唯一的訪問(wèn)入口,即:這個(gè) Pod 對(duì)應(yīng)的 DNS 記錄。

    這些狀態(tài),在 StatefulSet 的整個(gè)生命周期里都會(huì)保持不變,絕不會(huì)因?yàn)閷?duì)應(yīng) Pod 的刪除或者重新創(chuàng)建而失效。

    不過(guò),相信你也已經(jīng)注意到了,盡管 web-0.nginx 這條記錄本身不會(huì)變,但它解析到的 Pod 的 IP 地址,并不是固定的。這就意味著,對(duì)于“有狀態(tài)應(yīng)用”實(shí)例的訪問(wèn),你必須使用 DNS 記錄或者 hostname 的方式,而絕不應(yīng)該直接訪問(wèn)這些 Pod 的 IP 地址。

    以上就是k8s編排之StatefulSet知識(shí)點(diǎn)詳解一的詳細(xì)內(nèi)容,更多關(guān)于k8s編排StatefulSet的資料請(qǐng)關(guān)注其它相關(guān)文章!

    分享到:
    標(biāo)簽:K8S 服務(wù)器 知識(shí)點(diǎn) 編排 詳解
    用戶無(wú)頭像

    網(wǎng)友整理

    注冊(cè)時(shí)間:

    網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

    • 51998

      網(wǎng)站

    • 12

      小程序

    • 1030137

      文章

    • 747

      會(huì)員

    趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
    最新入駐小程序

    數(shù)獨(dú)大挑戰(zhàn)2018-06-03

    數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

    答題星2018-06-03

    您可以通過(guò)答題星輕松地創(chuàng)建試卷

    全階人生考試2018-06-03

    各種考試題,題庫(kù),初中,高中,大學(xué)四六

    運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

    記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

    每日養(yǎng)生app2018-06-03

    每日養(yǎng)生,天天健康

    體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

    通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定