K8S原來如此簡單(三)Pod+Deployment


上篇我們已經安裝好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

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來部署。

用途

  1. 方便管理、部署Pod

  2. 橫擴應對高負載

  3. 快速程序更新與回滾

創建

首先我們創建一個文件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

滾動更新機制

 

  1. 啟動一個新的RS與新pod

  2. 等待新的 pod 進入 Ready 狀態

  3. 建立 Endpoint,將新的 pod 歸入負載均衡運維

  4. 移除與老 pod 相關的 Endpoint,而且將老 pod 狀態設置為 Terminating,此時將不會有新的請求到達老 pod

  5. 給老 pod 發送 SIGTERM 信號,而且等待 terminationGracePeriodSeconds 這么長的時間。(默認為 30 秒)

  6. 超過 terminationGracePeriodSeconds 等待時間直接強制 kill 進程並關閉舊的 pod

 

除了滾動更新,還有一種更新Recreate,這種模式會先殺掉所有正在運行的Pod,然后創建新的Pod

橫向擴展

k8s通過 kubectl scale即可快速實現pod的橫向擴展

kubectl scale deployment/chesterdeployment -n chesterns --replicas=10


免責聲明!

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



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