云原生-Kubernetes Pod 介绍

Pod 直译是豆荚,可以把容器想像成豆荚里的豆子,把一个或多个关系紧密的豆子包在一起
就是豆荚(一个 Pod)。在 k8s 中我们不会直接操作容器,而是把容器包装成 Pod 再进行管
理。

一、 Pod 介绍与原理讲解

是 Kubernetes 项目中最小的 API 对象。如果换一个更专业的说法,我们可以这样描述:
Pod,是 Kubernetes 项目的原子调度单位。
Pod 是运行服务的基础.
基础容器是 pause.
每启动一个 Pod 都会附加启动这样一个容器,它的作用就只是简单的等待,设置 Pod 的网
络。
一个 Pod 中的应用容器共享同一组资源:
(1)PID 命名空间:Pod 中的不同应用程序可以看见其他应用程序的进程 ID
(2)网络命名空间:Pod 中的多个容器能访问同一个 IP 和端口范围
(3)IPC 命名空间:Pod 中的多个容器能够使用 SystemV IPC 或 POSIX 消息队列进行通
信。
(4)UTS 命名空间:Pod 中的多个容器共享一个主机名
(5)Volumes(共享存储卷):Pod 中的各个容器可以访问在 Pod 级别定义的 Volumes
每个 pod 中容器的镜像应该不同(不同的应用),避免端口重复

 

 

 

Pod 的设计
第一个最典型的例子是:WAR 包与 Web 服务器

 第二个例子,则是容器的日志收集。比如,我现在有一个应用,需要不断地把日志文件输出
到容器的 /var/log 目录中。这时,我就可以把一个 Pod 里的 Volume 挂载到应用容器的
/var/log 目录上。然后,我在这个 Pod 里同时运行一个 sidecar 容器,它也声明挂载同一
个 Volume 到自己的 /var/log 目录上。这样,接下来 sidecar 容器就只需要做一件事儿,
那 就 是不 断地 从自 己的 /var/log 目 录里 读取 日 志文 件, 转发 到 MongoDB 或者
Elasticsearch 中存储起来。这样,一个最基本的日志收集工作就完成了。跟第一个例子一样,
这个例子中的 sidecar 的主要工作也是使用共享的 Volume 来完成对文件的操作。

二、 Pod 创建与删除 

1、kubectl 创建 pod

K run nginx --image=nginx:1.9 –port=80

状态检查
K get pod name
K describe pod name
K logs name

2、Yaml 基本语法规则

大小写敏感
使用缩进表示层级关系
缩进时不允许使用 Tab 键,只允许使用空格。
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
# 表示注释,从这个字符一直到行尾,都会被解析器忽略。

3、Yaml 文件创建 pod

k run nginx --image=nginx:1.9 --port=80 --dry-run=client -o yaml>nginx.yaml
cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
 creationTimestamp: null
 labels:
 run: nginx
 name: nginx
spec:
 containers:
 - image: nginx:1.9
 name: nginx
 ports:
 - containerPort: 80
 resources: {}
 dnsPolicy: ClusterFirst restartPolicy: Always
status: {}

4、多容器 Pod 创建

apiVersion: v1
kind: Pod
metadata:
 creationTimestamp: null
 labels:
 run: nginx
 name: multi-container
spec:
 containers:
 - image: nginx:1.9
 name: nginx
 ports:
 - containerPort: 80
 resources: {}
 - image: tomcat
 name: tomcat
 ports:
 - containerPort: 8080
 dnsPolicy: ClusterFirst
 restartPolicy: Always
status: {}

三、 Pod 生命周期管理

        Pod 生命周期的变化,主要体现在 Pod API 对象的 Status 部分,这是它除了
Metadata 和 Spec 之外的第三个重要字段。其中,pod.status.phase,就是 Pod 的当前状
态,
        它有如下几种可能的情况:
        Pending。这个状态意味着,Pod 的 YAML 文件已经提交给了 Kubernetes,API 对象
已经被创建并保存在 Etcd 当中。但是,这个 Pod 里有些容器因为某种原因而不能被顺利
创建。比如,调度不成功。
        Running。这个状态下,Pod 已经调度成功,跟一个具体的节点绑定。它包含的容器都
已经创建成功,并且至少有一个正在运行中。

        Succeeded。这个状态意味着,Pod 里的所有容器都正常运行完毕,并且已经退出了。
这种情况在运行一次性任务时最为常见。
        Failed。这个状态下,Pod 里至少有一个容器以不正常的状态(非 0 的返回码)退出。
这个状态的出现,意味着你得想办法 Debug 这个容器的应用,比如查看 Pod 的 Events 和
日志。
        Unknown。这是一个异常状态,意味着 Pod 的状态不能持续地被 kubelet 汇报给
