1. Pod容器分类
Infrastructure Container:基础容器
• 维护整个Pod网络空间
• InitContainers:初始化容器
• 先于业务容器开始执行
• Containers:业务容器
• 并行启动
2. 镜像拉取策略
官方文档网址:https://kubernetes.io/docs/concepts/containers/images/
IfNotPresent:默认值,镜像在宿主机上不存在时才拉取
• Always:每次创建 Pod 都会重新拉取一次镜像
• Never: Pod 永远不会主动拉取这个镜像
3. 重启策略
重启逻辑:每次重启会有等待时间,最长为300s
当pod调度在某个node节点上的时候,容器重启只会帮你重新拉起来,并不会更换节点,除非你删除pod,他会按照调度分配来帮你重新拉起一个pod
当结束一个pod的时候,pod中的所有容器发送关闭信号,给一个时间限制,在xx时间内平滑的关闭,如果时间到了没关,会强制关闭,以防止数据丢失,默认30s,可以自己指定
• Always:当容器终止退出后,总是重启容器,默认策略。
• OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。
• Never:当容器终止退出,从不重启容器。
4.POD生命周期
创建pod
初始化容器
容器探测
Liveness probe
Readines probe
Init初始化前的准备
Post start启动后钩子
Post stop结束前钩子
Liveness probe存活状态检测 判定主容器是否处于运行状态
Readines probe就绪状态检测 判定主容器中的主进程是否准备就绪并可以对外提供服务
Liveness probe如果出问题要受控于Readines probe来决定是否重启
容器如果Running 存活探测是成功的,容器存活并不一定可以对外提供服务,docker如果容器不提供的话容器就结束了,而k8s中一个pod中可以有多个容器,一个容器死亡,并不会让pod死亡,Liveness probe和Readines probe都有三种方式
容器启动前做操作lifecycle(钩子)包括poststart和poststop,也支持ExecAction、TCPSocketAction、
HTTPGetAction,极少情况会用到,下面的command(有红框的)优先级要比exec下方的command优先级高,
也就意味之先执行带红框的command,后执行exec下面的command,
官网为:https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
5. 健康检查
官方文档网址:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
1 探针类型有三种:
ExecAction(shell命令)、
TCPSocketAction(针对端口)
HTTPGetAction(url get请求)
2 Probe有以下两种类型:
Liveness probe存活状态检测 判定主容器是否处于运行状态
Readines probe就绪状态检测 判定主容器中的主进程是否准备就绪并可以对外提供服务
1 Liveness probe区别Readines probe
Liveness probe是按照他所设定的标准检查容器是否符合规则,如果不符合就重启容器,
这里的重启容器是指重新来一个新的容器,
Readines probe是指按照他的标准来检查容器是否可以对外提供服务并为其引入流量
如果他检测失败,那么service的endpoint里面将不会被转发,
如下图所示
此图为两者检查都失败
此图为Liveness probe成功,Readines probe失败
所以存活并不一定就绪,进程运行并不一定提供服务,就比如nginx运行但是网页文件没了,
只能说未就绪但是还活着,具体怎么设置还需要按照需求来执行,但是两种检测机制是必须都得有的
3 Probe支持以下三种检查方法:
httpGet 发送HTTP请求,返回200-400范围状态码为成功。
exec 执行Shell命令(命令一定得存在)返回状态码是0为成功
tcpSocket 发起TCP Socket建立成功
如果容器端口有命名,那么我们可以直接用命名例如
4 配置探针字段释意
initialDelaySeconds:启动活动或准备就绪探测之前容器启动后的秒数。
periodSeconds:执行探测的频率(以秒为单位)。默认为10秒。最小值为1。
timeoutSeconds:探测超时的秒数。默认为1秒。最小值为1。
successThreshold:失败后探测成功的最小连续成功次数。默认为1.活跃度必须为1。最小值为1。
failureThreshold:当Pod启动并且探测失败时,Kubernetes会failureThreshold在放弃之前尝试一次。在活动探测的情况下放弃意味着重新启动Pod。如果准备好探测,Pod将被标记为未准备好。默认为3.最小值为1。
HTTP探针 具有可以设置的其他字段httpGet:
host:要连接的主机名,默认为pod IP。您可能希望在httpHeaders中设置“主机”。
scheme:用于连接主机的方案(HTTP或HTTPS)。默认为HTTP。
path:HTTP服务器上的访问路径。
httpHeaders:要在请求中设置的自定义标头。HTTP允许重复标头。
port:容器上要访问的端口的名称或编号。数字必须在1到65535的范围内。
对于HTTP探测,kubelet将HTTP请求发送到指定的路径和端口以执行检查。kubelet将探测器发送到pod的IP地址,除非地址被可选host字段覆盖httpGet。如果 scheme字段设置为HTTPS,则kubelet会发送跳过证书验证的HTTPS请求。在大多数情况下,您不希望设置该host字段。这是您设置它的一个场景。假设Container侦听127.0.0.1并且Pod的hostNetwork字段为true。然后host,在httpGet,应设置为127.0.0.1。如果您的pod依赖虚拟主机,这可能是更常见的情况,您不应该使用host,而是设置Host标头httpHeaders。
对于探测器,kubelet在节点处而不是在pod中进行探测连接,这意味着您无法在host参数中使用服务名称,因为kubelet无法解析它。
5 格式分别为
1 Httpget格式
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
1 在配置文件中,您可以看到Pod具有单个Container。
2 该periodSeconds字段指定kubelet应每3秒执行一次活跃度探测。
3 该initialDelaySeconds字段告诉kubelet它应该在执行第一次探测之前等待3秒。
4 为了执行探测,kubelet向在Container中运行的服务器发送HTTP GET请求并侦听端口8080.如果服务器/healthz路径5 5 的处理程序返回成功代码,则kubelet认为Container是活动且健康的。
6 如果处理程序返回失败代码,则kubelet会终止Container并重新启动它。
7 任何大于或等于200且小于400的代码表示成功。任何其他代码表示失败。
(2)Exec格式
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/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
1 在配置文件中,您可以看到Pod具有单个Container。
2 该periodSeconds字段指定kubelet应每5秒执行一次活跃度探测。
3 该initialDelaySeconds字段告诉kubelet它应该在执行第一次探测之前等待5秒。
4 要执行探测,kubelet将cat /tmp/healthy在Container中执行命令。
5 如果命令成功,则返回0,并且kubelet认为Container是活动且健康的。
6 如果该命令返回非零值,则kubelet会终止Container并重新启动它。
7 当Container启动时,它会执行以下命令:
8 /bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
9 在Container的生命的前30秒,有一个/tmp/healthy文件。
10 因此,在前30秒内,该命令cat /tmp/healthy返回成功代码。30秒后,cat /tmp/healthy返回失败代码。
(3)tcpSocker格式
第三种类型的活动探测器使用TCP套接字。使用此配置,kubelet将尝试在指定端口上打开容器的套接字。如果它可以建立连接,则容器被认为是健康的,如果它不能被认为是失败的话。
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
1 如您所见,TCP检查的配置与HTTP检查非常相似。
2 此示例使用就绪和活性探针。在容器启动5秒后,kubelet将发送第一个就绪探测器。
3 这将尝试连接到goproxy端口8080上的容器。
4 如果探测成功,则该pod将标记为就绪。
5 kubelet将每10秒继续运行此检查。
6 除准备探测外,此配置还包括活动探测。
7 在容器启动15秒后,kubelet将运行第一个活体探测器。
10 就像准备探测一样,这将尝试连接到goproxy端口8080上的 容器。
11 如果活动探测失败,容器将重新启动。
6. 调度约束
• nodeName用于将Pod调度到指定的Node名称上
nodeName: 192.168.31.65
• nodeSelector用于将Pod调度到匹配Label的Node上
nodeSelector:
env_role: dev
Api server负责总调度,scheduler负责调度分配新的pod在那个节点上创建(有资源的节点),
然后api server写入etcd中,并且把表交给kubelet来做pod的创建,调用docker来镜像拉取,容器的创建
7. 故障排查
官方文档地址:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
值 描述
1Pending(挂起) Pod创建已经提交到Kubernetes。
但是,因为某种原因而不能顺利创建。例如下 载镜像慢,调度不成功。
2 Running Pod已经绑定到一个节点,并且已经创建了所有容器。
至少有一个容器正在运行 中,或正在启动或重新启动。
3 Succeeded Pod中的所有容器都已成功终止,不会重新启动。
4 Failed Pod的所有容器均已终止,且至少有一个容器已在故障中终止。
也就是说,容器 要么以非零状态退出,要么被系统终止。
5 Unknown 由于某种原因apiserver无法获得Pod的状态,
6 通常是由于Master与Pod所在主机 kubelet通信时出错。
CrashLoopBackOff 可能是在拉取镜像
kubectl describe TYPE/NAME
kubectl logs TYPE/NAME [-c CONTAINER]
kubectl exec POD [-c CONTAINER] -- COMMAND [args...]
出现问题别慌张,可以根据他发生的事件以及日志或者进去容器查看,来迅速锁定原因并解决
8.YAML文件范本
大部分资源的配置清单:
apiVersion: apps/v1 group/version
$ kubectl api-versions
kind:资源类别
metadata:元数据
name
namespace
labels
annotaions
spec:期望的状态 disired state
status:当前状态 current state,这个字段由kuernetes集群维护
也可以protocol定义tcp或者udp
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default #指定命名空间
labels:
app: nginx #控制器的标签
spec: #控制器期望的状态
replicas: 1 #指定副本个数
selector: #标签选择器
matchLabels: #逻辑域(可以写多个标签)
app: nginx
template: #pod模板定义
metadata: #pod的元数据
labels: #pod标签一定符合标签选择器,至少符合标签选择器的一个
app: nginx
spec: #pod的期望的状态
nodeName: k8s-node1 #指定分配节点
containers: #列表所以下面会有-
- name: nginx-deployment #镜像
image: nginx:1.15
imagePullPolicy: Always #拉取镜像策略
livenessProbe: #Http探测
httpGet:
path: index.html
port: 80
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 60
periodSeconds: 3
resources: #限制策略
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
restartPolicy: Always #重启策略
9.command和args比较
官网文档:https://kubernetes.io/docs/tasks/inject-data-application/
如果在dockerfile中既有Entrypoint又有Cmd,那么cmd将作为Entrypoint命令中的参数运行
dockerfile kubernetes field
Entrypoint command
Cmd args
1.如果你的k8s 的yaml文件中没有command和args的情况下默认使用dockerfile的Entrypoint和Cmd,
当然如果镜像中只有cmd,那么就按照cmd的命令来执行,如果两者都有那么cmd将作为参数传入Entrypoint中
2如果k8s的yaml文件中只提供了args,如果dockerfile中有Entrypoint,args作为参数,传入Entrypoint,cmd被忽略。
如果dockerfile中没有Entrypoint,那么将执行args
3.如果既有command又有args,那么args将作为command的参数来运行
4.如果只有command,那么dockerfile的所有将被忽略,之运行command