一、Pod介绍
什么是Pod?
-
pod是容器集(一个或多个容器), 是Kubernetes管理(调度、部署、运行应用)的最小单元
- 同一个pod中的多个容器 只能运行在同一个node之上
- 必须是超亲密关系的容器 才能编排在一个pod中
- “超亲密”关系的容器 必须要在一个pod中的容器 例如mysql、mysql-exporeter
-
同一个pod中的存储资源、网络资源、运行容器的控制策略 都是共享的
- 举例: pod中挂载了一个卷 所有的容器都可以看到
-
CRI(Container Runtime Interface)的抽象
- pod的底层 存在pasuse容器
- 每个容器的mount user namespace是独占的
- 默认IPC UTS network是共享的, PID 也可以共享 但是需要显示的定义
-
Pod是运行应用的原子单元,其生命周期管理和健康状态监测由kubelet负责完成,
- 而诸如更新、扩缩容和重建等应用编排功能需要由专用的控制器实现,这类控制器即工作负载型控制器
本质上是共享Network、IPC和UTS名称空间以及存储资源的容器集
- 可将其想象成一台物理机或虚拟机,各容器就是该主机上的进程
- 同一POD中的各容器共享网络协议栈、网络设备、路由、IP地址和端口
- 同一POD中的各容器Mount、PID和USER 是隔离的
- 每个Pod上还可附加N个“存储卷(Volume)”作为该“主机”的外部存储,独立于Pod的生命周期,可由Pod内的各容器共享
类型展开
- ReplicaSet和Deployment 无状态
- DaemonSet 系统应用使用
- StatefulSet 有状态应用
- Job和CronJob 作业类的应用
pod 的组织原则
在设计上,仅应该将具有“超亲密”关系的应用分别以不同 容器的形式运行于同一Pod内部
linux mysql nginx php不是超亲密关系 tomcat 日志收集(fluted)是超亲密关系 mysql mysql_exporter(promethues)是超亲密关系
pod的特性
- pod封装的内容:可被该组容器共享的存储资源、网络协议栈及容器的运行控制策略等
- 依赖于pause容器事先创建出可被各应用容器共享的基础环境,
- 同一个pod中的容器 默认共享Network、IPC和UTS名称空间
- PID名称空间也可以共享,但需要用户显式定义
pod的类型
一般不会手工创建pod 都是通过控制器创建的
-
1.自主式pod
- 不受控于 任何控制器
- 问题:如果所在节点宕机 pod就没了 不会有控制器进行监控 和 状态的校对
- 不受控于 任何控制器
-
2.静态pod
- kubelet启动后 自动运行的pod 其定义不存在APIserver上 也不受控任何控制器
- 查看方法 kubectl get pods -n kube-systems
-
3.由控制器创建的pod
- 如果宕机导致pod没了 会有控制器进行监控和校对
Pod的组成形式?
- 单容器Pod:内部仅含有单个容器
- 多容器Pod:内部含有多个具有“超亲密”关系的容器
- 同一Pod内的所有容器都将运行于由Scheduler选定的同一个节点上
什么是静态 Pod?
“静态 Pod”非常特殊,它不受 Kubernetes 系统的管控,不与 apiserver、scheduler 发生关系,所以是“静态”的。
但既然它是 Pod,也必然会“跑”在容器运行时上,也会有 YAML 文件来描述它,而唯一能够管理它的 Kubernetes 组件也就只有在每个节点上运行的 kubelet 了。“静态 Pod”的 YAML 文件默认都存放在节点的 /etc/kubernetes/manifests 目录下,它是 Kubernetes 的专用目录
Kubernetes 的 4 个核心组件 apiserver、etcd、scheduler、controller-manager 原来都以静态 Pod 的形式存在的,这也是为什么它们能够先于 Kubernetes 集群启动的原因。
如果你有一些 DaemonSet 无法满足的特殊的需求,可以考虑使用静态 Pod,编写一个 YAML 文件放到这个目录里,节点的 kubelet 会定期检查目录里的文件,发现变化就会调用容器运行时创建或者删除静态 Pod
什么是pause容器?
- 创建POD时, 需要Network、IPC和UTS namespace 给到Pause容器
- 创建的POD共享 Pause容器的namespace
- 是一个暂停的容器 为pod提供基础环境: PID IPC UTS network
- pod可以借助 存储插件, 创建独立于pod的 外部存储空间(即卷)
- pod中所有的contrainer都可以 使用这个外部的存储空间
为什么引入namespace?
多租户的情况 大家都可以创建name=pro-nginx容器, 每个namespace中 就不能重复定义了 为了避免无法使用统一资源名称的问题 引入了 “名称空间 namespace”
都有哪些默认的namespace?
默认是4个 kubectl get ns
root@k8s-node01:~# kubectl get ns
NAME STATUS AGE
default Active 41h
kube-flannel Active 23h
kube-node-lease Active 41h
kube-public Active 41h
kube-system Active 41h
default空间
默认名称空间 默认创建的名称空间级别的资源、对象, 如果创建资源的时候没有指定namespace, 就会处于default之下
kube-node-lease 空间
租约
kube-public 空间
kube-system 空间
k8s自身使用的 一些关键组件会处于此
二、Pod资源规范
定义规范
一个极简的Pod定义,仅需要为其指定一个要运行的容器即可
apiVersion:v1
kind: Pod
metadata:
name: … # Pod的标识名,在名称空间中必须惟一;
namespace: … # 该Pod所属的名称空间,省略时使用默认名称空间default;
spec:
containers: # 定义容器,它是一个列表对象,可包括多个容器的定义,至少得有一个;
- name: … # 容器名称,必选字段,在当前Pod中必须惟一;
image: … # 创建容器时使用的镜像;
Pod资源的示例
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
spec:
containers:
- name: demo
image: ikubernetes/demoapp:v1.0
三、pod相关的命令
创建namespce
root@k8s-master01:~/pratice# kubectl create namespace test
namespace/test created
查看ns
root@k8s-master01:~/pratice# kubectl get ns
NAME STATUS AGE
default Active 43h
kube-flannel Active 43h
kube-node-lease Active 43h
kube-public Active 43h
kube-system Active 43h
test Active 10s
灵活的使用kubectl explain
# 查看用法 和关键字段
kubectl explain pods.spec
打印Pod完整的资源规范,通过status字段了解
commands:
kubectl get TYPE(资源类型 pods/service) NAME(资源名称) -o yaml|json
示例:
kubectl get pods demoapp-75f59c894-kmzlv -o yaml
kubectl get pods demoapp-75f59c894-kmzlv -o json
打印Pod资源的详细状态
commands:
kubectl describe TYPE NAME
示例:
kubectl describe pods demoapp-75f59c894-kmzlv -o yaml
获取Pod中容器应用的日志
commands:
kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]
示例:
kubectl logs demoapp -c demoapp
四、Pod的phase和重启策略
pod的相位(运行状态)
由kubelet探测pod的状态
- Pending
- 没有被scheduler调度完成之前 就是一个挂起的状态
- Running
- 正常启动之后的状态
- Successed
- 如果是作业类的应用 是存在退出时间的 一但运行成功 并且结束的话 就会处于此状态
- Failed
- 如果是作业类的应用 是存在退出时间的 没有运行成功的 就会处于此状态
- Unkonwn
- kubelet连接不上pod的时候 会出现
- 非正常状态
- 常见的错误状态 crash...
容器的状态
- Waiting
- Running
- Terminated
- Unkonwn
Pod的重启策略
重启决定了容器终止后是否应该重启
- Always:无论何种原因(exit code)导致的退出 都要重启容器
- OnFailure
- 仅在exit code为非0值(即错误退出)时才重启容器,
- 如果是正常终止的情况 就不会重启
- Never:无论何种exit code,都不重启容器
如何定义重启策略?
查看定义 kubectl explain pod.spec.restartPolicy
root@k8s-master01:~/pratice# kubectl explain pod.spec.restartPolicy
KIND: Pod
VERSION: v1
FIELD: restartPolicy <string>
DESCRIPTION:
Restart policy for all containers within the pod. One of Always, OnFailure,
Never. Default to Always. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
Possible enum values:
- `"Always"`
- `"Never"`
- `"OnFailure"`
配置示例
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: test
spec:
containers:
- name: test-restart-policy
image: ikubernetes/demoapp:v1.0
restartPolicy: Always