写点什么

【云原生 | 从零开始学 Kubernetes】五、Kubernetes 核心技术 Pod

作者:泡泡
  • 2022 年 9 月 23 日
    河北
  • 本文字数:3563 字

    阅读完需:约 12 分钟

【云原生 | 从零开始学Kubernetes】五、Kubernetes核心技术Pod

Pod 概述

Pod 是 K8S 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在 K8S 上运行容器化应用的资源对象,其它的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,K8S 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成。在 Pod 里面运行容器,容器需要指定一个镜像,这样就可以用来运行具体的服务。一个 Pod 封装一个容器(也可以封装多个容器),Pod 里的容器共享存储、网络等。也就是说,应该把整个 pod 看作虚拟机,然后每个容器相当于运行在虚拟机的进程。


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


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


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


Pod 基本概念

  • 最小部署的单元

  • Pod 里面是由一个或多个容器组成【一组容器的集合】

  • 一个 pod 中的容器共享网络命名空间

  • Pod 是短暂的

  • 每个 Pod 包含一个或多个紧密相关的用户业务容器

Pod 存在的意义

  • 创建容器使用 docker,一个 docker 对应一个容器,一个容器运行一个应用进程

  • Pod 是多进程设计,运用多个应用程序,也就是一个 Pod 里面有多个容器,而一个容器里面运行一个应用程序

  • Pod 的存在是为了亲密性应用

  • 两个应用之间进行交互

  • 网络之间的调用【通过 127.0.0.1 或 socket】

  • 两个应用之间需要频繁调用


Pod 是 K8S 集群中所有业务类型的基础,可以把 Pod 看作运行在 K8S 集群上的小机器人,不同类型的业务就需要不同类型的小机器人去执行。目前 K8S 的业务主要可以分为以下几种


  • 长期伺服型:long-running

  • 批处理型:batch

  • 节点后台支撑型:node-daemon

  • 有状态应用型:stateful application


上述的几种类型,分别对应的小机器人控制器为:Deployment、Job、DaemonSet 和 StatefulSet

Pod 如何管理多个容器?

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


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

Pod 实现机制

主要有以下两大机制


  • 共享网络

  • 共享存储

共享网络

Pod 是有 IP 地址的,每个 pod 都被分配唯一的 IP 地址(IP 地址是靠网络插件 calico、flannel、 weave 等分配的),POD 中的容器共享网络名称空间,包括 IP 地址和网络端口。 Pod 内部的容器可以使 用 localhost 相互通信。 Pod 中的容器也可以通过网络插件 calico 与其他节点的 Pod 通信。


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


  • 首先需要满足前提条件,也就是容器都在同一个 namespace 之间


关于 Pod 实现原理,首先会在 Pod 会创建一个根容器: pause容器,然后我们在创建业务容器 【nginx,redis 等】的时候,会把它添加到 info容器 中(info 容器就是 pause 容器)


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


完整步骤如下


  • 通过 Pause 容器,把其它业务容器加入到 Pause 容器里,让所有业务容器在同一个名称空间中,可以实现网络共享

共享存储

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


Pod 持久化数据,专门存储到某个地方中,因为在故障转移的过程中如果数据没有了,那么损失是非常严重的。

Pod 工作方式

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

实战:创建自主式 Pod

所谓的自主式 Pod,就是直接定义一个 Pod 资源(先在 node1 和 node2 节点上用 docker 拉取 tomcat 镜像)


[root@k8smaster~]# mkdir test[root@k8smaster~]# cd test[root@k8smaster~]# vim pod-tomcat.yaml apiVersion: v1kind: Podmetadata:  name: tomcat-test  namespace: default  labels:    app:  tomcatspec:  containers:  - name:  tomcat-java    ports:    - containerPort: 8080    image: tomcat    imagePullPolicy: IfNotPresent
#更新资源清单[root@k8smaster test]# kubectl apply -f pod-tomcat.yaml#查看 pod 是否创建成功 [root@k8smaster test]# kubectl get pods -o wide -l app=tomcat NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEStomcat-test 1/1 Running 0 3h9m 10.244.1.9 k8snode2 <none> <none>#但是自主式 Pod 是存在一个问题的,假如我们不小心删除了 pod[root@xianchaomaster1 ~]# kubectl delete pods tomcat-test #查看 pod 是否还在 [root@xianchaomaster1 ~]# kubectl get pods -l app=tomcat #结果是空,说明 pod 已经被删除了
复制代码


通过上面可以看到,如果直接定义一个 Pod 资源,那 Pod 被删除,就彻底被删除了,不会再创建一个新的 Pod,这在生产环境还是具有非常大风险的,所以今后我们接触的 Pod 都是控制器管理的。如果是不重要的可以重新更新资源清单(yaml 文件保存好)。

实战:创建控制器管理的 Pod

常见的管理 Pod 的控制器:Replicaset、Deployment、Job、CronJob、Daemonset、Statefulset。


控制器管理的 Pod 可以确保 Pod 始终维持在指定的副本数运行。 比如通过 Deployment 管理 Pod。


我们首先在 node1 和 node2 拉取 nginx 的镜像(用 docker)


#创建一个资源清单文件 [root@k8smaster test]# vim nginx-deploy.yamlapiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-test  labels:    app: nginx-deployspec:  selector:    matchLabels:      app: nginx  replicas: 2  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: my-nginx        image: nginx        imagePullPolicy: IfNotPresent        ports:        - containerPort: 80
#更新资源清单文件 [root@k8smaster test]# kubectl apply -f nginx-deploy.yaml #查看 Deployment [root@k8smaster test]# kubectl get deploy -l app=nginx-deployNAME READY UP-TO-DATE AVAILABLE AGEnginx-test 2/2 2 2 119s #查看 pod [root@k8smaster test]# kubectl get pods -o wide -l app=nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE nginx-test-84b997bfc5-6dkxx 1/1 Running 0 2m30s 10.244.2.12 k8snode <none> nginx-test-84b997bfc5-z6lqm 1/1 Running 0 2m40s 10.244.2.11 k8snode <none> #删除 nginx-test-84b997bfc5-6dkxx 这个 pod [root@k8smaster test]# kubectl delete pods nginx-test-84b997bfc5-6dkxxpod "nginx-test-84b997bfc5-6dkxx" deleted[root@k8smaster test]# kubectl get pods -o wide -l app=nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE nginx-test-84b997bfc5-6vccl 1/1 Running 0 11s 10.244.1.11 k8snode2 <none> nginx-test-84b997bfc5-z6lqm 1/1 Running 0 3m47s 10.244.2.11 k8snode <none> #发现重新创建一个新的 pod 是 nginx-test-84b997bfc5-6vccl
复制代码


通过上面可以发现通过 deployment 管理的 pod,可以确保 pod 始终维持在指定副本数量,而且两个 pod 访问哪个结果都是一样的!

写在最后

创作不易,如果觉得内容对你有帮助,麻烦给个三连关注支持一下我!如果有错误,请在评论区指出,我会及时更改!目前正在更新的系列:从零开始学 k8s

感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~

发布于: 2022 年 09 月 23 日阅读数: 50
用户头像

泡泡

关注

做最好的知识分享 云计算/云原生 2022.08.25 加入

CSDN万粉博主

评论

发布
暂无评论
【云原生 | 从零开始学Kubernetes】五、Kubernetes核心技术Pod_Docker_泡泡_InfoQ写作社区