Pod API 原理解析
- 理解系统进程组- 成组调度失败案例- Pod实现原理
什么是Pod
Pod是 K8S 中最小的 API 对象。换一个更专业的说法:Pod是 K8S 的原子调度单位。是 K8S 能够描述和编排各种复杂应用的基石
为什么需要 Pod
# pstree -gsystemd(1)-+-accounts-daemon(1984)-+-{gdbus}(1984) | `-{gmain}(1984) |-acpid(2044) ... |-rsyslogd(1632)-+-{in:imklog}(1632) | |-{in:imuxsock) S 1(1632) | `-{rs:main Q:Reg}(1632)
Pod 的实现原理
1、Pod 只是一个逻辑概念关于 Pod 最重要的一个事实是:它只是一个逻辑概念K8S 真正处理的,还是宿主机上 Linux 容器的 Namespace 和 Cgroups,并不存在一个所谓的 Pod 的边界或者隔离环境。2、Pod 是如何被"创建"出来的 Pod 其实是一组共享了某些资源的容器。 Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume。
pod属性分类
kind
指定了这个 API 对象的类型(Type),是一个 Pod,根据实际情况,此处资源类型可以是Deployment、Job、Ingress、Service等。
metadata
包含Pod的一些meta信息,比如名称、namespace、标签等信息。
spec
specification of the resource content 指定该资源的内容,包括一些container,storage,volume以及其他Kubernetes需要的参数,以及诸如是否在容器失败时重新启动容器的属性。可在特定Kubernetes API找到完整的Kubernetes Pod的属性。容器可选的设置属性:除了上述的基本属性外,还能够指定复杂的属性,包括容器启动运行的命令、使用的参数、工作目录以及每次实例化是否拉取新的副本。 还可以指定更深入的信息,例如容器的退出日志的位置。容器可选的设置属性包括:name、image、command、args、workingDir、ports、env、resource、volumeMounts、livenessProbe、readinessProbe、livecycle、terminationMessagePath、imagePullPolicy、securityContext、stdin、stdinOnce、tty跟"机器"相关的配置
运行节点选择
不指定由调度器分配node指定可以用nodeSelector 或者nodeName指定单个节点的时候 一般用nodeName多节点的话 用nodeSelector ----node有统一的标签
nodeSelector举例
查version
[root@master ~]# kubectl explain DaemonSet###################################################################################[root@master ~]# kubectl explain DaemonSetKIND: DaemonSetVERSION: apps/v1DESCRIPTION: DaemonSet represents the configuration of a daemon set.FIELDS: apiVersion <string> APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources kind <string> Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds metadata <Object> Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata spec <Object> The desired behavior of this daemon set. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status status <Object> The current status of this daemon set. This data may be out of date by some window of time. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
查node标签
[root@master ~]# kubectl describe node node2###################################################################################[root@master ~]# kubectl describe node node2Name: node2Roles: <none>Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/arch=amd64 kubernetes.io/hostname=node2 kubernetes.io/os=linuxAnnotations: flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"ca:49:fc:a1:73:a9"} flannel.alpha.coreos.com/backend-type: vxlan flannel.alpha.coreos.com/kube-subnet-manager: true flannel.alpha.coreos.com/public-ip: 192.168.81.32 kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock node.alpha.kubernetes.io/ttl: 0 volumes.kubernetes.io/controller-managed-attach-detach: trueCreationTimestamp: Tue, 06 Sep 2022 23:15:33 +0800Taints: <none>Unschedulable: falseConditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- NetworkUnavailable False Thu, 22 Sep 2022 17:49:15 +0800 Thu, 22 Sep 2022 17:49:15 +0800 FlannelIsUp Flannel is running on this node MemoryPressure False Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:15:33 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:15:33 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure PIDPressure False Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:15:33 +0800 KubeletHasSufficientPID kubelet has sufficient PID available Ready True Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:16:24 +0800 KubeletReady kubelet is posting ready statusAddresses:

