目录
一、Pod生命周期
- 和一个个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体。 Pod 会被创建、赋予一个唯一的 ID(UID),并被调度到节点,并在终止(根据重启策略)或删除之前一直运行在该节点。
- 如果一个节点死掉了,调度到该节点 的 Pod 也被计划在给定超时期限结束后删除。
- Pod 自身不具有自愈能力。如果 Pod 被调度到某节点 而该节点之后失效,或者调度操作本身失效,Pod 会被删除;与此类似,Pod 无法在节点资源 耗尽或者节点维护期间继续存活。Kubernetes 使用一种高级抽象,称作 控制器,来管理这些相对而言 可随时丢弃的 Pod 实例。
- 任何给定的 Pod (由 UID 定义)从不会被“重新调度(rescheduled)”到不同的节点; 相反,这一 Pod 可以被一个新的、几乎完全相同的 Pod 替换掉。 如果需要,新 Pod 的名字可以不变,但是其 UID 会不同。
- 如果某物声称其生命期与某 Pod 相同,例如存储卷, 这就意味着该对象在此 Pod (UID 亦相同)存在期间也一直存在。 如果 Pod 因为任何原因被删除,甚至某完全相同的替代 Pod 被创建时, 这个相关的对象(例如这里的卷)也会被删除并重建。和一个个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体。 Pod 会被创建、赋予一个唯一的 ID(UID),并被调度到节点,并在终止(根据重启策略)或删除之前一直运行在该节点。
- 如果一个节点死掉了,调度到该节点 的 Pod 也被计划在给定超时期限结束后删除。
- Pod 自身不具有自愈能力。如果 Pod 被调度到某节点 而该节点之后失效,或者调度操作本身失效,Pod 会被删除;与此类似,Pod 无法在节点资源 耗尽或者节点维护期间继续存活。Kubernetes 使用一种高级抽象,称作 控制器,来管理这些相对而言 可随时丢弃的 Pod 实例。
- 任何给定的 Pod (由 UID 定义)从不会被“重新调度(rescheduled)”到不同的节点; 相反,这一 Pod 可以被一个新的、几乎完全相同的 Pod 替换掉。 如果需要,新 Pod 的名字可以不变,但是其 UID 会不同。
- 如果某物声称其生命期与某 Pod 相同,例如存储卷, 这就意味着该对象在此 Pod (UID 亦相同)存在期间也一直存在。 如果 Pod 因为任何原因被删除,甚至某完全相同的替代 Pod 被创建时, 这个相关的对象(例如这里的卷)也会被删除并重建。
一般将pod对象从创建至结束的这段时间范围成为pod的生命周期
,它主要包含下面的过程:
pod创建过程
运行初始化容器(init container)过程(可多可少,可有可无)
运行主容器(main container)过程
pod终止过程
- pod 可以包含多个容器,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。Init 容器和普通容器区别不大,主要是init优先运行,init成功运行完成后,才会启动主容器,所以Init 容器不支持 Readiness。如果 Pod 的 Init 容器启动失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。
- Init 容器的优势:
1、想用某些工具,又不想放在主容器中,就把这些工具放在初始镜像init使用,运行完,初始镜像结束,再用主容器
2、Init 容器可以安全地运行这些工具,减少风险
3、应用镜像的创建者和部署者可以各自独立工作
二、init初始化
将service1和service2注释,模拟初始化失败
vim init.yaml
///
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busyboxplus
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busyboxplus
command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busyboxplus
command: ['sh', '-c', "until nslookup mydb.default.svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
#---
#apiVersion: v1
#kind: Service
#metadata:
# name: myservice
#spec:
# ports:
# - protocol: TCP
# port: 80
# targetPort: 9376
#---
#apiVersion: v1
#kind: Service
#metadata:
# name: mydb
#spec:
# ports:
# - protocol: TCP
# port: 80
# targetPort: 9377
\\\
kubectl apply -f init.yaml
kubectl get pod
可以看到初始化无法完成,那么主容器也就无法运行
再次修改init.yaml文件,添加init要满足的服务
vim init.yaml
///
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busyboxplus
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busyboxplus
command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busyboxplus
command: ['sh', '-c', "until nslookup mydb.default.svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
///
kubectl apply -f init.yaml
kubectl get pod
三、探针
1、存活探针livenessProbe
-
表示容器是否正在运行(running)
-
如果没有探针,k8s无法知道应用是否还活着,只要进程还在运行,k8s则认为容器是健康的。
注意:当存活和就绪探针同时存在,但只有存活探针通过时,容器会运行,但只能内部运行,无法对外访问。只有两个探针都运行成功,才可以对外访问。 -
http get
对容器的ip地址(指定的端口和路径)执行http get请求
如果探测器收到响应,并且响应码是2xx, 3xx,则认为探测成功。如果服务器没有响应或者返回错误响应则说明探测失败,容器将重启。 -
tcp socket
探针与容器指定端口建立tcp连接,如果连接建立则探测成功,否则探测失败容器重启。 -
exec
在容器内执行任意命令,并检查命令退出状态码,如果状态码为0,则探测成功,否则探测失败容器重启。
编辑pod2.yaml ,加入存活探针
vim pod2.yaml
\\\
apiVersion: v1
kind: Pod
metadata:
name: pod-example
labels:
app: myapp
spec:
#hostNetwork: true
#nodeName: server4
#imagePullSecrets:
containers:
- name: myapp
image: myapp:v1
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "200m"
memory: "100Mi"
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
///
kubectl apply -f pod2.yaml
因为是80端口在正常情况下,所以容器能够正常启动:
2、就绪探针readinessProbe
表示容器是否准备好服务请求(ready)
就绪探针就绪后,才能用这个后端,否则svc不会暴露端口
编辑pod.yaml 文件,添加就绪探针
vim pod2.yaml
\\\
后面加上:
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
\\\
kubectl delete -f pod2.yaml
kubectl apply -f pod2.yaml
因为test.html这个文件没有,所以容器无法就绪。
进入pod-example,添加test.html这个文件,就可以ready了
测试,访问添加的发布信息:
四、k8s集群之控制器
- 自主式 Pod,当Pod 退出后不会被创建。如果加入了控制器,控制器管理的 Pod,在控制器的生命周期里,始终要维持 Pod 的副本数目,删除一个副本,控制器就会自动补一个副本
1、ReplicaSet(rs)控制器
- ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创建、删除和更新的机制。
vim rs.yaml
///
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: nginx
\\\
kubectl apply -f rs.yaml
拉起pod,可以看到有6个副本:
在这里可以更改副本数量:
查看更改标签:
kubectl get pod --show-labels #查看pod的标签
kubectl label pod replicaset-example-2g2jr app=myapp --overwrite #覆盖replicaset-example-9b9gz这个pod的标签为app=myapp
2、Deployment控制器
- Deployment 为 Pod 和 ReplicaSet 提供了一个申明式的定义方法
- deployment可以更新,原理是和rs合作,一个版本一个rs,五个版本就是五个rs,每个rs分别管理自己的副本数量
vim deployment.yaml
\\\
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
///
kubectl apply -f deployment.yaml
可以看到是nginx:
镜像变为myapp:
看到,更新为mypp:
3、DaemonSet控制器
- DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod 。当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。一个典型用法是在每个节点上运行监控 DaemonSet,例如 zabbix agent等。保证每个节点做一次
- DaemonSet确保全部(或者某些)节点上运行一个Pod副本。当有新节点加入集群时,也会为它们新增一个Pod。当节点从集群中移除时,这些Pod也会被回收,删除DaemonSet将会删除它创建的所有Pod
- 使用DaemonSet的一些典型用法:
运行集群存储daemon(守护进程),例如在每个节点上运行Glusterd、Ceph等
在每个节点运行日志收集daemon,例如Fluentd、Logstash
在每个节点运行监控daemon,比如Prometheus Node Exporter、Collectd、Datadog代理、New Relic代理或 Ganglia gmond
vim daemonset.yaml
\\\
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/zabbix-agent
///
4、StatefulSet 控制器
StatefulSet 是用来管理有状态应用的工作负载 API 对象。实例之间有不对等关系,以及实例对外部数据有依赖关系的应用,称为“有状态应用”。
主要用于长期的、持续的监测状态,需要唯一的网络标识符的集群。
5、Job控制器
执行批处理任务,仅执行一次任务,执行成功就结束。比如可以计算pi值。
vim job.yaml
\\\
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
///
kubectl get pod
6、CronJob控制器
vim cronjob.yaml
\\\
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-example
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cronjob
image: busyboxplus
args:
- /bin/sh
- -c
- date; echo Hello from k8s cluster
restartPolicy: OnFailure
///
7、HPA控制器
全称是Horizontal Pod Autoscaler,根据资源利用率自动调整service中Pod数量,实现Pod水平动态拉伸