Pod API 原理解析

  1. - 理解系统进程组
  2. - 成组调度失败案例
  3. - Pod实现原理

什么是Pod

  1. Pod K8S 中最小的 API 对象。
  2. 换一个更专业的说法:Pod K8S 的原子调度单位。
  3. K8S 能够描述和编排各种复杂应用的基石

为什么需要 Pod

  1. # pstree -g
  2. systemd(1)-+-accounts-daemon(1984)-+-{gdbus}(1984)
  3. | `-{gmain}(1984)
  4. |-acpid(2044)
  5. ...
  6. |-rsyslogd(1632)-+-{in:imklog}(1632)
  7. | |-{in:imuxsock) S 1(1632)
  8. | `-{rs:main Q:Reg}(1632)

Pod 的实现原理

  1. 1Pod 只是一个逻辑概念
  2. 关于 Pod 最重要的一个事实是:它只是一个逻辑概念
  3. K8S 真正处理的,还是宿主机上 Linux 容器的 Namespace Cgroups
  4. 并不存在一个所谓的 Pod 的边界或者隔离环境。
  5. 2Pod 是如何被"创建"出来的
  6. Pod 其实是一组共享了某些资源的容器。
  7. Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume

pod属性分类

kind

  1. 指定了这个 API 对象的类型(Type),
  2. 是一个 Pod,根据实际情况,此处资源类型可以是DeploymentJobIngressService等。

metadata

  1. 包含Pod的一些meta信息,比如名称、namespace、标签等信息。

spec

  1. specification of the resource content
  2. 指定该资源的内容,包括一些containerstorage
  3. volume以及其他Kubernetes需要的参数,
  4. 以及诸如是否在容器失败时重新启动容器的属性。
  5. 可在特定Kubernetes API找到完整的Kubernetes Pod的属性。
  6. 容器可选的设置属性:
  7. 除了上述的基本属性外,还能够指定复杂的属性,
  8. 包括容器启动运行的命令、使用的参数、工作目录以及每次实例化是否拉取新的副本。
  9. 还可以指定更深入的信息,例如容器的退出日志的位置。
  10. 容器可选的设置属性包括:
  11. nameimagecommandargsworkingDirportsenvresource
  12. volumeMountslivenessProbereadinessProbelivecycleterminationMessagePath
  13. imagePullPolicysecurityContextstdinstdinOncetty
  14. "机器"相关的配置

运行节点选择

  1. 不指定由调度器分配node
  2. 指定可以用nodeSelector 或者nodeName指定
  3. 单个节点的时候 一般用nodeName
  4. 多节点的话 nodeSelector ----node有统一的标签

nodeSelector举例

查version

  1. [root@master ~]# kubectl explain DaemonSet
  2. ###################################################################################
  3. [root@master ~]# kubectl explain DaemonSet
  4. KIND: DaemonSet
  5. VERSION: apps/v1
  6. DESCRIPTION:
  7. DaemonSet represents the configuration of a daemon set.
  8. FIELDS:
  9. apiVersion <string>
  10. APIVersion defines the versioned schema of this representation of an
  11. object. Servers should convert recognized schemas to the latest internal
  12. value, and may reject unrecognized values. More info:
  13. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
  14. kind <string>
  15. Kind is a string value representing the REST resource this object
  16. represents. Servers may infer this from the endpoint the client submits
  17. requests to. Cannot be updated. In CamelCase. More info:
  18. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
  19. metadata <Object>
  20. Standard object's metadata. More info:
  21. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
  22. spec <Object>
  23. The desired behavior of this daemon set. More info:
  24. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
  25. status <Object>
  26. The current status of this daemon set. This data may be out of date by some
  27. window of time. Populated by the system. Read-only. More info:
  28. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

查node标签

  1. [root@master ~]# kubectl describe node node2
  2. ###################################################################################
  3. [root@master ~]# kubectl describe node node2
  4. Name: node2
  5. Roles: <none>
  6. Labels: beta.kubernetes.io/arch=amd64
  7. beta.kubernetes.io/os=linux
  8. kubernetes.io/arch=amd64
  9. kubernetes.io/hostname=node2
  10. kubernetes.io/os=linux
  11. Annotations: flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"ca:49:fc:a1:73:a9"}
  12. flannel.alpha.coreos.com/backend-type: vxlan
  13. flannel.alpha.coreos.com/kube-subnet-manager: true
  14. flannel.alpha.coreos.com/public-ip: 192.168.81.32
  15. kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
  16. node.alpha.kubernetes.io/ttl: 0
  17. volumes.kubernetes.io/controller-managed-attach-detach: true
  18. CreationTimestamp: Tue, 06 Sep 2022 23:15:33 +0800
  19. Taints: <none>
  20. Unschedulable: false
  21. Conditions:
  22. Type Status LastHeartbeatTime LastTransitionTime Reason Message
  23. ---- ------ ----------------- ------------------ ------ -------
  24. 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
  25. MemoryPressure False Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:15:33 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available
  26. DiskPressure False Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:15:33 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure
  27. PIDPressure False Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:15:33 +0800 KubeletHasSufficientPID kubelet has sufficient PID available
  28. Ready True Thu, 22 Sep 2022 18:29:09 +0800 Tue, 06 Sep 2022 23:16:24 +0800 KubeletReady kubelet is posting ready status
  29. Addresses:

