上篇我們已經安裝好k8s1.23集群,現在我們開始使用k8s部署我們的專案
Pod
Pod 是一組容器集合,是可以在 Kubernetes 中創建和管理的、最小的可部署的計算單元,這些容器共享存盤、網路,
準備Demo
我們要實作多容器Pod所以準備兩個WebAPI專案
新建一個webapi,命名為oneapi,里面新增TestController,新增兩個api,一個是回傳當前pod的ip,另一個是模擬高cpu操作
[ApiController] [Route("[controller]")] public class TestController : ControllerBase { private readonly ILogger<TestController> _logger; public TestController(ILogger<TestController> logger) { _logger = logger; } [HttpGet] public string Get() { var ip = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces().Select(p => p.GetIPProperties()).SelectMany(p => p.UnicastAddresses) .Where(p => p.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !System.Net.IPAddress.IsLoopback(p.Address)) .FirstOrDefault()?.Address.ToString(); return "ip is " + ip; } [HttpGet("highcpu")] public string HighCpu(int minutes) { var now = DateTime.Now; while (DateTime.Now - now <= TimeSpan.FromMinutes(minutes)) { _logger.LogInformation(DateTime.Now.ToString()); } return "ok"; } }
新建第二個webapi,命名為twoapi,里面同樣新增TestController,實作一個介面,通過localhost呼叫oneapi的ip介面(pod內容器共享存盤、網路)
[ApiController] [Route("[controller]")] public class TestController : ControllerBase { private readonly ILogger<TestController> _logger; private readonly HttpClient _httpclient; public TestController(ILogger<TestController> logger, HttpClient httpclient) { _logger = logger; _httpclient = httpclient; } [HttpGet("calloneapi")] public async Task<string> CallOneApiAsync() { var content = await (await _httpclient.GetAsync("http://localhost:5000/test")).Content.ReadAsStringAsync(); return "one api response is " + content; } }
將這兩個api打成鏡像,推進阿里云鏡像庫

單容器Pod
我們通過以下命令即可快速地部署一個pod,下面所有的鏡像都使用我們剛剛推送到阿里云里的鏡像
kubectl run oneapi --image=registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest
可通過以下命令查看pod的狀態
kubectl describe pod oneapi
查看到pod的私有ip,呼叫oneapi的ip介面,驗證是否部署成功
curl 10.244.36.66:5000/test
多容器Pod
多容器pod容器共享存盤、網路,我們通過yaml檔案來部署一個多容器的pod,來驗證是否共用網路,
新建pod.yaml檔案
apiVersion: v1 kind: Pod metadata: name: chesterapi spec: containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001通過以下命令部署容器
kubectl apply -f pod.yaml
通過以下命令查看pod
kubectl describe pod chesterapi
通過以下呼叫twoapi的介面驗證pod是否部署成功
curl podip:5001/test/calloneapi
驗證完成,通過以下命令洗掉pod
kubectl delete -f pod.yaml
探針
探針用于檢測pod的健康狀態,探針有三種,
-
ExecAction(借助容器運行時執行) -
TCPSocketAction(由 kubelet 直接檢測) -
HTTPGetAction(由 kubelet 直接檢測)
我們通過http探針,來檢測pod的健康狀態,修改pod.yaml檔案,并直接kubectl apply -f pod.yaml即可驗證
apiVersion: v1 kind: Pod metadata: name: chesterapi spec: containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test port: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001 livenessProbe: httpGet: path: /test/calloneapi port: 5001
Pod狀態

Pod重啟策略
restartPolicy的選擇值
-
Always:當容器失效時,由kubelet自動重啟該容器,
-
OnFailure:當容器終止運行且退出碼不為0時,由kubelet自動 重啟該容器,
-
Never:不論容器運行狀態如何,kubelet都不會重啟該容器,
我們通過pod.yaml的探針介面地址為一個不存在的地址,并將restartPolicy設定為Never,讓其即使健康檢查失敗,Pod也永不重啟
apiVersion: v1 kind: Pod metadata: name: chesterapi spec: restartPolicy: Never containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test1 port: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001 livenessProbe: httpGet: path: /test/calloneapi1 port: 5001
通過以下命令部署,并驗證
kubectl apply -f pod.yamlkubectl describe pod -n chesterapi
Deployemnt
說完了pod,我們來看看deployment,生產環境中基本不存在直接定義pod的方式來部署專案,更多的是通過Deployment來部署,
用途
-
方便管理、部署Pod
-
橫擴應對高負載
-
快速程式更新與回滾
創建
首先我們創建一個檔案ns.yaml來定義一個namespace
apiVersion: v1
kind: Namespace
metadata:
name: chesterns
我們通過定義以下一個deployment,實作部署三個pod,模擬負載
apiVersion: apps/v1 kind: Deployment metadata: name: chesterdeployment namespace: chesterns labels: app: chesterapi spec: replicas: 3 selector: matchLabels: app: chesterapi template: metadata: labels: app: chesterapi spec: containers: - name: oneapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest ports: - containerPort: 5000 livenessProbe: httpGet: path: /test port: 5000 - name: twoapi image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest ports: - containerPort: 5001 livenessProbe: httpGet: path: /test/calloneapi port: 5001
通過以下命令部署并呼叫介面
?kubectl apply -f deployment.yaml # 部署 kubectl get deployment -n chesterns # 獲取deployment kubectl describe pod -n chesterns # 查看pod
拿到pod的虛擬ip,開始測驗
?curl 10.244.36.75:5000/test curl 10.244.36.75:5001/test/calloneapi
滾動更新(RollingUpdate)與回滾
我們可以借助k8s的滾動更新實作服務的不停機更新,k8s也為我們提供了應對例外回滾的方法,下面就開始模擬
更新鏡像
kubectl set image deployment/chesterdeployment twoapi=registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest -n chesterns --record
查看更新狀態
kubectl rollout status deployment/chesterdeployment -n chesterns
查看更新歷史
kubectl rollout history deployment/chesterdeployment -n chesterns
回滾
kubectl rollout undo deployment/chesterdeployment -n chesterns kubectl rollout undo deployment/chesterdeployment -n chesterns --to-revision=1
滾動更新機制
-
啟動一個新的RS與新pod
-
等待新的 pod 進入 Ready 狀態
-
建立 Endpoint,將新的 pod 歸入負載均衡運維
-
移除與老 pod 相關的 Endpoint,而且將老 pod 狀態設定為 Terminating,此時將不會有新的請求到達老 pod
-
給老 pod 發送 SIGTERM 信號,而且等待 terminationGracePeriodSeconds 這么長的時間,(默認為 30 秒)
-
超過 terminationGracePeriodSeconds 等待時間直接強制 kill 行程并關閉舊的 pod
除了滾動更新,還有一種更新Recreate,這種模式會先殺掉所有正在運行的Pod,然后創建新的Pod
橫向擴展
k8s通過 kubectl scale即可快速實作pod的橫向擴展
kubectl scale deployment/chesterdeployment -n chesterns --replicas=10
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/447175.html
標籤:其他
