日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

.NET Core + Kubernetes:StatefulSet

發(fā)布時(shí)間:2023/12/4 asp.net 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core + Kubernetes:StatefulSet 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在 Kubernetes 中,Pod 資源的控制器 Deployment、Replicaset、Daemonset 等常用于管理無狀態(tài)應(yīng)用,它們所管理的 Pod 對(duì)應(yīng)的 IP、名字,啟停順序等都是隨機(jī)的,Pod 之間也并不存在任何關(guān)聯(lián)關(guān)系。而實(shí)際情況下,在應(yīng)用集群部署時(shí),實(shí)例彼此之間可能是需要存在關(guān)聯(lián)關(guān)系的(啟動(dòng)順序、角色),如 MySQL、MongoDB,所以 StatefulSet 就是為了運(yùn)行有狀態(tài)服務(wù)引入的一種資源類型,StatefulSet 為每個(gè) Pod 維持一個(gè)唯一且固定的標(biāo)識(shí)符,必要時(shí)還會(huì)為其創(chuàng)建專用的存儲(chǔ)卷,當(dāng) Pod 被重建時(shí),也依然能保持原來的標(biāo)識(shí)符和存儲(chǔ)卷。

完整的 StatefulSet 通常由三部分構(gòu)成:StatefulSet 、VolumeClaimTemplate、Headless Service。

StatefulSet 用于 Pod 資源定義與管控,在 StatefulSet 模式下,Pod 有自己固定的命名規(guī)則(StatfulSet 名稱 + Pod 創(chuàng)建時(shí)所在的索引),假設(shè)設(shè)置的 StatefulSet 名稱為 k8sdemo,replicas 為3,則對(duì)應(yīng)的 Pod 名稱將分別是 k8sdemo-0、k8sdemo-1、k8sdemo-0,同時(shí)在進(jìn)行 Pod 副本伸縮時(shí)也能做到按序號(hào)進(jìn)行升降。

VolumeClaimTemplate 用于定義 Pod 所需存儲(chǔ)的 PVC 聲明 ,PVC 與 PV 進(jìn)行綁定,提供專有固定的存儲(chǔ)卷。

Headless Service (clusterIP: None)用于為 Pod 生成可解析的 DNS 域名記錄,基于 Pod 名稱的有序規(guī)則,Pod 域名是不會(huì)變的(Pod 名稱.serviceName),這也保證了 Pod 網(wǎng)絡(luò)標(biāo)識(shí)的穩(wěn)定性。

下面繼續(xù)以 .NET Core ?項(xiàng)目構(gòu)建的 beckjin/k8sdemo:1.2.0 鏡像為例,增加了接口訪問日志記錄的功能。通過集成 log4net 將接口訪問日志進(jìn)行文件記錄,日志將輸出到 /Data/ 目錄,每個(gè) Pod 都會(huì)擁有自己的一份日志文件(這只是一個(gè)假設(shè)的場(chǎng)景,切勿較真,實(shí)際情況下日志記錄一般都會(huì)使用統(tǒng)一的日志采集工具)。

定義資源

k8sdemo-statefulset.yaml:

apiVersion: apps/v1 kind: StatefulSet metadata:name: k8sdemo spec:serviceName: "k8sdemo-service" # 需要與創(chuàng)建的 service name 一致replicas: 3selector:matchLabels:name: k8sdemotemplate:metadata:labels:name: k8sdemospec:containers:- name: k8sdemoimage: beckjin/k8sdemo:1.2.0imagePullPolicy: IfNotPresentvolumeMounts:- name: datamountPath: /app/Data # 將容器內(nèi)的 Data 目錄進(jìn)行掛載volumeClaimTemplates: # 定義模板,自動(dòng)創(chuàng)建 PVC- metadata:name: dataspec:accessModes:- ReadOnlyManyresources:requests:storage: 100MistorageClassName: "k8sdemo-sc" # 將自動(dòng)與集群內(nèi) storageClassName 匹配的 PV 進(jìn)行綁定

k8sdemo-service.yaml:

apiVersion: v1 kind: Service metadata:name: k8sdemo-service spec:clusterIP: Noneports:- port: 80targetPort: 80selector:name: k8sdemo

StatefulSet 模式下需要設(shè)置 serviceName 字段,用來告訴 StatefulSet 控制器具體使用哪個(gè) service 來解析它所管理的 Pod。同時(shí)通過 volumeClaimTemplates 字段進(jìn)行 PVC 定義,StatefulSet 控制器會(huì)自動(dòng)創(chuàng)建與 Pod 對(duì)應(yīng)的 PVC,PVC 的名稱為 (volumeClaimTemplateName)-(podName),然后 PVC 會(huì)自動(dòng)與滿足要求的 PV 進(jìn)行綁定,PV 如果不支持自動(dòng)創(chuàng)建可手動(dòng)完成。另外當(dāng) Pod 被刪除時(shí) PVC 與 PV 依然會(huì)被保留,Pod 重建時(shí)會(huì)重新關(guān)聯(lián)之前對(duì)應(yīng)的 PVC 與 PV。

這里還是使用的 NFS 創(chuàng)建 PV 來實(shí)現(xiàn)存儲(chǔ),分別創(chuàng)建 3 個(gè)(data-k8sdemo-pv-[1~3])滿足定義要求的 PV,如下:

apiVersion: v1 kind: PersistentVolume metadata:name: data-k8sdemo-pv-1 spec:nfs:server: 192.168.124.21path: /statefulset/data1accessModes:- ReadOnlyManycapacity:storage: 100MistorageClassName: k8sdemo-sc

部署與測(cè)試

創(chuàng)建 PV 與 StatefulSet:

