k8s---生命周期、控制器
一.Pod生命周期Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少 其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以 失败状态结束而进入 Succeeded 或者 Failed 阶段。在 Pod 运行期间,kubelet 能够重启容器以处理一些失效场景。 在 Pod 内部,Kubernetes 跟踪不同容器的状态 并确定使 Pod 重新
一.Pod生命周期
- Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少 其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以 失败状态结束而进入 Succeeded 或者 Failed 阶段。
- 在 Pod 运行期间,kubelet 能够重启容器以处理一些失效场景。 在 Pod 内部,Kubernetes 跟踪不同容器的状态 并确定使 Pod 重新变得健康所需要采取的动作。
- Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者 被终止
每个 Pod 中可以包含多个容器, 应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下两点:
- 它们总是运行到完成。
- 每个都必须在下一个启动之前成功完成。
如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod 对应的 restartPolicy 值为 “Never”,Kubernetes 不会重新启动 Pod。
容器状态
Kubernetes 会跟踪 Pod 中每个容器的状态,就像它跟踪 Pod 总体上的阶段一样。 你可以使用容器生命周期回调 来在容器生命周期中的特定时间点触发事件。
一旦调度器将 Pod 分派给某个节点,kubelet 就通过 容器运行时 开始为 Pod 创建容器。 容器的状态有三种:Waiting(等待)、Running(运行中)和 Terminated(已终止)。
要检查 Pod 中容器的状态,你可以使用 kubectl describe pod <pod 名称>。 其输出中包含 Pod 中每个容器的状态。
每种状态都有特定的含义:
Waiting (等待)
如果容器并不处在 Running 或 Terminated 状态之一,它就处在 Waiting 状态。 处于 Waiting 状态的容器仍在运行它完成启动所需要的操作:例如,从某个容器镜像 仓库拉取容器镜像,或者向容器应用 Secret 数据等等。 当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
Running(运行中)
Running 状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart 回调,那么该回调已经执行且已完成。 如果你使用 kubectl 来查询包含 Running 状态的容器的 Pod 时,你也会看到 关于容器进入 Running 状态的信息。
Terminated(已终止)
处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时,你会看到 容器进入此状态的原因、退出代码以及容器执行期间的起止时间。
如果容器配置了 preStop 回调,则该回调会在容器进入 Terminated 状态之前执行。
int容器
因为 Init 容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:
-
Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。 例如,没有必要仅为了在安装过程中使用类似 sed、awk、python 或 dig 这样的工具而去 FROM 一个镜像来生成一个新的镜像。
-
Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
-
应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
-
Init 容器能以不同于 Pod 内应用容器的文件系统视图运行。因此,Init 容器可以访问 应用容器不能访问的 Secret 的权限。
-
由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器 提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。 一旦前置条件满足,Pod 内的所有的应用容器会并行启动。
容器探针
Probe 是由 kubelet 对容器执行的定期诊断。 要执行诊断,kubelet 调用由容器实现的 Handler (处理程序)。有三种类型的处理程序:
-
ExecAction: 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
-
TCPSocketAction: 对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。
-
HTTPGetAction: 对容器的 IP 地址上指定端口和路径执行 HTTP Get 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
- Success(成功):容器通过了诊断。
- Failure(失败):容器未通过诊断。
- Unknown(未知):诊断失败,因此不会采取任何行动。
针对运行中的容器,kubelet 可以选择是否执行以下三种探针,以及如何针对探测结果作出反应:
-
livenessProbe:指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。
-
readinessProbe:指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。
-
startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。
[root@server2 ~]# vim live.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: 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:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
[root@server2 ~]# kubectl create -f live.yml
[root@server2 ~]# kubectl get pod


[root@server2 ~]# kubectl delete -f live.yml
[root@server2 ~]# vim live.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: myapp:v1
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 2
periodSeconds: 3
readinessProbe:
httpGet:
path: /hostname.html
port: 80
initialDelaySeconds: 3
periodSeconds: 3
[root@server2 ~]# kubectl create -f live.yml
[root@server2 ~]# kubectl get pod

如果port改为8080,会不断重启
[root@server2 ~]# kubectl delete -f live.yml
[root@server2 ~]# vim service.yml
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
[root@server2 ~]# kubectl create -f service.yml
[root@server2 ~]# kubectl get svc
[root@server2 ~]# kubectl describe svc myservice
[root@server2 ~]# kubectl get pod

