K8s资源文件 Pod
init Container定义的容器 会按照资源文件顺序优先启动,知道它们启动并且退出了,用户容器才会启动
字段
- NodeSelector :指定Pod与Node进行绑定的字段
apiVersion: v1
kind: Pod
...
spec:
nodeSelector: #这个Pod只能运行在disktype: ssd标签的节点上
disktype: ssd
- NodeName: Pod的这个字段被赋值,K8s就会认为这个Pod已经经过了调度,调度的结果就是赋值节点名字,所以如果手动设置一般用来测试用
- HostAlizses: 定义了Pod的hosts文件
apiVersion: v1
kind: Pod
...
spec:
hostAliases: #Pod重建后kubelet会自动覆盖被修改的内容 所以修改资源文件来代替直接修改/etc/hosts
- ip: "10.1.2.3"
hostnames:
- "foo.remote"
- "bar.remote"
...
- shareProcessNamespace: PID Namespace
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true #开启之后 下面两个容器共享PID Namespace
containers:
- name: nginx
image: nginx
- name: shell
image: busybox
stdin: true #-i 交互
tty: true #-t 终端
=====================================================
kubectl apply -f nginx.yaml #执行上面的资源文件
kubectl attach -it nginx -c shell #进入nginx Pod中的shell容器的tty上
#进入之后 即可ps查看所有正在运行的进程
ps ax
PID USER TIME COMMAND
1 root 0:00 /pause #infra容器 一直是暂停状态 所以取名pause
8 root 0:00 nginx: master process nginx -g daemon off; #nginx容器进程
14 101 0:00 nginx: worker process
15 root 0:00 sh
21 root 0:00 ps ax #ps ax本身
#需要开启 apiserver的sharepid功能 1.11后默认开启
- ImagePullPolicy: 定义镜像拉取策略
ImagePullPolicy: Always #Always 每次创建Pod都重新拉取一次镜像
#Never Pod永远不会主动拉取这个镜像
#默认值ifNotPresent 只在宿主机上不存在这个镜像时才拉取
- Lifecycle: 定义Container Lifecycle Hooks 定义容器状态发生变化时触发一系列“钩子”
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle: #定义钩子
postStart: #容器启动后 执行时ENTRYPOINT可能没有结束
exec: #执行操作 如果失败 Pod的Events中会报错 导致整个Pod报错
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop: #容器杀死前 会阻塞杀死
exec: #执行操作
command: ["/usr/sbin/nginx","-s","quit"]
Pod生命周期
pod除Metadata(元数据)和Spec(资源详细定义)之外第三个重要的字段 Status
pod.status.phase Pod的当前状态
kubectl get pod -o wide
- Pending
- 当前状态,Pod的YAML文件已经提交给了K8s,API对象已经被创建并保存在Etcd中,但是这个Pod里有些容器因为某种原因不能顺利创建。比如,调度失败(没有符合条件的节点)
- Condition: Unschedulable
- 当前状态,Pod的YAML文件已经提交给了K8s,API对象已经被创建并保存在Etcd中,但是这个Pod里有些容器因为某种原因不能顺利创建。比如,调度失败(没有符合条件的节点)
- Running
- 当前状态,Pod已经调度成功,跟一个具体的节点绑定。它包含的容器都已经创建成功,并且至少有一个正在运行中
- Succeeded
- 当前状态,Pod里的所有容器都正常运行完毕,并且已经退出了。一次性任务时最常见
- Failed
- 当前状态,Pod里至少有一个容器以非正常的状态(非0的 返回码)退出。这个状态下,需要debug这个容器的应用,可以查看Pod的Events和日志
- Unknown
- 异常状态,意味着Pod的状态不能持续地被kubelet汇报给kube-apiserver,可能是(Master和Kubelet)之间的通信出现问题
Pod对象的Status字段,还可以再细分出一组Conditions : PodScheduled 、Ready、lnitialized、Unschedulable 描述造成当前Statu的具体原因
Ready可能情况
- 程序本身有bug 返回500 而非200
- 程序内存问题,进程还在,但已经无响应了
- Dockerfile 写的不规范,应用程序不是主进程(之前CMD写的参数错了,容器跑不起来)
- 程序出现死循环
Pod特殊的volume(投射数据卷)
- Secrete 密码信息获取
- 创建Secrete对象保存加密数据,存放到Etcd中。然后,你就可以通过在Pod的容器里加载Volume的方式,访问到这些Secret里保存的信息
- ConfigMap 配置信息获取
- 创建ConfigMap对象保存数据,存放到Etcd中。然后,通过挂载Volume的方式,访问到ConfigMap里保存的内容
- DownwardAPI
- 容器获取Pod中定义的静态信息,通过挂载DownwardAPI这个特殊的Volume,访问到Pod中定义的静态信息
- ServiceAccountToken
- Pod中要访问K8s的API,任何运行在K8s集群上的应用,都必须使用这个ServiceAccountToken里保存的授权信息,也就是Token,才可以合法地访问API Server,所以,通过挂载Volume的方式,把对应权限的ServiceAccountToken这个特殊的Secrete挂载到Pod中即可
容器健康检查和恢复机制
在Pod中定义一个健康检查“探针”(Probe)
kubelet会根据Probe的返回值来决定这个容器的状态 而并非直接以容器镜像是否运行(Docker返回的信息)作为依据
有三种类型的处理程序
- ExecAction: 在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功
- TCPSocketAction: 对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的。
- HTTPGetAction: 对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的
诊断
探针探测状态
- Success : 容器通过了诊断
- Failure: 容器未通过诊断
- Unknown:诊断失败,因此不会采取任何行动
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: test-liveness-exec
spec:
containers:
- name: liveness
image: busybox
args: #启动之后就执行
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe: #探针
exec: #类型是exec
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5 #在容器启动后5秒执行
periodSeconds: 5 #每5s执行一次
#启动之后就在/tmp目录下创建一个healthy文件,表示自己已经正常运行的标志。30s之后,它会把这个文件删除掉 容器启动5s之后以5s的间隔cat /tmp/healthy 命令 返回健康状态
- spec.container.livenessProbe
- 指示容器是否正在运行。如果存活态探测失败,则kubelet会杀死容器,并且容器将根据其重启策略决定未来。如果容器不提供存活探针,则默认状态为Success
- restartPolicy:Always值代表如果这个容器发生了异常,它一定会被重新创建
- OnFailure: 当探测失败时
- spec.container.readinessProbe
- 指示容器是否准备好为请求提供服务。如果就绪探测失败,端点控制器将从与Pod匹配的所有服务的端点列表中删除该Pod的IP地址。初始延迟之前的就绪态的状态值默认为Failure。如果容器不提供就绪态探针,则默认状态为Success.
- spec.container.startupProbe
- 指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。如果启动探测失败,Kubelet将杀死容器,而容器依其重启策略进行重启,如果容器没有提供启动探测,则默认状态为Success