kubernetes pod(Kubernetes之三 k8s中的pod)

本文目录
- Kubernetes之三 k8s中的pod
- Kubernetes下pod控制组管理解析
- Kubernetes-Pod基本概念(六)
- Kubernetes Pod 安全策略(PSP)配置
- kubernetes Pod 异常排错
- 简述Kubernetes Pod如何实现对节点的资源控制
Kubernetes之三 k8s中的pod
在k8s中,Pod是一个容器集合,相当于一组docker,同一pod内所有容器使用IPC相互通信,因为它们共享了IPC,UTS,Network。
下面这张图详述了各个容器间的关系
一 Pod中的各个对象:
kind: 定义资源类型, 例如 deployment,service 等
apiVersion: 定义调用的 API 版本, 所支持的版本可以通过 kubectl API-resources 查看
metadata: 资源提供源数据信息, 如名称, 隶属的名称空间和标签等
spec: 用于定义用户期望的状态, 不同的资源类型
Status: 记录活动对象的当前状态信息, 由 k8s 系统自行维护, 对用户来说为只读字段
二 如何创建pod
kubectl create:
(1)kubectl create命令,是先删除所有现有的东西,重新根据yaml文件生成新的。所以要求yaml文件中的配置必须是完整的
(2)kubectl create命令,用同一个yaml 文件执行替换replace命令,将会不成功,fail掉。
kubectl apply:
kubectl apply命令,根据配置文件里面列出来的内容,升级现有的。所以yaml文件的内容可以只写需要升级的属性
# 相关资源的命令查询:
kubectl explain pods(.spec.tolerations....)
# 导出 pod 对应的 YAML 模版:
kubectl get pod web YAML --export》 web.YAML
三镜像拉取方式imagePullPolicy
k8s的配置文件中经常看到有imagePullPolicy属性,这个属性是描述镜像的拉取策略
Always 总是拉取镜像
IfNotPresent 本地有则使用本地镜像,不拉取
Never 只使用本地镜像,从不拉取,即使本地没有
如果省略imagePullPolicy 镜像tag为 :latest 策略为always ,否则 策略为 IfNotPresent
四 pod中的网络代理方式
Service方式: 申明 NodePort 类型, 可以通过任意节点访问,可以实现负载均衡功能
hostPort方式: hostPort是直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过宿主机的IP加上来访问Pod了
hostNetwork方式: 共享宿主机的网络名称空间
五 创建pod
以下面的yaml创建pod,命令为kubectl create -f firstpod.yaml ,在创建之前,需要pull镜像busybox
apiVersion: v1
kind: Pod
metadata:
name: first-pod
spec:
containers:
- name: bash-container
image: docker.io/busybox
kubectl explain pods.status 可查看pod的resource
Kubernetes下pod控制组管理解析
在 Kubernetes 里面,将资源分成不同的 QoS 类别,并且通过 pod 里面的资源定义来区分 pod 对于平台提供的资源保障的 SLA 等级:
针对不同的优先级的业务,在资源紧张或者超出的时候会有不同的处理策略。
同时,针对 CPU 和内存两类不同类型的资源,一种是可压缩的,一种是不可压缩的,所以资源的分配和调控策略也会有很大区别。
CPU 资源紧缺时,如果节点处于超卖状态,则会根据各自的 requests 配置,按比例分配 CPU 时间片,而内存资源紧缺时需要内核的 oom killer 进行管控,
Kubernetes 负责为 OOM killer 提供管控依据:
OOM 得分主要根据 QoS 类和容器的 requests 内存占机器总内存比来计算:
OOM 得分越高,该进程的优先级越低,越容易被终止;根据公式, Burstable 优先级的 pod 中, requests 内存申请越多,越容易在 OOM 的时候被终止。
首先我们先看下 pod 的控制组层级
其中 kubepods-besteffort.slice 存放 besteffort 类型 pod 控制组配置, kubepods-burstable.slice 存放 burstable 类型 pod 控制组配置。
kubepods-pod934b0aa2_1d1b_4a81_bfcf_89c4beef899e.slice 、 kubepods-podca849e84_aa86_4402_bf31_e7e73faa77fe.slice 则为 Guaranteed 类型 pod
为了更好的解释说明,我们创建一个新的 Guaranteed 类型的 pod 用于测试:
kubepods-podf56bf66f_3efb_4c80_8818_37de69ee5b72.slice 这个名称是怎么命名的呢?
命名格式为: kubepods-pod《pod uid》.slice ,并且会将 uid 中 - 转换为 _
我们发现怎么有两个容器呢?( docker-08974ffd61043b34e4cd5710d5446eb423c6371afb4c9d106e608f08cc1182a3.scope 、 docker-d33dc12340fd32b35148293c21f84dab14f2274046056bbeef9e9666d1d0dc2a.scope )
其实是业务容器 + infra 沙箱容器,并且命名格式遵循: docker-《container id》.scope
我们可根据以下命令获取业务容器 id :
我们上述对 pod 配额的定义为:
其实等同于以以下方式启动 docker 容器:
我们可以看下 docker 容器的配额:
.HostConfig.CpuShares 对应控制内的 cpu.shares 文件内容
.HostConfig.CpuPeriod 对应控制内的 cpu.cpu.cfs_period_us 文件内容
.HostConfig.CpuQuota 对应控制内的 cpu.cfs_quota_us 文件内容
并且我们发现 k8s 基于 pod 管理控制组(同一 pod 内的容器所属同一控制组)
我们可以得出记录: k8s 通过控制组的 cpu.shares 、 cpu.cpu.cfs_period_us 、 cpu.cfs_quota_us 配置,达到限制 CPU 的目的。
那么这三个文件是用来干嘛的?
当系统中有两个 cgroup ,分别是 A 和 B , A 的 shares 值是 1024 ,B 的 shares 值是 512 ,
那么 A 将获得 1024/(1024+512)=66% 的 CPU 资源,而 B 将获得 33% 的 CPU 资源。 shares 有两个特点:
从上面两个特点可以看出:
在闲的时候, shares 基本上不起作用,只有在 CPU 忙的时候起作用,这是一个优点。
由于 shares 是一个绝对值,需要和其它 cgroup 的值进行比较才能得到自己的相对限额,而在一个部署很多容器的机器上, cgroup 的数量是变化的,所以这个限额也是变化的,自己设置了一个高的值,但别人可能设置了一个更高的值,所以这个功能没法精确的控制 CPU 使用率。
值对应关系为: resources.requests.cpu * 1024 = cpu.shares
如: resources.requests.cpu 为3的时候, cpu.shares 值为 3072 ; resources.requests.cpu 为 100m 的时候, cpu.shares 值为 102
并且 k8s 下容器控制组的 cpu.cpu.cfs_period_us 值固定为 100000 ,实际只设置 cpu.cfs_quota_us 值
例如:
cpu.cpu.cfs_period_us 为 100000 (单位微妙,即0.1秒), cpu.cfs_quota_us 为 500000 (单位微妙,即 0.5 秒)时, resources.limits.cpu 为5,即5个 cpu 核心。
cpu.cpu.cfs_period_us 为 100000 (单位微妙,即0.1秒), cpu.cfs_quota_us 为 10000 (单位微妙,即 0.01 秒)时, resources.limits.cpu 为0.1(或100m),即0.1个 cpu 核心。
与 cpu 不同, k8s 里 pod 容器的 requests.memory 在控制组内没有对应的属性,未起到限制作用,只是协助 k8s 调度计算。
而 pod 容器的 limits.memory 对应控制组里的 memory.limit_in_bytes 值。
Kubernetes-Pod基本概念(六)
一个pod是一组紧密相关的容器,是一起运行在同一个工作节点上,以及同一个Linux命名空间中。每个pod就像是一个独立的逻辑机器,拥有自己的IP、主机名、进程等,运行一个独立的应用程序。
pod是逻辑主机,一个pod的所有容器都运行在同一个逻辑机器上,其他pod中的容器,即使运行在同一个工作节点上,也会出现在不同的节点上。即一个pod包含多个容器时,这些容器总是运行在同一个工作节点上,一个pod绝不可能跨多个工作节点。
举例 :
每个pod自有IP,包含1个或多个容器,每个容器运行一个应用进程
查看pod命令
$ kubectl get pods
READY:0/1 表示pod的单个容器显示为未就绪的状态;相反,1/1表示已就绪;
STATUS: Pending 表示pod处于挂起状态;相反,Running表示pod处于运行状态;
运行应用两大步骤:1)构建镜像并推送至镜像仓库中;2)K8s创建pod进行调度;
流程:
1)本地构建镜像;
2)推送镜像至镜像仓库;
3)kubectl创建并部署应用;
4)kubectl发出REST请求至REST API服务器;
5)创建pod并调度到工作节点;
6)kubelet收到通知;
7)kubelet告知Docker运行镜像;
8)Docker从镜像仓库中拉取镜像;
9)Docker创建并运行容器;
如果单个容器中运行多个不相关的进程,保持所有进程运行、管理它们的日志将很难,需要包含一种在进程崩溃时能够自动重启的机制,同事,这些进程都将记录到相同的标准输出中,很难确定每个进程分别记录的内容。
不能讲多个进程聚集在一个单独的容器中,需要pod将容器绑定在一起,并将它们作为一个单元进行管理,在包含容器的pod下,可以同时运行一些密切现骨干的进程,并为其提供相同的环境,此时这些进程就好像全部运行于单独的容器中,同时保持一定的隔离性。
k8s可以通过配置docker让一个pod内的所有容器共享相同的Linux命名空间(network、UTS命名空间、IPC命名空间),从而使容器都共享相同的主机名、网络名和IPC通信。
同一个pod中的容器运行的多个进程不能绑定到相同的端口号,否则会端口冲突(每个pod都有独立的端口空间,不同pod中的容器不会有端口冲突现象。)
同一个pod中的容器具有相同的loopback网络接口,所以容器可以通过localhost与同一个pod中的其他容器进行通信。
注意 :
容器不应该包含多个进程,pod也不应该包含多个并不需要运行在同一主机上的容器。如下图:
1)yaml中使用的kubernetes API版本和yaml描述的资源类型;
2)metadata:包括名称、命名空间、标签和关于该容器的其他信息;
3)spec:包含pod内容的实际说明,如pod的容器、卷和其他数据;
4)status:包含运行中的pod的当前信息,如pod所处的条件、每个容器的描述和状态,以及内部IP和其他基本信息。
描述信息:
1)该文件遵循Kubernetes API的v1版本;
2)描述的资源类型是pod;
3)资源名称为kubia-manual;
4)该pod由基于luksa/kubia镜像的单个容器组成;
5)容器名称为kubia;
6)容器监听的端口是8080;
按名称删除
$ kubectl delete po pod_name
其中, pod_name 为pod名称;删除命令指示uk8s终止该pod中所有容器,k8s向进程发送一个SIGTERM信号并等待一定的秒数(默认30s),使得其正常关闭,若未及时关闭,则通过SIGKILL终止进程。
删除多个pod
$ kubectl delete po pod_name1 pod_name2
多个pod删除使用空格隔开;
按照标签删除
$ kubectl depete po -l tag_key=tag_value
其中, tag_key 为标签健, tag_value 为标签值;
按照整个命名空间删除
$ kubectl delete ns namespace_name
其中, namespace_name 为命名空间名称
Kubernetes Pod 安全策略(PSP)配置
Kubernetes Pod 安全策略(PSP)配置
默认情况下,Kubernetes 允许创建一个有特权容器的 Pod,这些容器很可能会危机系统安全,而 Pod 安全策略(PSP)则通过确保请求者有权限按配置来创建 Pod,从而来保护集群免受特权 Pod 的影响。
其他插件来自 Kubernetes 文档中推荐的一些插件列表。
然后直接创建上面的 Deployment:
deployment.apps/nginx-deploy created
我们可以看到 Deployment 已经创建成功了,现在检查下 default 命名空间下面的 pod、replicaset、deployment:
NAME READY STATUS RESTARTS AGE
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-deploy-77f7d4c6b4 1 0 0 40s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-deploy 0/1 0 0 40s
可以看到 replicaset 和 deployment 都创建成功了,但是 replicaset 控制器却并没有创建 Pod,这个时候就需要使用 ServiceAccount 了。
attachdetach-controller
calico-kube-controller
certificate-controller
clusterrole-aggregation-controller
cronjob-controller
daemon-set-controller
deployment-controller
disruption-controller
endpoint-controller
expand-controller
job-controller
namespace-controller
node-controller
pv-protection-controller
pvc-protection-controller
replicaset-controller
replication-controller
resourcequota-controller
service-account-controller
service-controller
statefulset-controller
ttl-controller
这些 ServiceAccount 指定了哪个控制器可以解析哪些策略的配置。
podsecuritypolicy.policy/restrictive configured
虽然限制性的访问对于大多数 Pod 创建是足够的了,但是对于需要提升访问权限的 Pod 来说,就需要一些允许策略了,例如,kube-proxy 就需要启用 hostNetwork:
NAME READY STATUS RESTARTS AGE
kube-proxy-4z4vf 1/1 Running 0 18d
$ kubectl get pods -n kube-system kube-proxy-4z4vf -o yaml |grep hostNetwork
hostNetwork: true
这就需要创建一个用于提升创建权限的许可策略了:(psp-permissive.yaml)
podsecuritypolicy.policy/permissive configured
$ kubectl get psp
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
permissive true RunAsAny RunAsAny RunAsAny RunAsAny false *
restrictive false * RunAsAny RunAsAny RunAsAny RunAsAny false configMap,downwardAPI,emptyDir,persistentVolumeClaim,secret,projected
现在配置都已经就绪了,但是我们需要引入到 Kubernetes 授权,这样才可以确定请求 Pod 创建的用户或者 ServiceAccount 是否解决了限制性或许可性策略,这就需要用到 RBAC 了。
clusterrole.rbac.authorization.k8s.io/psp-restrictive created
clusterrolebinding.rbac.authorization.k8s.io/psp-default created
然后现在我们再重新创建上面我们的定义的 Deployment:
deployment.apps "nginx-deploy" deleted
$ kubectl apply -f nginx.yaml
deployment.apps/nginx-deploy created
创建完成后同样查看下 default 命名空间下面我们创建的一些资源对象:
NAME READY STATUS RESTARTS AGE
pod/nginx-deploy-77f7d4c6b4-njfdl 1/1 Running 0 13s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-deploy-77f7d4c6b4 1 1 1 13s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-deploy 1/1 1 1 13s
我们可以看到 Pods 被成功创建了,但是,如果我们尝试做一些策略不允许的事情,正常来说就应该被拒绝了。首先删除上面的这个 Deployment:
deployment.apps "nginx-deploy" deleted
现在我们在 nginx-deploy 基础上添加hostNetwork: true来使用 hostNetwork 这个特权:(nginx-hostnetwork.yaml)
deployment.apps/nginx-hostnetwork-deploy created
创建完成后同样查看 default 这个命名空间下面的一些资源对象:
NAME READY STATUS RESTARTS AGE
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 1 0 0 44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 0/1 0 0 44s
现在我们发现 ReplicaSet 又没有创建 Pod 了,可以使用kubectl describe命令去查看这里我们创建的 ReplicaSet 资源对象来了解更多的信息:
Name: nginx-hostnetwork-deploy-74c8fbd687
......
Events:
Type Reason Age From Message
-
Warning FailedCreate 80s (x15 over 2m42s) replicaset-controller Error creating: pods "nginx-hostnetwork-deploy-74c8fbd687-" is forbidden: unable to validate against any pod security policy:
我们可以看到很明显 Hostnetwork 不被允许使用,但是在某些情况下,我们的确有在某个命名空间(比如 kube-system)下面创建使用 hostNetwork 的 Pod,这里就需要我们创建一个允许执行的 ClusterRole,然后为特定的命名空间创建一个 RoleBinding,将这里的 ClusterRole 和相关的控制器 ServiceAccount 进行绑定:(psp-permissive-rbac.yaml)
clusterrole.rbac.authorization.k8s.io/psp-permissive created
rolebinding.rbac.authorization.k8s.io/psp-permissive created
现在,我们就可以在 kube-system 这个命名空间下面使用 hostNetwork 来创建 Pod 了,将上面的 nginx 资源清单更改成 kube-system 命名空间下面:
重新创建这个 Deployment:
deployment.apps/nginx-hostnetwork-deploy created
创建完成后同样查看下对应的资源对象创建情况:
NAME READY STATUS RESTARTS AGE
pod/nginx-hostnetwork-deploy-74c8fbd687-7x8px 1/1 Running 0 2m1s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 1 1 1 2m1s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 1/1 1 1 2m1s
现在我们可以看到 Pod 在 kube-system 这个命名空间下面创建成功了。
serviceaccount/specialsa created
然后创建一个 RoleBinding 将 specialsa 绑定到上面的 psp-permissive 这个 CluterRole 上:(specialsa-psp.yaml)
创建上面的 RoleBinding 对象:
rolebinding.rbac.authorization.k8s.io/specialsa-psp-permissive created
然后为我们上面的 Deployment 添加上 serviceAccount 属性:(nginx-hostnetwork-sa.yaml)
然后直接创建即可:
deployment.apps/nginx-hostnetwork-deploy configured
这个时候我们查看 default 这个命名空间下面带有 hostNetwork 的 Pod 也创建成功了:
NAME READY STATUS RESTARTS AGE
pod/nginx-hostnetwork-deploy-6c85dfbf95-hqt8j 1/1 Running 0 65s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-6c85dfbf95 1 1 1 65s
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 0 0 0 31m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 1/1 1 1 31m
上面我们描述了 Pod 安全策略是一种通过使用 PSP 授权策略来保护 k8s 集群中的 Pod 的创建过程的方法。
***隐藏网址***
***隐藏网址***
***隐藏网址***
kubernetes Pod 异常排错
Pod 运行异常的排错方法。
一般来说,无论 Pod 处于什么异常状态,都可以执行以下命令来查看 Pod 的状态
这些事件和日志通常都会有助于排查 Pod 发生的问题。
Pending 说明 Pod 还没有调度到某个 Node 上面。可以通过 kubectl describe pod 《pod-name》 命令查看到当前 Pod 的事件,进而判断为什么没有调度。如
可能的原因包括
首先还是通过 kubectl describe pod 《pod-name》 命令查看到当前 Pod 的事件
可以发现,该 Pod 的 Sandbox 容器无法正常启动,具体原因需要查看 Kubelet 日志
发现是 cni0 网桥配置了一个不同网段的 IP 地址导致,删除该网桥(网络插件会自动重新创建)即可修复
除了以上错误,其他可能的原因还有
这通常是镜像名称配置错误或者私有镜像的密钥配置错误导致。这种情况可以使用 docker pull 《image》 来验证镜像是否可以正常拉取。
如果是私有镜像,需要首先创建一个 docker-registry 类型的 Secret
然后在容器中引用这个 Secret
CrashLoopBackOff 状态说明容器曾经启动了,但又异常退出了。此时 Pod 的 RestartCounts 通常是大于 0 的,可以先查看一下容器的日志
这里可以发现一些容器退出的原因,比如
如果此时如果还未发现线索,还可以到容器内执行命令来进一步查看退出原因
如果还是没有线索,那就需要 SSH 登录该 Pod 所在的 Node 上,查看 Kubelet 或者 Docker 的日志进一步排查了
通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括
从 v1.5 开始,Kubernetes 不会因为 Node 失联而删除其上正在运行的 Pod,而是将其标记为 Terminating 或 Unknown 状态。想要删除这些状态的 Pod 有三种方法:
如果 Kubelet 是以 Docker 容器的形式运行的,此时 kubelet 日志中可能会发现 如下的错误 :
如果是这种情况,则需要给 kubelet 容器设置 --containerized 参数并传入以下的存储卷
处于 Terminating 状态的 Pod 在 Kubelet 恢复正常运行后一般会自动删除。但有时也会出现无法删除的情况,并且通过 kubectl delete pods 《pod》 --grace-period=0 --force 也无法强制删除。此时一般是由于 finalizers 导致的,通过 kubectl edit 将 finalizers 删除即可解决。
这里所说的行为异常是指 Pod 没有按预期的行为执行,比如没有运行 podSpec 里面设置的命令行参数。这一般是 podSpec yaml 文件内容有误,可以尝试使用 --validate 参数重建容器,比如
也可以查看创建后的 podSpec 是否是对的,比如
Kubelet 使用 inotify 机制检测 /etc/kubernetes/manifests 目录(可通过 Kubelet 的 --pod-manifest-path 选项指定)中静态 Pod 的变化,并在文件发生变化后重新创建相应的 Pod。但有时也会发生修改静态 Pod 的 Manifest 后未自动创建新 Pod 的情景,此时一个简单的修复方法是重启 Kubelet。
简述Kubernetes Pod如何实现对节点的资源控制
Kubernetes集群里的节点提供的资源主要是计算资源,计算资源是可计量的能被申请、分配和使用的基础资源。当前Kubernetes集群中的计算资源主要包括CPU、GPU及Memory。CPU与Memory是被Pod使用的,因此在配置Pod时可以通过参数CPU Request及Memory Request为其中的每个容器指定所需使用的CPU与Memory量,Kubernetes会根据Request的值去查找有足够资源的Node来调度此Pod。
通常,一个程序所使用的CPU与Memory是一个动态的量,确切地说,是一个范围,跟它的负载密切相关:负载增加时,CPU和Memory的使用量也会增加。我推荐你去看看时速云,他们是一家全栈云原生技术服务提供商,提供云原生应用及数据平台产品,其中涵盖容器云PaaS、DevOps、微服务治理、服务网格、API网关等。大家可以去体验一下。
如果我的回答能够对您有帮助的话,求给大大的赞。

更多文章:
form表单制作(为什么制作的form表单会在网页显示中多出一行)
2026年10月11日 09:10
teammate(teammate,company,partner)
2026年10月11日 06:10
javascript arraybuffer(javascript可以把base64编码转换成二进制代码吗求示例代码!)
2026年10月11日 04:00
text函数公式(excel中round和text函数的区别是什么)
2026年10月11日 03:50
google chrome打不开(chrome浏览器打不开怎么回事 浏览器打不开的处理方法)
2026年10月11日 02:00
websocket整合springboot(Springboot整合Websocket遇到的坑)
2026年10月11日 01:40
drawerlayout(android 怎样让drawerlayout设置的侧滑菜单的内容充满屏幕)
2026年10月10日 19:20
xor四位数怎么运算(单片机怎样用C语言实现4个数字间的异或)
2026年10月10日 17:50


