为什么需要Pod?
- 进程是以进程组的方式组织在一起。
- 受限制容器的“单进程模型”, 成组调用没有被妥善处理(资源调用有限),使用资源囤积则导致复杂度上升。
在k8s项目中,Pod的实现需要使用一个中间容器——Infra容器,该容器永远是第一个被创建的容器,用户定义的其他容器则通过Join Network Namespace的方式与Infra容器关联在一起。
initContainer
Init Container容器会按顺序逐一启动,而直到它们启动并且退出了,用户容器才会启动
nodeselector
nodeselector:
disktype: ssd
意味着这个Pod只能在携带disktype:ssd标签的节点上运行,否则调度失败
NodeName
一旦Pod的这个字段被赋值,K8s则认为这个Pod已经被调度
HostAliases
定义了Pod的host文件(比如/etc/hosts)里的内容
shareProcessNamespace
这个Pod里的容器要共享PID Namespace,Pod就是要让其中的容器尽可能多地共享Linux Namespace
HostNetwork, hostIPC, hostPID
待补充
Lifecycle
- postStart: 在容器启动后立即执行一个指定操作。虽然在Docker ENTRYPOINT执行之后,但并不严格保证顺序。
- preStop:容器被结束之前(比如收到了SIGKILL信号)执行是同步的。
Pod的生命周期
- Pending:Pod的YAML文件已经提交给了k8s,API对象已经创建并保存到etcd中。但是Pod里的容器因为某种原因不能被顺利创建(比如:调度不成功)。
- Running:
- Succeeded:一段时间就退出的Pod,反馈任务执行的结果(运行一次性任务时最为常见)。
- Failed:Pod里至少有一个容器以不正常的状态(非0的返回码)退出。查看Events和日志。
- Unknown:异常状态,很有可能是Master和kubelet间的通信出了问题。
特殊的Volume
Secret
Pod想要访问的加密数据存放到etcd中,可以通过Pod的容器里挂载Volume的方式去访问Secret里保存的信息。
k create secret generic user --from-file=./username.txt
k create secret generic pass --from-file=./password.txt
也可以使用Secret.yaml来进行生成。
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU2
但Secret对象要求这些数据需要经过Base64进行转码,同时创建出来的Secret对象只有一个,在data中以key-value的形式保存。
ConfigMap
使用properties文件生成ConfigMap,与Secret区别在ConfigMap保存的是无须加密、应用所需的配置信息。
Downward API
让Pod里的容器能够直接获取这个Pod API对象本身的信息。比如可以获取Pod的Labels字段的值
注意
通过环境变量获取这些信息的方式不具备自动更新的能力,建议使用volume文件的方式获取这些消息。
ServiceAccountToken
是一种特殊的Secret对象,每一个Pod都已经自动声明了一个类型是Secret、名为default-token-xxxx的Volume,然后自动挂载在每一个容器的一个固定目录上。
考虑到自动挂载默认ServiceAccountToken的潜在风险,K8s允许设置默认不为Pod里的容器自动挂载Volume
容器健康检查和恢复机制
容器健康检查-liveness
apiVersion: v1
kind: Pod
metadata:
name: test-liveness-exec
labels:
test: liveness
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
也可以定义为发起HTTP或者TCP请求的方式。所以Pod其实可以暴露一个健康检查URL(/healthz)
恢复机制 restartPolicy
默认值为Always,Pod的恢复过程永远发生在当前节点上,而不会跑到别的节点上。
- Always
- OnFailure
- Never:如果关心这个容器退出后的上下文环境,比如容器退出后的日志、文件和目录,就需要将restartPolicy设置为Never
PodPreset
Pod的annotation会表示该Pod被PodPreset改动过,并且修改对象只能是Pod。