【云原生】Kubernetes核心技术(上)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: Kubernetes核心技术(上)

 

部署 Pod,Deployment 与 Service

博主昵称:跳楼梯企鹅
博主主页面链接:博主主页传送门

博主专栏页面连接:专栏传送门--网路安全技术
创作初心:本博客的初心为与技术朋友们相互交流,每个人的技术都存在短板,博主也是一样,虚心求教,希望各位技术友给予指导。
博主座右铭:发现光,追随光,成为光,散发光;
博主研究方向:渗透测试、机器学习 ;
博主寄语:感谢各位技术友的支持,您的支持就是我前进的动力 ;

图片.png

本篇文章分为3次分享完

一、Pod

1.概述

Pod 是 K8S 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在 K8S 上运行容器化应用的资源对象,其它的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,K8S 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成

Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为 “根容器”的 Pause 容器Pause 容器对应的镜像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器

image.gif图片.png

2.概念以及意义

    • 最小部署的单元
    • Pod 里面是由一个或多个容器组成【一组容器的集合】
    • 一个 pod 中的容器是共享网络命名空间
    • Pod 生命周期是短暂的
    • 每个 Pod 包含一个或多个紧密相关的用户业务容器

    意义:Pod 是在 K8S 集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。同时 Pod 对多容器的支持是 K8S 中最基础的设计理念。在生产环境中,通常是由不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。

    3.分类

      • 长期伺服型:long-running
      • 批处理型:batch
      • 节点后台支撑型:node-daemon
      • 有状态应用型:stateful application

      4.Pod机制

      主要有以下两大机制

        • 共享网络
        • 共享存储

        (1)共享网络:

        容器本身之间相互隔离的,一般是通过 namespace 和 group 进行隔离,那么Pod里面的容器如何实现通信?

        首先需要满足前提条件,也就是容器都在同一个namespace之间关于Pod实现原理,首先会在Pod会创建一个根容器: pause容器然后我们在创建业务容器 【nginx,redis 等】,在我们创建业务容器的时候,会把它添加到 info容器

        而在 info容器 中会独立出 ip地址,mac地址,port 等信息,然后实现网络的共享

        (2)共享存储:


        image.gif图片.png

        5.常用命令

        # 查看所有的 pod 列表,-n 后面跟 namespace,查看指定的命名空间,-o wide 查看详细信息
        kubectl get pod
        kubectl get pod -n kube-system  # 查看 kube-system 命名空间下的 pod
        kubectl get pod -o wide # 查看 pod 的详细信息,有 ip、node 节点等信息
        # 显示 Node 的详细信息
        kubectl describe node dce-10-6-215-190 # node 后面的是 node名称
        # 显示 Pod 的详细信息, 特别是查看 pod 无法创建的时候的日志
        kubectl describe pod web # web 是你创建 pod 时起的名称
        # 根据 yaml 创建资源, apply 可以重复执行,create 不行
        kubectl create -f pod.yaml
        kubectl apply -f pod.yaml
        # 删除所有 Pod
        kubectl delete pod --all
        # 强制删除某个文件名命名节点 ,基于 pod.yaml 定义的名称删除 pod 
        kubectl delete -f <文件名>
        # 删除某个Pod命令节点 
        kubectl delete pod <pod名>
        # 删除某个Replication Controller命名节点 
        kubectl delete rc <rc名>
        kubectl delete deployment 名称
        # 删除某个服务命名节点 
        kubectl delete service <service名>
        # 删除所有Pod节点 
        kubectl delete pod --all

        image.gif

        二、Deployment

        1.概述
        图片.png

        Deployment 是 k8s 中一种重要的pod控制器,主要用于实现控制 Pod 的副本数量和水平伸缩以及版本更新。起到一个实现应用程序级别的资源模拟的作用。

        2.Deployment的两大功能

        通过上面简单的介绍,我们已经大概了解了Deployment, ReplicaSet,以及 Pod 的关系,他们实际上是一种“层层控制”的关系。

        那么,Deployment的作用到底是什么,又为什么需要 ReplicaSet 来间接控制 Pod 呢,答案就是为了实现水平扩展 / 收缩和滚动更新功能。

        水平扩展 / 收缩

        “水平扩展 / 收缩”非常容易实现,Deployment Controller 只需要修改它所控制的 ReplicaSet 的 Pod 副本个数就可以了。

        滚动更新

        应用的发布和升级是运维最重要的核心职能之一,那么部署在K8S中的应用是怎么发布升级的呢?其实,你只要编辑修改下 Deployment 的 yaml 文件中镜像版本号,再 apply 一下,就更新成功了,但是具体的实现过程又是怎么样的呢?

        在 K8S 中可以使用 kubectl rollout命令来查看 Deployment 对象的状态变化。

        3. Deployment常用字段

        apiVersion: apps/v1     # API群组和版本
        kind: Deployment      # 资源类型
        metadata:
          name <string>       # 资源名称,名称空间中要唯一
          namespace <string>            # 名称空间
        spec:
          minReadySeconds <integer>   # Pod就绪后多少秒后没有容器crash才视为“就绪”
          replicas <integer>      # Pod副本数,默认为1
          selector <object>     # 标签选择器,必须和template字段中Pod的标签一致
          template <object>     # 定义Pod模板
          revisionHistoryLimit <integer>  # 滚动更新历史记录数量,默认为10
          strategy <Object>     # 滚动更新策略
            type <string>     # 滚动更新类型,默认为RollingUpdate
            rollingUpdate <Object>    # 滚动更新参数,只能用于RollingUpdate类型
              maxSurge <string>     # 更新期间可以比replicas定义的数量多出的数量或比例
              maxUnavailable <string>   # 更新期间可以比replicas定义的数少的数量或比例 
          progressDeadlineSeconds <integer> # 滚动更新故障超时时长,默认为600秒
          paused <boolean>      # 是否暂停部署

        image.gif

        4.代码实操

        #运行一个deployment
        [root@ken ~]# kubectl run httpd-ken1--generator=run-pod/v1 --image=httpd --replicas=2
        #详细分析 Kubernetes
        [root@ken ~]# kubectl get deployment
        NAME        READY   UP-TO-DATE   AVAILABLE   AGE
        httpd-ken   2/2     2            2           35m
        #kubectl get deplouyment命令可以查看 httpd-ken 的状态
        [root@ken ~]# kubectl  describe deployment httpd-ken
        Name:                   httpd-ken
        Namespace:              default
        CreationTimestamp:      Tue, 29 Jan 2019 15:27:40 +0800
        Labels:                 run=httpd-ken
        Annotations:            deployment.kubernetes.io/revision: 1
        Selector:               run=httpd-ken
        Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
        StrategyType:           RollingUpdate
        MinReadySeconds:        0
        RollingUpdateStrategy:  25% max unavailable, 25% max surge
        Pod Template:
          Labels:  run=httpd-ken
          Containers:
           httpd-ken:
            Image:        httpd
            Port:         <none>
            Host Port:    <none>
            Environment:  <none>
            Mounts:       <none>
          Volumes:        <none>
        Conditions:
          Type           Status  Reason
          ----           ------  ------
          Available      True    MinimumReplicasAvailable
          Progressing    True    NewReplicaSetAvailable
        OldReplicaSets:  <none>
        NewReplicaSet:   httpd-ken-5c949b96f (2/2 replicas created)
        Events:
          Type    Reason             Age   From                   Message
          ----    ------             ----  ----                   -------
          Normal  ScalingReplicaSet  18m   deployment-controller  Scaled up replica set httpd-ken-5c949b96f to 2
        kubectl describe replicaset:
        [root@ken ~]# kubectl get replicaset
        NAME                  DESIRED   CURRENT   READY   AGE
        httpd-ken-5c949b96f   2         2         2       20m
        #用 kubectl describe replicaset 查看详细信息:
        [root@ken ~]# kubectl describe replicaset
        Name:           httpd-ken-5c949b96f
        Namespace:      default
        Selector:       pod-template-hash=5c949b96f,run=httpd-ken
        Labels:         pod-template-hash=5c949b96f
                        run=httpd-ken
        Annotations:    deployment.kubernetes.io/desired-replicas: 2
                        deployment.kubernetes.io/max-replicas: 3
                        deployment.kubernetes.io/revision: 1
        Controlled By:  Deployment/httpd-ken
        Replicas:       2 current / 2 desired
        Pods Status:    2 Running / 0 Waiting / 0 Succeeded / 0 Failed
        Pod Template:
          Labels:  pod-template-hash=5c949b96f
                   run=httpd-ken
          Containers:
           httpd-ken:
            Image:        httpd
            Port:         <none>
            Host Port:    <none>
            Environment:  <none>
            Mounts:       <none>
          Volumes:        <none>
        Events:
          Type    Reason            Age   From                   Message
          ----    ------            ----  ----                   -------
          Normal  SuccessfulCreate  20m   replicaset-controller  Created pod: httpd-ken-5c949b96f-twdsd
          Normal  SuccessfulCreate  20m   replicaset-controller  Created pod: httpd-ken-5c949b96f-9cd52
        #执行 kubectl get pod:
        [root@ken ~]# kubectl get pod
        NAME                        READY   STATUS    RESTARTS   AGE
        httpd-ken-5c949b96f-9cd52   1/1     Running   0          22m
        httpd-ken-5c949b96f-twdsd   1/1     Running   0          22m
        #用 kubectl describe pod 查看更详细的信息:
        root@ken ~]# kubectl describe pod
        Name:               httpd-ken-5c949b96f-9cd52
        Namespace:          default
        Priority:           0
        PriorityClassName:  <none>
        Node:               host1/172.20.10.7
        Start Time:         Tue, 29 Jan 2019 15:46:45 +0800
        Labels:             pod-template-hash=5c949b96f
                            run=httpd-ken
        Annotations:        <none>
        Status:             Running
        IP:                 10.244.1.3
        Controlled By:      ReplicaSet/httpd-ken-5c949b96f
        Containers:
          httpd-ken:
            Container ID:   docker://e59bda9941a16f20027c89a0d8fa8e17797b517f6f5461e905c0d29b57369dde
            Image:          httpd
            Image ID:       docker-pullable://httpd@sha256:44daa8e932a32ab6e50636d769ca9a60ad412124653707e5ed59c0209c72f9b3
            Port:           <none>
            Host Port:      <none>
            State:          Running
              Started:      Tue, 29 Jan 2019 15:47:10 +0800
            Ready:          True
            Restart Count:  0
            Environment:    <none>
            Mounts:
              /var/run/secrets/kubernetes.io/serviceaccount from default-token-vb7lm (ro)
        Conditions:
          Type              Status
          Initialized       True 
          Ready             True 
          ContainersReady   True 
          PodScheduled      True 
        Volumes:
          default-token-vb7lm:
            Type:        Secret (a volume populated by a Secret)
            SecretName:  default-token-vb7lm
            Optional:    false
        QoS Class:       BestEffort
        Node-Selectors:  <none>
        Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                         node.kubernetes.io/unreachable:NoExecute for 300s
        Events:
          Type    Reason     Age   From               Message
          ----    ------     ----  ----               -------
          Normal  Scheduled  23m   default-scheduler  Successfully assigned default/httpd-ken-5c949b96f-9cd52 to host1
          Normal  Pulling    23m   kubelet, host1     pulling image "httpd"
          Normal  Pulled     22m   kubelet, host1     Successfully pulled image "httpd"
          Normal  Created    22m   kubelet, host1     Created container
          Normal  Started    22m   kubelet, host1     Started container

        image.gif

        三、Service

        1.概述

        Pod是非永久性资源,会动态创建和销毁,pod的ip会变化。这会导致一类Pod(业务1)访问另一类Pod(业务2)需要找出并跟踪Pod(业务2)的IP地址,再者Pod(业务2)是多个的,如何提供负载均衡呢?虽然Pod1通过轮询一组Pod的ip可以实现,但会Pod就需要增加负载均衡的逻辑,Pod就变得不纯粹了,不符合单一设计原则。于是有了Service,把一类Pods上的应用程序抽象成服务,并提供可以访问他们的策略。

        2.通过Service访问Pod

        指定 spec.selector即通过打标签的方式

        apiVersion: v1
        kind: Service
        metadata:
          name: my-service
        spec:
          selector:
            app: MyApp
          ports:
            - protocol: TCP
              port: 80
              targetPort: 9376

        image.gif

        自动创建相应的 Endpoint 对象

        kubectl describe ep/my-service

        image.gif

        自动创建的Endpoint对象

        Subsets:
             Addresses: 10.244.2.1,10.244.4.1

        image.gif

        3.Service的三种主要形式

          • ClusterIP: 仅仅使用一个集群内部的IP地址 - 这是默认值。选择这个值意味着你只想这个服务在集群内部才可以被访问到
          • NodePort: 在集群内部IP的基础上,在集群的每一个节点的端口上开放这个服务。你可以在任意:NodePort地址上访问到这个服务。
          • LoadBalancer: 在使用一个集群内部IP地址和在NodePort上开放一个服务之外,向云提供商申请一个负载均衡器,会让流量转发到这个在每个节点上以:NodePort的形式开放的服务上。

          4.部署

          (1)配置文件如下

          spec.selector: 指定如何选择 Pod

          spec.ports: 指定如何暴露端

          apiVersion: v1
          kind: Service
          metadata:
            name: nginx-service
          spec:
            selector:
              app: nginx
            ports:
            - protocol: TCP
              port: 80
              targetPort: 80

          image.gif

          使用 kubectl apply 部署,查看 Service 状态

          $ kubectl get svc nginx-service -o wide
          NAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
          nginx-service   ClusterIP   10.108.9.49   <none>        80/TCP    11m   app=nginx

          image.gif

          ClusterIP 代表服务只能在集群内部访问,此时我们访问服务

          $ curl 指定ip
          <!DOCTYPE html>
          <html>
          <head>
          <title>Welcome to nginx!</title>
          <style>
              body {
                  width: 35em;
                  margin: 0 auto;
                  font-family: Tahoma, Verdana, Arial, sans-serif;
              }
          </style>
          </head>
          <body>
          <h1>Welcome to nginx!</h1>
          <p>If you see this page, the nginx web server is successfully installed and
          working. Further configuration is required.</p>
          <p>For online documentation and support please refer to
          <a href="http://nginx.org/">nginx.org</a>.<br/>
          Commercial support is available at
          <a href="http://nginx.com/">nginx.com</a>.</p>
          <p><em>Thank you for using nginx.</em></p>
          </body>
          </html>

          image.gif

          服务发现,知道服务的ip就可以访问服务

          在 k8s 中,服务可以通过 my-svc.my-namespace.svc.cluster.local 发现

          对于刚才部署的 Service 就是 nginx-service.default.svc.cluster.local

          在集群中的任意一个 Pod 中通过域名访问

          $ curl nginx-service.default.svc.cluster.local
          <!DOCTYPE html>
          <html>
          <head>
          <title>Welcome to nginx!</title>
          <style>
              body {
                  width: 35em;
                  margin: 0 auto;
                  font-family: Tahoma, Verdana, Arial, sans-serif;
              }
          </style>
          </head>
          <body>
          <h1>Welcome to nginx!</h1>
          <p>If you see this page, the nginx web server is successfully installed and
          working. Further configuration is required.</p>
          <p>For online documentation and support please refer to
          <a href="http://nginx.org/">nginx.org</a>.<br/>
          Commercial support is available at
          <a href="http://nginx.com/">nginx.com</a>.</p>
          <p><em>Thank you for using nginx.</em></p>
          </body>
          </html>

          image.gif

          四、小结

          本次主要分享部署 Pod,Deployment 与 Service,后期还有两篇将进一步深入讲解。

          尽情期待

          相关实践学习
          通过Ingress进行灰度发布
          本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
          容器应用与集群管理
          欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
          相关文章
          |
          4天前
          |
          边缘计算 运维 Cloud Native
          浙江省科技进步奖一等奖!阿里云云原生技术实现新突破
          科技成果鉴定委员会高度评价该技术,“项目研发难度大,成果创新性强,对促进关键技术进步及自主可控具有重大意义,成果在国内外开源社区产生了广泛影响,并成功应用于互联网、交通、金融、物流、医疗等多个行业。”
          |
          10天前
          |
          运维 Kubernetes Cloud Native
          云原生技术:容器化与微服务架构的完美结合
          【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其灵活性和高效性成为企业的新宠。本文将深入探讨云原生的核心概念,包括容器化技术和微服务架构,以及它们如何共同推动现代应用的发展。我们将通过实际代码示例,展示如何在Kubernetes集群上部署一个简单的微服务,揭示云原生技术的强大能力和未来潜力。
          |
          8天前
          |
          运维 Kubernetes Cloud Native
          云原生技术入门及实践
          【10月更文挑战第39天】在数字化浪潮的推动下,云原生技术应运而生,它不仅仅是一种技术趋势,更是企业数字化转型的关键。本文将带你走进云原生的世界,从基础概念到实际操作,一步步揭示云原生的魅力和价值。通过实例分析,我们将深入探讨如何利用云原生技术提升业务灵活性、降低成本并加速创新。无论你是云原生技术的初学者还是希望深化理解的开发者,这篇文章都将为你提供宝贵的知识和启示。
          |
          4天前
          |
          监控 Cloud Native 持续交付
          云原生技术在现代企业中的应用与实践
          本文将深入探讨云原生技术如何改变现代企业的运作模式,提升业务灵活性和创新能力。通过实际案例分析,我们将揭示云原生架构的关键要素、实施步骤以及面临的挑战,为读者提供一套清晰的云原生转型指南。
          |
          6天前
          |
          Kubernetes Cloud Native 开发者
          云原生入门:Kubernetes的简易指南
          【10月更文挑战第41天】本文将带你进入云原生的世界,特别是Kubernetes——一个强大的容器编排平台。我们将一起探索它的基本概念和操作,让你能够轻松管理和部署应用。无论你是新手还是有经验的开发者,这篇文章都能让你对Kubernetes有更深入的理解。
          |
          4天前
          |
          边缘计算 运维 Cloud Native
          阿里云基于云原生的大规模云边协同关键技术及应用荣获浙江省科学技术进步一等奖
          11月22日, 2023年度浙江省科学技术奖获奖成果公布,阿里云与浙江大学、支付宝、谐云科技联合完成的基于云原生的大规模云边协同关键技术及应用获得浙江省科学技术进步一等奖。
          |
          10天前
          |
          Cloud Native 持续交付 云计算
          云原生技术入门与实践
          【10月更文挑战第37天】本文旨在为初学者提供云原生技术的基础知识和实践指南。我们将从云原生的概念出发,探讨其在现代软件开发中的重要性,并介绍相关的核心技术。通过实际的代码示例,我们展示了如何在云平台上部署和管理应用,以及如何利用云原生架构提高系统的可伸缩性、弹性和可靠性。无论你是云原生领域的新手,还是希望深化理解的开发者,这篇文章都将为你打开一扇通往云原生世界的大门。
          |
          8天前
          |
          弹性计算 Kubernetes Cloud Native
          云原生技术的实践与思考
          云原生技术的实践与思考
          23 2
          |
          9天前
          |
          Kubernetes Cloud Native 持续交付
          云原生技术在现代应用架构中的实践与思考
          【10月更文挑战第38天】随着云计算的不断成熟和演进,云原生(Cloud-Native)已成为推动企业数字化转型的重要力量。本文从云原生的基本概念出发,深入探讨了其在现代应用架构中的实际应用,并结合代码示例,展示了云原生技术如何优化资源管理、提升系统弹性和加速开发流程。通过分析云原生的优势与面临的挑战,本文旨在为读者提供一份云原生转型的指南和启示。
          25 3
          |
          8天前
          |
          边缘计算 Cloud Native 安全
          云原生技术的未来发展趋势
          云原生技术的未来发展趋势
          24 1
          下一篇
          无影云桌面