[root@server2 ~]# vim init.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: myapp:v1
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
[root@server2 ~]# kubectl delete -f service.yml
[root@server2 ~]# kubectl create -f init.yml
[root@server2 ~]# kubectl get pod

[root@server2 ~]# kubectl create -f service.yml
[root@server2 ~]# kubectl get svc
[root@server2 ~]# kubectl get pod

[root@server2 ~]# kubectl delete -f init.yml
[root@server2 ~]# kubectl delete -f service.yml
正常情况下my-app会准备好
二.控制器
Pod的分类:
- 自主式Pod:Pod退出后不会被创建
- 控制器管理的Pod:在控制器的生命周期里,始终要维持Pod的副数目
控制器类型:
- ReplicationController和ReplicaSet
- Deployments
- DaemonSet
- StatefulSets
- Jobs
- CronJob
- HPA全称Horizontal Pod Autoscaler



ReplicaSet
[root@server2 ~]# vim rs.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: ReplicaSet-example
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
[root@server2 ~]# kubectl get rs
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl delete rs replicaset-example
Deployment
[root@server2 ~]# vim rs.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
[root@server2 ~]# kubectl apply -f rs.yml
[root@server2 ~]# kubectl get pod

[root@server2 ~]# kubectl get pod --show-labels

[root@server2 ~]# kubectl label pod deployment-6456d7c676-c9w9j app=myapp --overwrite
[root@server2 ~]# kubectl get pod --show-labels
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl get pod -L app

[root@server2 ~]# kubectl delete pod deployment-6456d7c676-c9w9j
[root@server2 ~]# kubectl get pod -L app
[root@server2 ~]# kubectl get rs

[root@server2 ~]# kubectl get svc
[root@server2 ~]# kubectl expose deployment deployment --port=80
[root@server2 ~]# kubectl get svc
[root@server2 ~]# kubectl describe svc deployment

[root@server2 ~]# kubectl label pod deployment-6456d7c676-67lxh app=myapp --overwrite
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl get pod -L app
[root@server2 ~]# kubectl describe svc deployment

[root@server2 ~]# kubectl edit svc deployment

[root@server2 ~]# kubectl describe svc deployment

[root@server2 ~]# kubectl delete -f rs.yml
[root@server2 ~]# kubectl delete svc deployment
[root@server2 ~]# kubectl get all

[root@server2 ~]# kubectl delete pod/deployment-6456d7c676-67lxh
[root@server2 ~]# kubectl get all

DaemonSet
[root@server2 ~]# vim daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-example
labels:
k8s-app: zabbix-agent
spec:
selector:
matchLabels:
name: zabbix-agent
template:
metadata:
labels:
name: zabbix-agent
spec:
containers:
- name: zabbix-agent
image: zabbix-agent
[root@server1 harbor]# docker pull zabbix/zabbix-agent
[root@server1 harbor]# docker tag zabbix/zabbix-agent:latest reg.westos.org/library/zabbix-agent:latest
[root@server1 harbor]# docker push reg.westos.org/library/zabbix-agent:latest

[root@server2 ~]# kubectl apply -f daemonset.yml
[root@server2 ~]# kubectl get pod

正常情况下此处两个容器都会运行
排错:镜像拉取错误,查看拉取的路径是否是本地仓库
每个节点都要满足
[root@server4 ~]# vim /etc/docker/daemon.json
"registry-mirrors": ["https://reg.westos.org"]
注意:要用逗号隔开下面的内容
[root@server4 ~]# systemctl daemon-reload
[root@server4 ~]# systemctl restart docker
重新生效后查看镜像拉取是否正常
[root@server2 ~]# kubectl delete -f daemonset.yml
Job
[root@server2 ~]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
[root@server1 harbor]# docker pull perl
[root@server1 harbor]# docker tag perl:latest reg.westos.org/library/perl:latest
[root@server1 harbor]# docker push reg.westos.org/library/perl:latest

[root@server2 ~]# kubectl create -f job.yml
[root@server2 ~]# kubectl get pod

正常状态会变为completed
[root@server2 ~]# kubectl delete -f job.yml
Cronjob
[root@server2 ~]# vim cronjob.yml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busyboxplus
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
[root@server2 ~]# kubectl create -f cronjob.yml
[root@server2 ~]# kubectl get all
[root@server2 ~]# kubectl get pod

正常状态应为completed
[root@server2 ~]# kubectl delete -f cronjob.yml
更多推荐
所有评论(0)