【云原生 | 从零开始学Kubernetes】五、Kubernetes核心技术Pod
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
该篇文章已经被专栏《从零开始学k8s》收录
Pod详解
Pod概述
Pod是K8S系统中可以创建和管理的最小单元是资源对象模型中由用户创建或部署的最小资源对象模型也是在K8S上运行容器化应用的资源对象其它的资源对象都是用来支撑或者扩展Pod对象功能的比如控制器对象是用来管控Pod对象的Service或者Ingress资源对象是用来暴露Pod引用对象的PersistentVolume资源对象是用来为Pod提供存储等等K8S不会直接处理容器而是PodPod是由一个或多个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 通信。
容器本身之间相互隔离的一般是通过 namespace 和 group 进行隔离那么Pod里面的容器如何实现通信
- 首先需要满足前提条件也就是容器都在同一个namespace之间
关于Pod实现原理首先会在Pod会创建一个根容器 pause容器
然后我们在创建业务容器 【nginxredis 等】的时候会把它添加到 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: v1
kind: Pod
metadata:
name: tomcat-test
namespace: default
labels:
app: tomcat
spec:
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 GATES
tomcat-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.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test
labels:
app: nginx-deploy
spec:
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-deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-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-6dkxx
pod "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从零开始学zabbix
感谢各位的观看文章掺杂个人理解如有错误请联系我指出~