kubectl apply -f k8sdemo-statefulset-pv1.yaml kubectl apply -f k8sdemo-statefulset-pv2.yaml kubectl apply -f k8sdemo-statefulset-pv3.yaml kubectl apply -f k8sdemo-statefulset.yaml

注意::PV 命名順序并不代表被 PVC 的綁定順序,這兩者沒有關(guān)系,所以不用對(duì)上圖的數(shù)字編號(hào)對(duì)應(yīng)關(guān)系有疑問。

創(chuàng)建 Service:

kubectl apply -f k8sdemo-service.yaml

因?yàn)?Service 定義的是 Headless 模式,所以需要進(jìn)去 Pod 內(nèi)進(jìn)行接口訪問測(cè)試,如:kubectl exec -it k8sdemo-0 bash 進(jìn)入 k8sdemo-0 這個(gè) Pod,通過域名 Pod 名稱.serviceName 來訪問,如下:

curl k8sdemo-0.k8sdemo-service/weatherforecast curl k8sdemo-1.k8sdemo-service/weatherforecast curl k8sdemo-2.k8sdemo-service/weatherforecast

在 NFS 掛載目錄中查看接口訪問日志,以下是 Pod ?k8sdemo-1 中的日志:

2020-09-20 06:01:17,451 [17] INFO [k8sdemo-1] - Request starting HTTP/1.1 GET http://k8sdemo-1.k8sdemo-service/weatherforecast 2020-09-20 06:01:17,455 [17] INFO [k8sdemo-1] - Executing endpoint 'T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo)' 2020-09-20 06:01:17,458 [17] INFO [k8sdemo-1] - Route matched with {action = "Get", controller = "WeatherForecast"}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[T.K8SDemo.WeatherForecast] Get() on controller T.K8SDemo.Controllers.WeatherForecastController (T.K8SDemo). 2020-09-20 06:01:17,459 [17] INFO [k8sdemo-1] - Executing ObjectResult, writing value of type 'T.K8SDemo.WeatherForecast[]'. 2020-09-20 06:01:17,460 [17] INFO [k8sdemo-1] - Executed action T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo) in 2.3627ms 2020-09-20 06:01:17,460 [17] INFO [k8sdemo-1] - Executed endpoint 'T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo)' 2020-09-20 06:01:17,461 [17] INFO [k8sdemo-1] - Request finished in 9.9194ms 200 application/json; charset=utf-8

執(zhí)行 kubectl delete pod k8sdemo-1 刪除 Pod k8sdemo-1,等待一會(huì) k8sdemo-1 會(huì)自動(dòng)恢復(fù),然后重新訪問 curl k8sdemo-1.k8sdemo-service/weatherforecast,日志依然向原來的文件內(nèi)追加,也說明保留了原來的狀態(tài)。

2020-09-20 06:01:17,451 [17] INFO [k8sdemo-1] - Request starting HTTP/1.1 GET http://k8sdemo-1.k8sdemo-service/weatherforecast 2020-09-20 06:01:17,455 [17] INFO [k8sdemo-1] - Executing endpoint 'T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo)' 2020-09-20 06:01:17,458 [17] INFO [k8sdemo-1] - Route matched with {action = "Get", controller = "WeatherForecast"}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[T.K8SDemo.WeatherForecast] Get() on controller T.K8SDemo.Controllers.WeatherForecastController (T.K8SDemo). 2020-09-20 06:01:17,459 [17] INFO [k8sdemo-1] - Executing ObjectResult, writing value of type 'T.K8SDemo.WeatherForecast[]'. 2020-09-20 06:01:17,460 [17] INFO [k8sdemo-1] - Executed action T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo) in 2.3627ms 2020-09-20 06:01:17,460 [17] INFO [k8sdemo-1] - Executed endpoint 'T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo)' 2020-09-20 06:01:17,461 [17] INFO [k8sdemo-1] - Request finished in 9.9194ms 200 application/json; charset=utf-8 2020-09-20 06:17:06,467 [12] INFO [k8sdemo-1] - Request starting HTTP/1.1 GET http://k8sdemo-1.k8sdemo-service/weatherforecast 2020-09-20 06:17:06,494 [12] INFO [k8sdemo-1] - Executing endpoint 'T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo)' 2020-09-20 06:17:06,527 [12] INFO [k8sdemo-1] - Route matched with {action = "Get", controller = "WeatherForecast"}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[T.K8SDemo.WeatherForecast] Get() on controller T.K8SDemo.Controllers.WeatherForecastController (T.K8SDemo). 2020-09-20 06:17:06,533 [12] INFO [k8sdemo-1] - Executing ObjectResult, writing value of type 'T.K8SDemo.WeatherForecast[]'. 2020-09-20 06:17:06,548 [12] INFO [k8sdemo-1] - Executed action T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo) in 17.1904ms 2020-09-20 06:17:06,549 [12] INFO [k8sdemo-1] - Executed endpoint 'T.K8SDemo.Controllers.WeatherForecastController.Get (T.K8SDemo)' 2020-09-20 06:17:06,550 [12] INFO [k8sdemo-1] - Request finished in 84.3414ms 200 application/json; charset=utf-8

另外對(duì) Pod 副本進(jìn)行伸縮時(shí)效果也是一樣的,都會(huì)保持 Pod 具有的狀態(tài)。當(dāng)然文中的例子和一些組件的集群部署不太一樣,比如像 MySQL 這類組件,各實(shí)例間還會(huì)做數(shù)據(jù)同步來實(shí)現(xiàn)數(shù)據(jù)的一致性,當(dāng)然最終也是每個(gè)實(shí)例關(guān)聯(lián)自己的數(shù)據(jù)存儲(chǔ)卷。

總結(jié)

以上是生活随笔為你收集整理的.NET Core + Kubernetes:StatefulSet的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。