之前
[root@master kubernetes]# cat nginx.yaml apiVersion: v1kind: Podmetadata: name: nginx01spec: containers: - name: nginx01 image: daocloud.io/library/nginx:1.7.9[root@master kubernetes]# kubectl apply -f nginx.yaml [root@master kubernetes]# kubectl get pod[root@master kubernetes]# kubectl get pod -o wide
之后
[root@master kubernetes]# kubectl delete -f nginx.yaml pod "nginx01" deleted[root@master kubernetes]# cat nginx.yaml apiVersion: v1kind: Podmetadata: name: nginx01spec: nodeSelector: kubernetes.io/hostname: node2 containers: - name: nginx01 image: daocloud.io/library/nginx:1.7.9[root@master kubernetes]# kubectl apply -f nginx.yaml pod/nginx01 created[root@master kubernetes]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx01 0/1 ContainerCreating 0 25s <none> node2 <none> <none>
NodeName举例
[root@master kubernetes]# vim nginx.yaml [root@master kubernetes]# kubectl apply -f nginx.yaml pod/nginx01 created[root@master kubernetes]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx01 1/1 Running 0 9s 10.244.1.7 node1 <none> <none>[root@master kubernetes]# cat nginx.yaml apiVersion: v1kind: Podmetadata: name: nginx01spec: nodeName: node1 containers: - name: nginx01 image: daocloud.io/library/nginx:1.7.9
HostAliases
类似域名解析定义 Pod 的 hosts 文件(比如 /etc/hosts)里的内容,用法: apiVersion: v1 kind: Pod ... spec: hostAliases: - ip: "10.1.2.3" hostnames: - "foo.remote" - "bar.remote" ...举例[root@master kubernetes]# kubectl apply -f nginx.yaml pod/nginx01 created[root@master kubernetes]# cat nginx.yaml apiVersion: v1kind: Podmetadata: name: nginx01spec: hostAliases: - ip: "192.168.31.31" hostnames: - "www.xlx.com" - "www.test.com" containers: - name: nginx01 image: daocloud.io/library/nginx:1.7.9[root@master kubernetes]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx01 1/1 Running 0 31s 10.244.1.8 node1 <none> <none>[root@master kubernetes]# kubectl exec -it nginx01 /bin/bashroot@nginx01:/# cat /etc/hosts# Kubernetes-managed hosts file.127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopbackfe00::0 ip6-localnetfe00::0 ip6-mcastprefixfe00::1 ip6-allnodesfe00::2 ip6-allrouters10.244.1.8 nginx01# Entries added by HostAliases.192.168.31.31 www.xlx.com www.test.com
shareProcessNamespace
共享名称空间---【进程的名称空间】表示这个 Pod 里的容器要共享 PID Namespace[root@master kubernetes]# vim nginx.yaml [root@master kubernetes]# kubectl apply -f nginx.yaml pod/nginx01 created[root@master kubernetes]# kubectl get podNAME READY STATUS RESTARTS AGEnginx01 2/2 Running 0 9s[root@master kubernetes]# cat nginx.yaml apiVersion: v1kind: Podmetadata: name: nginx01spec: containers: - name: nginx01 image: daocloud.io/library/nginx:1.7.9 - name: busybox image: daocloud.io/library/busybox stdin: true tty: true[root@master kubernetes]# kubectl get podNAME READY STATUS RESTARTS AGEnginx01 2/2 Running 0 9s2/2后面2表示有一个pod有2个容器 前面2表示 2个都是运行的[root@master kubernetes]# kubectl exec -it nginx01 /bin/bashDefaulting container name to nginx01.Use 'kubectl describe pod/nginx01 -n default' to see all of the containers in this pod.默认进来是第一个容器指定进入哪个容器 -c[root@master kubernetes]# kubectl exec -it nginx01 -c busybox /bin/sh/ # [root@master kubernetes]# kubectl exec -it nginx01 -c busybox /bin/sh/ # psPID USER TIME COMMAND 1 root 0:00 sh 18 root 0:00 /bin/sh 24 root 0:00 ps[root@master kubernetes]# cat nginx.yaml apiVersion: v1kind: Podmetadata: name: nginx01spec: shareProcessNamespace: true containers: - name: nginx01 image: daocloud.io/library/nginx:1.7.9 - name: busybox image: daocloud.io/library/busybox stdin: true tty: true[root@master kubernetes]# kubectl apply -f nginx.yaml pod/nginx01 created[root@master kubernetes]# kubectl get podNAME READY STATUS RESTARTS AGEnginx01 2/2 Running 0 40s[root@master kubernetes]# kubectl exec -it nginx01 -c busybox /bin/sh/ # psPID USER TIME COMMAND 1 root 0:00 /pause 7 root 0:00 nginx: master process nginx -g daemon off; 13 101 0:00 nginx: worker process 14 root 0:00 sh 20 root 0:00 /bin/sh 26 root 0:00 psstdin :-itty: -t


常用容器属性
Pod 里最重要的字段"Containers":"Containers"和"Init Containers"这两个字段都属于 Pod 对容器的定义,内容也完全相同,只是 Init Containers 的生命周期,会先于所有的 Containers,并且严格按照定义的顺序执行。K8S 对 Container 的定义,和 Docker 相比并没有什么太大区别。Docker中Image(镜像)、Command(启动命令)、workingDir(容器的工作目录)、Ports(容器要开发的端口),以及 volumeMounts(容器要挂载的 Volume)都是构成 K8S 中 Container 的主要字段。
其他的容器属性
imagePullPolicy 字段
定义镜像的拉取策略。之所以是一个 Container 级别的属性,是因为容器镜像本来就是 Container 定义中的一部分。默认值: Always表示每次创建 Pod 都重新拉取一次镜像。当容器的镜像是类似于 nginx 或者 nginx:latest 这样的名字时,ImagePullPolicy 也会被认为 Always。值:Never 或者 IfNotPresent表示 Pod 永远不会主动拉取这个镜像,或者只在宿主机上不存在这个镜像时才拉取。eg: spec: containers: - name: kubernetes-dashboard image: kubernetesui/dashboard:v2.0.0-rc5 imagePullPolicy: IfNotPresent
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 的具体原因是什么。