image.png

之前

  1. [root@master kubernetes]# cat nginx.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx01
  6. spec:
  7. containers:
  8. - name: nginx01
  9. image: daocloud.io/library/nginx:1.7.9
  10. [root@master kubernetes]# kubectl apply -f nginx.yaml
  11. [root@master kubernetes]# kubectl get pod
  12. [root@master kubernetes]# kubectl get pod -o wide

image.png

之后

  1. [root@master kubernetes]# kubectl delete -f nginx.yaml
  2. pod "nginx01" deleted
  3. [root@master kubernetes]# cat nginx.yaml
  4. apiVersion: v1
  5. kind: Pod
  6. metadata:
  7. name: nginx01
  8. spec:
  9. nodeSelector:
  10. kubernetes.io/hostname: node2
  11. containers:
  12. - name: nginx01
  13. image: daocloud.io/library/nginx:1.7.9
  14. [root@master kubernetes]# kubectl apply -f nginx.yaml
  15. pod/nginx01 created
  16. [root@master kubernetes]# kubectl get pod -o wide
  17. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  18. nginx01 0/1 ContainerCreating 0 25s <none> node2 <none> <none>

image.png

NodeName举例

  1. [root@master kubernetes]# vim nginx.yaml
  2. [root@master kubernetes]# kubectl apply -f nginx.yaml
  3. pod/nginx01 created
  4. [root@master kubernetes]# kubectl get pod -o wide
  5. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  6. nginx01 1/1 Running 0 9s 10.244.1.7 node1 <none> <none>
  7. [root@master kubernetes]# cat nginx.yaml
  8. apiVersion: v1
  9. kind: Pod
  10. metadata:
  11. name: nginx01
  12. spec:
  13. nodeName: node1
  14. containers:
  15. - name: nginx01
  16. image: daocloud.io/library/nginx:1.7.9

HostAliases

  1. 类似域名解析
  2. 定义 Pod hosts 文件(比如 /etc/hosts)里的内容,用法:
  3. apiVersion: v1
  4. kind: Pod
  5. ...
  6. spec:
  7. hostAliases:
  8. - ip: "10.1.2.3"
  9. hostnames:
  10. - "foo.remote"
  11. - "bar.remote"
  12. ...
  13. 举例
  14. [root@master kubernetes]# kubectl apply -f nginx.yaml
  15. pod/nginx01 created
  16. [root@master kubernetes]# cat nginx.yaml
  17. apiVersion: v1
  18. kind: Pod
  19. metadata:
  20. name: nginx01
  21. spec:
  22. hostAliases:
  23. - ip: "192.168.31.31"
  24. hostnames:
  25. - "www.xlx.com"
  26. - "www.test.com"
  27. containers:
  28. - name: nginx01
  29. image: daocloud.io/library/nginx:1.7.9
  30. [root@master kubernetes]# kubectl get pods -o wide
  31. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  32. nginx01 1/1 Running 0 31s 10.244.1.8 node1 <none> <none>
  33. [root@master kubernetes]# kubectl exec -it nginx01 /bin/bash
  34. root@nginx01:/# cat /etc/hosts
  35. # Kubernetes-managed hosts file.
  36. 127.0.0.1 localhost
  37. ::1 localhost ip6-localhost ip6-loopback
  38. fe00::0 ip6-localnet
  39. fe00::0 ip6-mcastprefix
  40. fe00::1 ip6-allnodes
  41. fe00::2 ip6-allrouters
  42. 10.244.1.8 nginx01
  43. # Entries added by HostAliases.
  44. 192.168.31.31 www.xlx.com www.test.com

image.png

