• 【云原生 | Kubernetes 实战】02、k8s 核心资源 Pod 介绍


    目录

    一、Pod是什么?

    白话解释:

    1.1 Pod如何管理多个容器?

    1.1.2 Pod网络

    1.1.3 Pod存储

    1.2 之前学习过容器(如docker),为什么还需要Pod?

    1.2.1 代码自动发版更新

    1.2.2 收集业务日志 

    1.3 Pod工作方式

    1.3.1 自主式Pod(不推荐)

    1.3.2 控制器管理的Pod(推荐)

    二、如何基于Pod运行应用?


    • K8s官方文档:https://kubernetes.io/
    • K8s中文官方文档: https://kubernetes.io/zh/
    • K8s Github地址:https://github.com/kubernetes/kubernetes
    • Pod资源对应的官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/

    一、Pod是什么?

            官方文档:https://kubernetes.io/docs/concepts/workloads/pods/

            Pod是Kubernetes中的最小调度单元,k8s是通过定义一个Pod的资源,然后在Pod里面运行容器,容器需要指定一个镜像,这样就可以用来运行具体的服务。一个Pod封装一个容器(也可以封装多个容器),Pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。

            Pod是需要调度到k8s集群的工作节点来运行的,具体调度到哪个节点,是根据scheduler调度器实现的。 

    白话解释:

            可以把pod看成是一个“豌豆荚”,里面有很多“豆子”(容器)。一个豌豆荚里可以有很多豆子(容器)

            pod相当于一个逻辑主机——比方说我们想要部署一个tomcat应用,如果不用容器,我们可能会部署到物理机、虚拟机或者云主机上,那么出现k8s之后,我们就可以定义一个pod资源,在pod里定义一个把tomcat容器,所以pod充当的是一个逻辑主机的角色。 

    1.1 Pod如何管理多个容器?

            Pod中可以同时运行多个容器。同一个Pod中的容器会自动的分配到同一个 node 上。同一个Pod中的容器共享资源、网络环境,它们总是被同时调度,在一个Pod中同时运行多个容器是一种比较高级的用法,只有当你的容器需要紧密配合协作的时候才考虑用这种模式。例如,你有一个容器作为web服务器运行,需要用到共享的volume,有另一个“sidecar”容器来从远端获取资源更新这些文件。

            一些Pod有init容器和应用容器。 在应用程序容器启动之前,运行初始化容器。

    1.1.2 Pod网络

            Pod是有IP地址的,假如pod不是共享物理机ip,由网络插件(calico、flannel、weave)划分的ip,每个pod都会被分配到唯一的IP地址。

    1. # 查看所有 pod 详细信息,包括pod 的状态、ip、分配的节点等信息
    2. [root@k8s-master01 ~]# kubectl get pod -A -owide
    3. # 或者查看指定命名空间下的pod
    4. [root@k8s-master01 ~]# kubectl get pods -n kube-system -owide

    Docker容器互联的方式:

            创建新容器的时候,通过--net container参数,指定其和已经存在的某个容器共享一个Network Namespace。如下图所示,右方黄色新创建的container,其网卡共享左边容器。因此就不会拥有自己独立的 IP,而是共享左边容器的 IP 172.17.0.2 、端口范围等网络资源。

    1. # 例如和已经存在的none容器共享网络
    2. [root@k8s-master01 ~]# docker run --name container2 --net=container:none -it centos --privileged=true

     docker 网络详解可用查看这篇文章:【云原生 | Docker 高级篇】06、Docker 网络模式详解_Stars.Sky的博客-CSDN博客

    Kubernetes中容器共享的方式:

            在k8s中,启动Pod时,会先启动⼀个pause 的容器,然后将后续的所有容器都 link 到这个pause 的容器,以实现⽹络共享。 

    1.1.3 Pod存储

            创建Pod的时候可以指定挂载的存储卷。 POD中的所有容器都可以访问共享卷,允许这些容器共享数据。 Pod只要挂载持久化数据卷,Pod重启之后数据还是会存在的。

    1.2 之前学习过容器(如docker),为什么还需要Pod?

            1、Pod是由一组紧耦合的容器组成的容器组,当然目前最流行的就是Docker、containerd、podman容器,Pod就可以作为1或者多个容器的载体。

            2、Pod中的所用容器会被一致调度、同节点部署,并且在一个“共享环境”中运行。把Pod想成一个车:车里面好多座位,每个座位都坐不同的人,每个座位想成是一个容器,这里的“共享环境”包括以下几点:

    • 1)所有容器共享一个IP地址和端口空间,意味着容器之间可以通过localhost高效访问,不能有端口冲突
    • 2)允许容器之间共享存储卷,通过文件系统交互信息

            3、有些容器需要紧密联系,需要一起工作。Pod提供了比容器更高层次的抽象, Pod中的所有容器使用同一个网络的namespace,即相同的IP地址和Port空间。它们可以直接用localhost通信。同样的,这些容器可以共享存储,当K8s挂载Volume到Pod上,本质上是将volume挂载到Pod中的每一个容器里。 

    1.2.1 代码自动发版更新

            假如生产环境部署了一个go的应用,而且部署了几百个节点,希望这个应用可以定时的同步最新的代码,以便自动升级线上环境。这时,我们不希望改动原来的go应用,可以开发一个Git代码仓库的自动同步服务,然后通过Pod的方式进行编排,并共享代码目录,就可以达到更新java应用代码的效果。

    1.2.2 收集业务日志 

            某服务模块已经实现了一些核心的业务逻辑,并且稳定运行了一段时间,日志记录在了某个目录下,按照不同级别分别为 error.log、access.log、warning.log、info.log,现在希望收集这些日志并发送到统一的日志处理服务器上。

            这时我们可以修改原来的服务模块,在其中添加日志收集、发送的服务,但这样可能会影响原来服务的配置、部署方式,从而带来不必要的问题和成本,也会增加业务逻辑和基础服务的藕合度。

            但如果使用Pod的方式,通过简单的编排,既可以保持原有服务逻辑、部署方式不变,又可以增加新的日志收集服务。

            而且如果我们对所有服务的日志生成有一个统一的标准,或者仅对日志收集服务稍加修改,就可以将日志收集服务和其他服务进行Pod编排,提供统一、标准的日志收集方式。

            这里的“核心业务服务”、“日志收集服务”分别是一个镜像,运行在隔离的容器环境中。 

    1.3 Pod工作方式

            在K8s中,所有的资源都可以使用一个yaml文件来创建,创建Pod也可以使用yaml配置文件。或者使用kubectl run在命令行创建Pod(不常用)。 

    1.3.1 自主式Pod(不推荐)

    所谓的自主式Pod,就是直接定义一个Pod资源,如下:

    1. #1. 创建pod yaml资源文件:
    2. [root@k8s-master01 pod-yaml]# vi pod-tomcat.yaml
    3. apiVersion: v1
    4. kind: Pod
    5. metadata:
    6. name: tomcat-test
    7. namespace: default
    8. labels:
    9. app: tomcat
    10. spec:
    11. containers:
    12. - name: tomcat-java
    13. ports:
    14. - containerPort: 8080
    15. image: tomcat:latest
    16. imagePullPolicy: IfNotPresent
    17. #2. k8s集群(三台机子都要)拉取相关镜像
    18. docker pull tomcat
    19. #3. 创建pod
    20. [root@k8s-master01 pod-yaml]# kubectl apply -f pod-tomcat.yaml
    21. #4. 查看pod是否创建成功
    22. [root@k8s-master01 pod-yaml]# kubectl get pods -owide -l app=tomcat
    23. [root@k8s-master01 pod-yaml]# kubectl get pods

    但是自主式Pod是存在一个问题的,假如我们不小心删除了pod:

    1. [root@k8s-master01 pod-yaml]# kubectl delete pods tomcat-test
    2. pod "tomcat-test" deleted
    3. # 查看pod是否还在
    4. [root@k8s-master01 pod-yaml]# kubectl get pods
    5. No resources found in default namespace.
    6. [root@k8s-master01 pod-yaml]# kubectl get pods -l app=tomcat
    7. No resources found in default namespace.

            结果是空,说明pod已经被删除了通过上面可以看到,如果直接定义一个Pod资源,那Pod被删除,就彻底被删除了,不会再创建一个新的Pod,这在生产环境还是具有非常大风险的,所以今后我们接触的Pod,都是控制器管理的。 

    1.3.2 控制器管理的Pod(推荐)

            常见的管理Pod的控制器:Replicaset、Deployment、Job、CronJob、Daemonset、Statefulset。控制器管理的Pod可以确保Pod始终维持在指定的副本数运行。如,通过Deployment管理Pod 

    1. #1. k8s集群拉取 nginx 镜像
    2. docker pull nginx
    3. #2. 创建资源清单文件
    4. [root@k8s-master01 pod-yaml]# vi pod-nginx.yaml
    5. apiVersion: apps/v1
    6. kind: Deployment
    7. metadata:
    8. name: nginx-test
    9. labels:
    10. app: nginx-deploy
    11. spec:
    12. selector:
    13. matchLabels:
    14. app: nginx
    15. replicas: 2
    16. template:
    17. metadata:
    18. labels:
    19. app: nginx
    20. spec:
    21. containers:
    22. - name: my-nginx
    23. image: nginx:latest
    24. imagePullPolicy: IfNotPresent
    25. ports:
    26. - containerPort: 80
    27. #3. 更新资源清单文件
    28. [root@k8s-master01 pod-yaml]# kubectl apply -f pod-nginx.yaml
    29. #4. 查看pods
    30. [root@k8s-master01 pod-yaml]# kubectl get pods
    31. NAME READY STATUS RESTARTS AGE
    32. nginx-test-7767bdd4d-r4qt7 1/1 Running 0 33s
    33. nginx-test-7767bdd4d-rqrm5 1/1 Running 0 33s
    34. # 查看Deployment
    35. [root@k8s-master01 pod-yaml]# kubectl get deployments.apps
    36. NAME READY UP-TO-DATE AVAILABLE AGE
    37. nginx-test 2/2 2 2 49s
    38. #5. 删除一个pod
    39. [root@k8s-master01 pod-yaml]# kubectl delete pods nginx-test-7767bdd4d-r4qt7
    40. pod "nginx-test-7767bdd4d-r4qt7" deleted
    41. #6. 再次查看,立马又重新创建了一个pod
    42. [root@k8s-master01 pod-yaml]# kubectl get pods
    43. NAME READY STATUS RESTARTS AGE
    44. nginx-test-7767bdd4d-d5pqv 1/1 Running 0 8s
    45. nginx-test-7767bdd4d-rqrm5 1/1 Running 0 3m52s

    通过上面可以发现通过deployment管理的pod,可以确保pod始终维持在指定副本数量。 

    二、如何基于Pod运行应用?

    创建pod流程: 

    kubectl apply -f pod-nginx.yaml->找到(/root/.kube/config)config文件,基于config文件指定的用户访问指定的集群,这样就找到了apiserver 

    第一步: 通过 kubectl 命令向 apiserver 提交创建pod的请求,apiserver接收到pod创建请求后,会将pod的属性信息(metadata)写入etcd。

    第二步:apiserver触发watch机制准备创建pod,信息转发给调度器scheduler,调度器使用调度算法选择node,调度器将node信息给apiserver,apiserver将绑定的node信息写入etcd

    第三步:apiserver又通过watch机制,调用kubelet,指定pod信息,调用容器运行时创建并启动pod内的容器。

    第四步:创建完成之后反馈给kubelet, kubelet又将pod的状态信息给apiserver, apiserver又将pod的状态信息写入etcd。

    上一篇文章:【云原生 | Kubernetes 实战】01、K8s-v1.25集群搭建和部署基于网页的 K8s 用户界面 Dashboard_Stars.Sky的博客-CSDN博客​​​​​​​

    下一篇文章:【云原生 | Kubernetes 实战】03、手把手教你基于YAML文件运行pod应用_Stars.Sky的博客-CSDN博客

  • 相关阅读:
    天翼云服务器80、443等特殊端口无法访问原因记录
    代码随想录算法训练营第十一天|20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值
    云原生之Kubernetes:16、详解Operator控制器
    化学制品制造业数智化供应链管理系统:构建智能供应链体系,实现供应链协同响应
    Eolink 微光计划
    AUTOSAR知识点 之NvM(一):存储栈整体介绍(偏从ASW到BSW的配置与基础概念性质)
    在模拟现货黄金中锻炼短线的修养
    【Python自然语言处理】使用SVM、随机森林法、梯度法等多种方法对病人罹患癌症预测实战(超详细 附源码)
    cadence layout lvs时出现error
    Pinia与Vuex使用区别
  • 原文地址:https://blog.csdn.net/weixin_46560589/article/details/127872047