kube-apiserver,这很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题。
        更进一步地,Pod 对象的 Status 字段,还可以再细分出一组 Conditions。这些细分状
态的值包括:PodScheduled、Ready、Initialized,以及 Unschedulable。它们主要用于描述
造成当前 Status 的具体原因是什么。
Restart policy
Restart policy for all containers within the pod. One of Always, OnFailure, Never. 
Default to Always

1、Pod 资源的配额和限制

apiVersion: v1
kind: Pod
metadata:
 name: qos-demo
 namespace: qos-example
spec:
 containers:
 - name: qos-demo-ctr
 image: nginx
 resources:
 limits:
 memory: "200Mi"
 cpu: "700m"
 requests:
 memory: "200Mi"
 cpu: "700m"
kubectl get pod qos-demo --namespace=qos-example --output=yaml
spec:
 containers: ...
 resources:
 limits:
 cpu: 700m
 memory: 200Mi
 requests:
 cpu: 700m
 memory: 200Mi
 ...
status:
 qosClass: Guaranteed
k describe pod -A |grep QoS
Service SLA
No define best of effort
Request < limit burstable
Request = limit guaranteed

五、Pod 的健康检查 

探针是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 
Handler。有三种类型的探针:
Exec 探针:执行进程的地方,容器的状态由进程的退出状态代码确认;
Http get 探针:向容器发送 HTTP GET 请求,通过响应的 HTTP 状态代码判断容器是否准备
好;如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的
Tcp socket 探针:它打开一个 TCP 连接到容器的指定端口,如果连接己建立,则认为容器己
准备就绪。
kubernetes 会周期性地调用探针,并根据就绪探针的结果采取行动。如果某个 pod 报告它
尚未准备就绪,则会从该服务中删除该 pod。如果 pod 再次准备就绪,则重新添加 pod;
每次探测都将获得以下三种结果之一:
成功:容器通过了诊断。
失败:容器未通过诊断。
未知:诊断失败,因此不会采取任何行动
livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且
容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success
readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 
匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为
Failure。如果容器不提供就绪探针,则默认状态为 Success
只要 pod 的标签和服务的 pod 选择器匹配,pod 就可以作为服务的后端,但是如果 pod 没
有准备好,是不能处理请求的,这时候就需要就绪探针了,用来检查 pod 是否已经准备好
了,如果检查成功就可以作为服务的后端处理消息了;

1、向 pod 添加检测探针 - 存活检测

livenessProbe-exec 
apiVersion: v1
kind: Pod
metadata:
 name: liveness-exec-pod
 namespace: default
spec:
 containers:
 - name: liveness-exec-container
 image: busybox
 imagePullPolicy: IfNotPresent
 command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600"]
 livenessProbe:
 exec:
 command: ["test","-e","/tmp/live"]
 initialDelaySeconds: 1
 periodSeconds: 3

检测/tmp/live,每隔 60 秒就会被删除,liveness 检测,如果被删除,就会返回失败,重启
pod。陷入无限循环。

2、向 pod 添加准备就绪探针

编辑 yaml 文件,修改 pod 模版添加就绪探针

apiVersion: v1
kind: Pod
metadata:
 creationTimestamp: null
 labels:
 run: nginx
 name: nginx
spec:
 containers:
 - image: nginx:1.9
 name: nginx
 ports:
 - containerPort: 80
 resources: {}
 readinessProbe:
 exec:
 command: - ls
 - /var/ready
 dnsPolicy: ClusterFirst
 restartPolicy: Always

就绪探针将定期在容器内执行 ls/var/ready 命令。如果文件存在,则 ls 命令返回退出码 0, 
否则返回非零的退出码;如果文件存在,则就绪探针将成功,否则失败;我们编辑完 yaml
并产生新的 pod,所以可以发现以上 pod 的 READY 为 0;

K apply -f nginx.yaml
K get pods
进入 pod 增加相应的文件
k exec -it nginx -- sh
Defaulting container name to nginx.
Use 'kubectl describe pod/nginx -n default' to see all of the containers in this pod.
# touch /var/ready
K get pods
修改探针。
 httpGet:
 path: /
 port: 80
 initialDelaySeconds: 3
 periodSeconds: 3

六、.Pod 调度 

1、调度原理

 

 

2、Pod调度过程

 1. 用户提交 pod,APIServer 记录到 etcd 中;
2. scheduler 周期性查询 APIServer,以获取未绑定的 pod,尝试为 pod 分配节点;
3. scheduler 调度:首先过滤不符合 pod 资源要求的主机。然后考虑整体优化策略对
主机打分,比如使用最低负载,使用分散主机等。最后选择最高分的主机存储绑
定信息到 etcd 中;
4. kubelet 周期查询绑定对象,获取需要在本机启动的 pod 并通过 docker 启动。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

30岁老阿姨

支持一下哦!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值