Pod 是 k8s 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最
小资源对象模型,也是在 k8s 上运行容器化应用的资源对象,其他的资源对象都是用来支
撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者
Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod
提供存储等等,k8s 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成。
Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为”根容器“的 Pause
容器。Pause 容器对应的镜 像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod
还包含一个或多个紧密相关的用户业务容器。
(1)d Pod s vs 应用
每个 Pod 都是应用的一个实例,有专用的 IP
(2 )d Pod s vs 容器
一个 Pod 可以有多个容器,彼此间共享网络和存储资源,每个 Pod 中有一个 Pause 容器保
存所有的容器状态, 通过管理 pause 容器,达到管理 pod 中所有容器的效果
(3)d Pod s vs 节点
同一个 Pod 中的容器总会被调度到相同 Node 节点,不同节点间 Pod 的通信基于虚拟二层网
络技术实现
(4)d Pod s vs Pod
普通的 Pod 和静态 Pod
(1)资源共享
一个 Pod 里的多个容器可以共享存储和网络,可以看作一个逻辑的主机。共享的如
namespace,cgroups 或者其他的隔离资源。
多个容器共享同一 network namespace,由此在一个 Pod 里的多个容器共享 Pod 的 IP 和
端口 namespace,所以一个 Pod 内的多个容器之间可以通过 localhost 来进行通信,所需要
注意的是不同容器要注意不要有端口冲突即可。不同的 Pod 有不同的 IP,不同 Pod 内的多
个容器之前通信,不可以使用 IPC(如果没有特殊指定的话)通信,通常情况下使用 Pod
的 IP 进行通信。
一个 Pod 里的多个容器可以共享存储卷,这个存储卷会被定义为 Pod 的一部分,并且可
以挂载到该 Pod 里的所有容器的文件系统上。
(2)生命周期短暂
Pod 属于生命周期比较短暂的组件,比如,当 Pod 所在节点发生故障,那么该节点上的 Pod
会被调度到其他节点,但需要注意的是,被重新调度的 Pod 是一个全新的 Pod,跟之前的
Pod 没有半毛钱关系。
(3)平坦的网络
K8s 集群中的所有 Pod 都在同一个共享网络地址空间中,也就是说每个 Pod 都可以通过其
他 Pod 的 IP 地址来实现访问。
(1)下面是 yaml 文件定义的 Pod 的完整内容
apiVersion: v1
kind: Pod
metadata: //元数据
name: string
namespace: string
labels:
-name: string
annotations:
-name: string
spec:
containers: //pod 中的容器列表,可以有多个容器
- name: string //容器的名称
image: string //容器中的镜像
imagesPullPolicy: [Always|Never|IfNotPresent]//获取镜像的策略,默认值为
Always,每次都尝试重新下载镜像
command: [string] //容器的启动命令列表(不配置的话使用镜像内部的命令) args:
[string] //启动参数列表
workingDir: string //容器的工作目录 volumeMounts: //挂载到到容器内部的存储
卷设置
-name: string
mountPath: string //存储卷在容器内部 Mount 的绝对路径 readOnly: boolean //
默认值为读写
ports: //容器需要暴露的端口号列表
-name: string
containerPort: int //容器要暴露的端口
hostPort: int //容器所在主机监听的端口(容器暴露端口映射到宿主机的端口,设置
hostPort 时同一 台宿主机将不能再启动该容器的第 2 份副本)
protocol: string //TCP 和 UDP,默认值为 TCP env: //容器运行前要设置的环境
列表
-name: string value: string
resources:
limits: //资源限制,容器的最大可用资源数量 cpu: Srting
memory: string
requeste: //资源限制,容器启动的初始可用资源数量 cpu: string
memory: string
livenessProbe: //pod 内容器健康检查的设置 exec:
command: [string] //exec 方式需要指定的命令或脚本 httpGet: //通过 httpget 检
查健康
path: string port: number host: string scheme: Srtring httpHeaders:
- name: Stirng value: string
tcpSocket: //通过 tcpSocket 检查健康
port: number initialDelaySeconds: 0//首次检查时间 timeoutSeconds: 0 //检查超时
时间
periodSeconds: 0 //检查间隔时间
successThreshold: 0
failureThreshold: 0 securityContext: //安全配置
privileged: falae
restartPolicy: [Always|Never|OnFailure]//重启策略,默认值为 Always
nodeSelector: object //节点选择,表示将该 Pod 调度到包含这些 label 的 Node 上,以
key:value 格式指定
imagePullSecrets:
-name: string
hostNetwork: false //是否使用主机网络模式,弃用 Docker 网桥,默认否
volumes: //在该 pod 上定义共享存储卷列表
-name: string emptyDir: {} hostPath:
path: string secret:
secretName: string item:
-key: string path: string
configMap: name: string items:
-key: string
path: string
在 kubernetes 中对运行容器的要求为:容器的主程序需要一直在前台运行,而不是后台运
行。应用需要改造成前 台运行的方式。如果我们创建的 Docker 镜像的启动命令是后台执行程序,则在 kubelet 创建包含这个容器的 pod 之 后运行完该命令,即认为 Pod 已经结束,将立刻销毁该 Pod。如果为该 Pod 定义了 RC,则创建、销毁会陷入一个无 限循环的过程中。Pod 可以由 1 个或多个容器组合而成。
(1)一个容器组成的Pod 的yaml
# 一个容器组成的 Pod
apiVersion: v1 kind: Pod metadata:
name: mytomcat labels:
name: mytomcat spec:
containers:
- name: mytomcat image: tomcat ports:
- containerPort: 8000
(2)多个容器组成的Pod的yaml
#两个紧密耦合的容器
apiVersion: v1 kind: Pod metadata:
name: myweb labels:
name: tomcat-redis
spec:
containers:
-name: tomcat image: tomcat ports:
-containerPort: 8080
-name: redis image: redis ports:
-containerPort: 6379
(3)Pod相关命令
创建pod
kubectl create -f xxx.yaml
查看
kubectl get pod/po
kubectl get pod/po -o wide
kubectl describe pod/po
删除
kubectl delete -f pod pod_name.yaml
kubectl delete pod --all/[pod_name]
Pod有两种类型
(1)普通Pod
普通 Pod 一旦被创建,就会被放入到 etcd 中存储,随后会被 Kubernetes Master 调度到某
个具体的 Node 上并进行绑定,随后该 Pod 对应的 Node 上的 kubelet 进程实例化成一组相
关的 Docker 容器并启动起来。在默认情 况下,当 Pod 里某个容器停止时,Kubernetes 会
自动检测到这个问题并且重新启动这个 Pod 里某所有容器, 如果 Pod 所在的 Node 宕机,
则会将这个 Node 上的所有 Pod 重新调度到其它节点上。
(2)静态Pod
静态 Pod 是由 kubelet 进行管理的仅存在于特定 Node 上的 Pod,它们不能通过 API Server
进行管理,无法与 ReplicationController、Deployment 或 DaemonSet 进行关联,并且
kubelet 也无法对它们进行健康检查。
(1)Pod的状态
状态值 | 说明 |
---|---|
Pending | API Server已经创建了该Pod,但Pod中的一个或多个容器还没有创建,包括镜像下载过程 |
Running | Pod内所有的容器已创建,且至少一个容器处于运行状态、正在启动状态或正在重启状态 |
Completed | Pod内所有的容器均成功执行退出,且不会再重启 |
Failed | Pod内所有容器均已退出,但至少一个容器退出失败 |
Unknown | 由于某种原因无法获取Pod状态,例如网络通信不畅 |
(2)Pod重启策略
Pod的重启策略包括Always、OnFailure和Never,默认值是Always。
重启策略 | 说明 |
---|---|
Always | 当容器失效时,由Kubelet自动重启该容器 |
OnFailure | 当容器终止运行且退出码不为0时,由Kubelet自动重启该容器 |
Never | 不论容器运行状态如何,Kubelet都不会重启该容器 |
每个 Pod 都可以对其能使用的服务器上的计算资源设置限额,Kubernetes 中可以设置限额
的计算资源有 CPU 与 Memory 两种,其中 CPU 的资源单位为 CPU 数量,是一个绝对值而非相
对值。Memory 配额也是一个绝对值,它的单 位是内存字节数。
Kubernetes 里,一个计算资源进行配额限定需要设定以下两个参数: Requests 该资源最
小申请数量,系统必须满足要求 Limits 该资源最大允许使用的量,不能突破,当容器试
图使用超过这个量的资源时,可能会被 Kubernetes Kill 并重启
举例
sepc
containers:
- name: db
image: mysql
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
上述代码表明 MySQL 容器申请最少 0.25 个 CPU 以及 64MiB 内存,在运行过程中容器所能使
用的资源配额为 0.5 个 CPU 以及 128MiB 内存。