文章目录
声明 该系列文章属于极客时间专栏 ”深入剖析Kubernetes“学习笔记
pod 是k8s中最小的编排单位,从API的角度看,容器(Container)就是pod属性里的一个普通字段,那么那些属性是属于pod,哪些属性又是属于container呢?
凡是调度、网络、存储以及安全相关的属性,基本是属于pod的属性。
接下来我们需要了解一些pod中重要的字段。
** NodeSelector** :将Pod和Node进行绑定,用法如下:
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
disktype: ssd
这意味着这个pod只能运行在带有”disktype:ssd“标签的节点上,否则会调度失败。
NodeName:一旦pod的这个字段被赋值,k8s会认为这个pod已经被调度了,调度的结果就是赋予节点名字。这个字段一般有调度器负责,用户可以设置他来骗过调度器。
HostAliases:定义Pod的hosts文件(比如/etc/hosts)里的内容,用法如下:
apiVersion: v1
kind: Pod
...
spec:
hostAliases:
- ip: "10.1.2.3"
hostnames:
- "foo.remote"
- "bar.remote"
...
pod启动后,/etc/hosts文件的内容如下:
cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
...
10.244.135.10 hostaliases-pod
10.1.2.3 foo.remote
10.1.2.3 bar.remote
最下面两行就是通过HostAliases字段设置的。在k8s中设置hosts文件内容一般通过这种方法,如果直接修改hosts文件,当pod被删除重建之后,kubelet会自动覆盖被修改的内容。
凡是跟容器的Linux NameSpace相关的属性,也一定是Pod级别的。
举个例子,在pod的YAML文件中设置shareProcessNameSpace=true:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true
containers:
- name: nginx
image: nginx
- name: shell
image: busybox
stdin: true
tty: true
这意味这这个Pod里的容器共享PID NameSpace也就是说整个Pod里的每个容器进程,对所有容器都是可见的,他们共享同一个PID NameSpace。
Pod中最重要的字段是Containers。Kubernetes 项目中对 Container 的定义,和 Docker 相比并没有什么太大区别。Image(镜像)、Command(启动命令)、workingDir(容器的工作目录)、Ports(容器要开发的端口),以及 volumeMounts(容器要挂载的 Volume)都是构成 Kubernetes 项目中 Container 的主要字段。除了这些字段外,还需要关注一些额外的字段。
ImagePullPolicy定义了镜像拉去的策略。默认为Always,即每次创建Pod都需要重新拉取一次镜像。当容器镜像的名字类似于nginx或者nginx:latest时,该字段会被认为是Always。如果他的值被定义为Never或者IfNotPresent,Pod不会主动拉去镜像,或者只在宿主机上不存在这个镜像时才拉取。
Lifecycle他定义的时Container Lifecycle Hooks,意思是在容器状态发生变化时出发一系列”钩子“。
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
在YAML文件的containers部分设置了一个postStart和preStop参数。先说postStart,它值的是容器启动之后执行一个指定的操作。preStop发生的时机是在容器被杀死之前,(比如,收到SIGKILL信号)。他会阻塞当前容器杀死流程,直到这个Hook定义的操作完成之后,才允许容器被杀死。
Pod对象在Kubernetes中的生命周期,主要体现在Pod API对象的Status部分,这是除了Metadata和Spec之外的第三个重要字段。其中,pod.status.phase,就是 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)间的通信出现了问题。