shareProcessNamespace

  1. 共享名称空间---【进程的名称空间】
  2. 表示这个 Pod 里的容器要共享 PID Namespace
  3. [root@master kubernetes]# vim nginx.yaml
  4. [root@master kubernetes]# kubectl apply -f nginx.yaml
  5. pod/nginx01 created
  6. [root@master kubernetes]# kubectl get pod
  7. NAME READY STATUS RESTARTS AGE
  8. nginx01 2/2 Running 0 9s
  9. [root@master kubernetes]# cat nginx.yaml
  10. apiVersion: v1
  11. kind: Pod
  12. metadata:
  13. name: nginx01
  14. spec:
  15. containers:
  16. - name: nginx01
  17. image: daocloud.io/library/nginx:1.7.9
  18. - name: busybox
  19. image: daocloud.io/library/busybox
  20. stdin: true
  21. tty: true
  22. [root@master kubernetes]# kubectl get pod
  23. NAME READY STATUS RESTARTS AGE
  24. nginx01 2/2 Running 0 9s
  25. 2/2
  26. 后面2表示有一个pod2个容器 前面2表示 2个都是运行的
  27. [root@master kubernetes]# kubectl exec -it nginx01 /bin/bash
  28. Defaulting container name to nginx01.
  29. Use 'kubectl describe pod/nginx01 -n default' to see all of the containers in this pod.
  30. 默认进来是第一个容器
  31. 指定进入哪个容器 -c
  32. [root@master kubernetes]# kubectl exec -it nginx01 -c busybox /bin/sh
  33. / #
  34. [root@master kubernetes]# kubectl exec -it nginx01 -c busybox /bin/sh
  35. / # ps
  36. PID USER TIME COMMAND
  37. 1 root 0:00 sh
  38. 18 root 0:00 /bin/sh
  39. 24 root 0:00 ps
  40. [root@master kubernetes]# cat nginx.yaml
  41. apiVersion: v1
  42. kind: Pod
  43. metadata:
  44. name: nginx01
  45. spec:
  46. shareProcessNamespace: true
  47. containers:
  48. - name: nginx01
  49. image: daocloud.io/library/nginx:1.7.9
  50. - name: busybox
  51. image: daocloud.io/library/busybox
  52. stdin: true
  53. tty: true
  54. [root@master kubernetes]# kubectl apply -f nginx.yaml
  55. pod/nginx01 created
  56. [root@master kubernetes]# kubectl get pod
  57. NAME READY STATUS RESTARTS AGE
  58. nginx01 2/2 Running 0 40s
  59. [root@master kubernetes]# kubectl exec -it nginx01 -c busybox /bin/sh
  60. / # ps
  61. PID USER TIME COMMAND
  62. 1 root 0:00 /pause
  63. 7 root 0:00 nginx: master process nginx -g daemon off;
  64. 13 101 0:00 nginx: worker process
  65. 14 root 0:00 sh
  66. 20 root 0:00 /bin/sh
  67. 26 root 0:00 ps
  68. stdin :-i
  69. tty -t

image.png
image.png
image.png

常用容器属性

  1. Pod 里最重要的字段"Containers"
  2. "Containers""Init Containers"这两个字段都属于 Pod 对容器的定义,
  3. 内容也完全相同,只是 Init Containers 的生命周期,会先于所有的 Containers
  4. 并且严格按照定义的顺序执行。
  5. K8S Container 的定义,和 Docker 相比并没有什么太大区别。
  6. DockerImage(镜像)、Command(启动命令)、workingDir(容器的工作目录)、
  7. Ports(容器要开发的端口),以及 volumeMounts(容器要挂载的 Volume
  8. 都是构成 K8S Container 的主要字段。

其他的容器属性

imagePullPolicy 字段

  1. 定义镜像的拉取策略。
  2. 之所以是一个 Container 级别的属性,是因为容器镜像本来就是 Container 定义中的一部分。
  3. 默认值: Always
  4. 表示每次创建 Pod 都重新拉取一次镜像。
  5. 当容器的镜像是类似于 nginx 或者 nginx:latest 这样的名字时,
  6. ImagePullPolicy 也会被认为 Always
  7. 值:Never 或者 IfNotPresent
  8. 表示 Pod 永远不会主动拉取这个镜像,或者只在宿主机上不存在这个镜像时才拉取。
  9. eg
  10. spec:
  11. containers:
  12. - name: kubernetes-dashboard
  13. image: kubernetesui/dashboard:v2.0.0-rc5
  14. imagePullPolicy: IfNotPresent

pod状态【生命周期】

  1. Pending
  2. 此状态表示Pod YAML 文件已经提交给了 KubernetesAPI 对象已经被创建并保存在 Etcd 当中。
  3. 但这个 Pod 里有些容器因为某种原因而不能被顺利创建。比如,调度不成功。
  4. Running
  5. 此状态表示Pod 已经调度成功,跟一个具体的节点绑定。它包含的容器都已经创建成功,
  6. 并且至少有一个正在运行中。
  7. Succeeded
  8. 此状态表示 Pod 里的所有容器都正常运行完毕,并且已经退出了。这种情况在运行一次性任务时最为常见。
  9. Failed:
  10. 此状态表示 Pod 里至少有一个容器以不正常的状态(非 0 的返回码)退出。
  11. 这个状态的出现,意味着你得想办法 Debug 这个容器的应用,比如查看 Pod Events 和日志。
  12. Unknown
  13. 这是一个异常状态,表示 Pod 的状态不能持续地被 kubelet 汇报给 kube-apiserver
  14. 这很有可能是主从节点(Master Kubelet)间的通信出现了问题。
  15. Pod 对象的 Status 字段,还可以再细分出一组 Conditions
  16. 这些细分状态的值包括:PodScheduledReadyInitialized,以及 Unschedulable
  17. 它们主要用于描述造成当前 Status 的具体原因是什么。