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


     部署 Pod,Deployment 与 Service

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

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

    本篇文章分为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 还包含一个或多个紧密相关的用户业务容器

     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)共享存储:

    5.常用命令

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

    二、Deployment

    1.概述

      

     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常用字段

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

      1. #运行一个deployment
      2. [root@ken ~]# kubectl run httpd-ken1--generator=run-pod/v1 --image=httpd --replicas=2
      3. #详细分析 Kubernetes
      4. [root@ken ~]# kubectl get deployment
      5. NAME READY UP-TO-DATE AVAILABLE AGE
      6. httpd-ken 2/2 2 2 35m
      7. #kubectl get deplouyment命令可以查看 httpd-ken 的状态
      8. [root@ken ~]# kubectl describe deployment httpd-ken
      9. Name: httpd-ken
      10. Namespace: default
      11. CreationTimestamp: Tue, 29 Jan 2019 15:27:40 +0800
      12. Labels: run=httpd-ken
      13. Annotations: deployment.kubernetes.io/revision: 1
      14. Selector: run=httpd-ken
      15. Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
      16. StrategyType: RollingUpdate
      17. MinReadySeconds: 0
      18. RollingUpdateStrategy: 25% max unavailable, 25% max surge
      19. Pod Template:
      20. Labels: run=httpd-ken
      21. Containers:
      22. httpd-ken:
      23. Image: httpd
      24. Port: <none>
      25. Host Port: <none>
      26. Environment: <none>
      27. Mounts: <none>
      28. Volumes: <none>
      29. Conditions:
      30. Type Status Reason
      31. ---- ------ ------
      32. Available True MinimumReplicasAvailable
      33. Progressing True NewReplicaSetAvailable
      34. OldReplicaSets: <none>
      35. NewReplicaSet: httpd-ken-5c949b96f (2/2 replicas created)
      36. Events:
      37. Type Reason Age From Message
      38. ---- ------ ---- ---- -------
      39. Normal ScalingReplicaSet 18m deployment-controller Scaled up replica set httpd-ken-5c949b96f to 2
      40. kubectl describe replicaset:
      41. [root@ken ~]# kubectl get replicaset
      42. NAME DESIRED CURRENT READY AGE
      43. httpd-ken-5c949b96f 2 2 2 20m
      44. #用 kubectl describe replicaset 查看详细信息:
      45. [root@ken ~]# kubectl describe replicaset
      46. Name: httpd-ken-5c949b96f
      47. Namespace: default
      48. Selector: pod-template-hash=5c949b96f,run=httpd-ken
      49. Labels: pod-template-hash=5c949b96f
      50. run=httpd-ken
      51. Annotations: deployment.kubernetes.io/desired-replicas: 2
      52. deployment.kubernetes.io/max-replicas: 3
      53. deployment.kubernetes.io/revision: 1
      54. Controlled By: Deployment/httpd-ken
      55. Replicas: 2 current / 2 desired
      56. Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
      57. Pod Template:
      58. Labels: pod-template-hash=5c949b96f
      59. run=httpd-ken
      60. Containers:
      61. httpd-ken:
      62. Image: httpd
      63. Port: <none>
      64. Host Port: <none>
      65. Environment: <none>
      66. Mounts: <none>
      67. Volumes: <none>
      68. Events:
      69. Type Reason Age From Message
      70. ---- ------ ---- ---- -------
      71. Normal SuccessfulCreate 20m replicaset-controller Created pod: httpd-ken-5c949b96f-twdsd
      72. Normal SuccessfulCreate 20m replicaset-controller Created pod: httpd-ken-5c949b96f-9cd52
      73. #执行 kubectl get pod:
      74. [root@ken ~]# kubectl get pod
      75. NAME READY STATUS RESTARTS AGE
      76. httpd-ken-5c949b96f-9cd52 1/1 Running 0 22m
      77. httpd-ken-5c949b96f-twdsd 1/1 Running 0 22m
      78. #用 kubectl describe pod 查看更详细的信息:
      79. root@ken ~]# kubectl describe pod
      80. Name: httpd-ken-5c949b96f-9cd52
      81. Namespace: default
      82. Priority: 0
      83. PriorityClassName: <none>
      84. Node: host1/172.20.10.7
      85. Start Time: Tue, 29 Jan 2019 15:46:45 +0800
      86. Labels: pod-template-hash=5c949b96f
      87. run=httpd-ken
      88. Annotations: <none>
      89. Status: Running
      90. IP: 10.244.1.3
      91. Controlled By: ReplicaSet/httpd-ken-5c949b96f
      92. Containers:
      93. httpd-ken:
      94. Container ID: docker://e59bda9941a16f20027c89a0d8fa8e17797b517f6f5461e905c0d29b57369dde
      95. Image: httpd
      96. Image ID: docker-pullable://httpd@sha256:44daa8e932a32ab6e50636d769ca9a60ad412124653707e5ed59c0209c72f9b3
      97. Port: <none>
      98. Host Port: <none>
      99. State: Running
      100. Started: Tue, 29 Jan 2019 15:47:10 +0800
      101. Ready: True
      102. Restart Count: 0
      103. Environment: <none>
      104. Mounts:
      105. /var/run/secrets/kubernetes.io/serviceaccount from default-token-vb7lm (ro)
      106. Conditions:
      107. Type Status
      108. Initialized True
      109. Ready True
      110. ContainersReady True
      111. PodScheduled True
      112. Volumes:
      113. default-token-vb7lm:
      114. Type: Secret (a volume populated by a Secret)
      115. SecretName: default-token-vb7lm
      116. Optional: false
      117. QoS Class: BestEffort
      118. Node-Selectors: <none>
      119. Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
      120. node.kubernetes.io/unreachable:NoExecute for 300s
      121. Events:
      122. Type Reason Age From Message
      123. ---- ------ ---- ---- -------
      124. Normal Scheduled 23m default-scheduler Successfully assigned default/httpd-ken-5c949b96f-9cd52 to host1
      125. Normal Pulling 23m kubelet, host1 pulling image "httpd"
      126. Normal Pulled 22m kubelet, host1 Successfully pulled image "httpd"
      127. Normal Created 22m kubelet, host1 Created container
      128. Normal Started 22m kubelet, host1 Started container

      三、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即通过打标签的方式

      1. apiVersion: v1
      2. kind: Service
      3. metadata:
      4. name: my-service
      5. spec:
      6. selector:
      7. app: MyApp
      8. ports:
      9. - protocol: TCP
      10. port: 80
      11. targetPort: 9376

       自动创建相应的 Endpoint 对象

      kubectl describe ep/my-service
      

      自动创建的Endpoint对象

      1. Subsets:
      2. Addresses: 10.244.2.1,10.244.4.1

      3.Service的三种主要形式

      • ClusterIP: 仅仅使用一个集群内部的IP地址 - 这是默认值。选择这个值意味着你只想这个服务在集群内部才可以被访问到

      • NodePort: 在集群内部IP的基础上,在集群的每一个节点的端口上开放这个服务。你可以在任意:NodePort地址上访问到这个服务。

      • LoadBalancer: 在使用一个集群内部IP地址和在NodePort上开放一个服务之外,向云提供商申请一个负载均衡器,会让流量转发到这个在每个节点上以:NodePort的形式开放的服务上。

       4.部署

      (1)配置文件如下

       spec.selector: 指定如何选择 Pod

       spec.ports: 指定如何暴露端

      1. apiVersion: v1
      2. kind: Service
      3. metadata:
      4. name: nginx-service
      5. spec:
      6. selector:
      7. app: nginx
      8. ports:
      9. - protocol: TCP
      10. port: 80
      11. targetPort: 80

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

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

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

      1. $ curl 指定ip
      2. html>
      3. <html>
      4. <head>
      5. <title>Welcome to nginx!title>
      6. <style>
      7. body {
      8. width: 35em;
      9. margin: 0 auto;
      10. font-family: Tahoma, Verdana, Arial, sans-serif;
      11. }
      12. style>
      13. head>
      14. <body>
      15. <h1>Welcome to nginx!h1>
      16. <p>If you see this page, the nginx web server is successfully installed and
      17. working. Further configuration is required.p>
      18. <p>For online documentation and support please refer to
      19. <a href="http://nginx.org/">nginx.orga>.<br/>
      20. Commercial support is available at
      21. <a href="http://nginx.com/">nginx.coma>.p>
      22. <p><em>Thank you for using nginx.em>p>
      23. body>
      24. html>

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

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

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

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

      1. $ curl nginx-service.default.svc.cluster.local
      2. html>
      3. <html>
      4. <head>
      5. <title>Welcome to nginx!title>
      6. <style>
      7. body {
      8. width: 35em;
      9. margin: 0 auto;
      10. font-family: Tahoma, Verdana, Arial, sans-serif;
      11. }
      12. style>
      13. head>
      14. <body>
      15. <h1>Welcome to nginx!h1>
      16. <p>If you see this page, the nginx web server is successfully installed and
      17. working. Further configuration is required.p>
      18. <p>For online documentation and support please refer to
      19. <a href="http://nginx.org/">nginx.orga>.<br/>
      20. Commercial support is available at
      21. <a href="http://nginx.com/">nginx.coma>.p>
      22. <p><em>Thank you for using nginx.em>p>
      23. body>
      24. html>

      四、小结

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

      尽情期待

    20. 相关阅读:
      PROJECT #1 - BUFFER POOL [CMU 15-445645]笔记
      玩转cropperjs图片裁剪及数据提交文件流互相转换详解
      pytorch 33 使用mmdeploy将mmdetection模型转换为onnx,并实现c++部署(支持动态nms)
      软件项目和安全项目案例(承接软件和安全项目合作)
      [数据结构] 串与KMP算法详解
      Ubuntu22.04配置Go环境
      Ceph入门到精通-Macvlan网络模式
      orderby是如何工作的?
      Spring Statement 状态机应用实例
      SpringCloud原生组件之Eureka服务注册中心
    21. 原文地址:https://blog.csdn.net/weixin_50481708/article/details/126357546