暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

K8S原来如此简单(三)Pod+Deployment

chester技术分享 2022-03-26
499

k8s视频课程

上篇我们已经安装好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.yaml
                            kubectl describe pod -n chesterapi


                            Deployemnt

                            说完了pod,我们来看看deployment。生产环境中基本不存在直接定义pod的方式来部署项目,更多的是通过Deployment来部署。

                            用途

                            1. 方便管理、部署Pod

                            2. 横扩应对高负载

                            3. 快速程序更新与回滚

                            创建

                            首先我们创建一个文件ns.yaml来定义一个namespace

                              apiVersion: v1
                              kind: Namespace
                              metadata:
                              name: chesterns
                                kubectl apply -f ns.yaml

                                我们通过定义以下一个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的横向扩展

                                              k8s通过 kubectl scale即可快速实现pod的横向扩展

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

                                                关注我获取技术分享


                                                文章转载自chester技术分享,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                评论