一、pod生命周期
- Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或
多个先于应用容器启动的 Init 容器。 - Init容器与普通的容器非常像,除了如下两点:
- 它们总是运行到完成。
- Init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成。
每个 Init 容器必须运行成功,下一个才能够运行。
- 如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容
器成功为止。然而,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新
启动。
Init容器可以做什么?
• Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化
代码。
• Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性
降低。
• 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个
单独的应用镜像。
• Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器
可具有访问 Secrets 的权限,而应用容器不能够访问。
• 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一
种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前
置条件满足,Pod内的所有的应用容器会并行启动。
实例
创建init.yml文件,将init.yaml中的配置应用到pod
vim init.yml
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"]
kubectl apply -f init.yaml
显示正在运行的pod
加入服务
vim init.yml
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
将init.yaml中的配置应用到pod,显示,初始化完成
kubectl apply -f init.yaml
kubectl get pod
将pod删除
二、探针
简介:
探针 是由 kubelet 对容器执行的定期诊断:
• ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认
为诊断成功。
• TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果
端口打开,则诊断被认为是成功的。
• HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP
Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是
成功的。
每次探测都将获得以下三种结果之一:
• 成功:容器通过了诊断。
• 失败:容器未通过诊断。
• 未知:诊断失败,因此不会采取任何行动。
Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应:
• livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet
会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探
针,则默认状态为 Success。
• readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端
点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。
初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默
认状态为 Success。
• startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探测
(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测
失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有
提供启动探测,则默认状态为成功Success。
重启策略
• PodSpec 中有一个 restartPolicy 字段,可能的值为 Always、OnFailure 和
Never。默认为 Always。
Pod 的生命
• 一般Pod 不会消失,直到人为销毁他们,这可能是一个人或控制器。
• 建议创建适当的控制器来创建 Pod,而不是直接自己创建 Pod。因为单独的
Pod 在机器故障的情况下没有办法自动复原,而控制器却可以。
• 三种可用的控制器:
• 使用 Job 运行预期会终止的 Pod,例如批量计算。Job 仅适用于重启策略
为 OnFailure 或 Never 的 Pod。
• 对预期不会终止的 Pod 使用 ReplicationController、ReplicaSet 和
Deployment ,例如 Web 服务器。 ReplicationController 仅适用于具
有 restartPolicy 为 Always 的 Pod。
• 提供特定于机器的系统服务,使用 DaemonSet 为每台机器运行一个 Pod 。
实例1:livenessProbe存活探针
建立pod,yaml(pod.yml也可)文档
apiVersion: v1
kind: Pod
metadata:
name: pod-example
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"
ports:
- containerPort: 80
hostPort: 80
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
先设置检索的端口LivenessProbe Port为8080
运行并查看pod
kubectl apply -f pod.yaml
kubectl get pod -w
因为端口开启的是80,检测不到8080端口开启,所以会一直重启pod,删除容器,修改配置端口为80
重新运行pod,yaml,显示为running
实例2:readinessProbe就绪态探针的示例(配合svc)
apiVersion: v1
kind: Pod
metadata:
name: pod-example
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"
ports:
- containerPort: 80
hostPort: 80
# - name: busybox
# image: busybox:latest
# imagePullPolicy: IfNotPresent
# tty: true
# stdin: true
livenessProbe:
tcpSocket:
port: 80
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
运行pod.yaml文件并查看,status不处于ready态
此时我们在资源清单pod.yaml里面加入标签
重新将init.yaml中的配置应用到pod
创建一个svc.yaml资源清单,服务选择的标签为上面pod-example的标签
vim svc.yaml
apiVersion: v1
kind: Service
metadata:
name: mysvc
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: myapp
重新将svc.yaml中的配置应用到service
描述(describe)服务
kubectl describe svc mysvc
进入容器,创建test.html 满足上面就绪态探针
kubectl exec pod-example -i -t -- sh
ctrl+d返回,可以看到pod-example已经ready
mysvc的endpoints也有了pod-example的ip
访问curl 10.107.27.32/test.html
三、控制器
Pod 的分类:
• 自主式 Pod:Pod 退出后不会被创建
• 控制器管理的 Pod:在控制器的生命周期里,始终要维持 Pod 的副本数目
控制器类型:
• Replication Controller和ReplicaSet
• Deployment
• DaemonSet
• StatefulSet
• Job
• CronJob
• HPA全称Horizontal Pod Autoscaler
Replication Controller和ReplicaSet
• ReplicaSet 是下一代的 Replication Controller,官方推荐使用ReplicaSet。
• ReplicaSet 和 Replication Controller 的唯一区别是选择器的支持,ReplicaSet
支持新的基于集合的选择器需求。
• ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。
• 虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创
建、删除和更新的机制。
Deployment
• Deployment 为 Pod 和 ReplicaSet 提供了一个申明式的定义方法。
• 典型的应用场景:
- 用来创建Pod和ReplicaSet
- 滚动更新和回滚
- 扩容和缩容
- 暂停与恢复
DaemonSet
• DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节
点加入集群时, 也会为他们新增一个 Pod 。当有节点从集群移除时,这些
Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
• DaemonSet 的典型用法:
• 在每个节点上运行集群存储 DaemonSet,例如 glusterd、ceph。
• 在每个节点上运行日志收集 DaemonSet,例如 fluentd、logstash。
• 在每个节点上运行监控 DaemonSet,例如 Prometheus Node
Exporter、zabbix agent等
• 一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种
类型的 daemon 使用。
• 一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,
但具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。
实例1:ReplicaSet
ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。
vim rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-example
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
运行rs.yaml,查看展示标签
更改其中一个容器的标签
kubectl label pod replicaset-example-w7qnj app=nginx --overwrite
删除一个带app=myapp和带有app=nginx的pod,可以看到删除,但是app=nginx的容器没有被创建
指定副本数量,从3变更为6
重新应用配置到pod,可以看到多生成了三个副本
如果将版本从v1改成v2
关闭后重新应用配置到pod,,查询到副本ip,可以看出ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行,而不会更新你的版本
实例2:Deployment示例
vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
运行并查看,可以看出,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能.
修改版本myapp:v2,关闭后重新应用配置到pod,查询到副本ip
实例3:DaemonSet
DaemonSet 的一些典型用法
在每个节点上运行集群守护进程
在每个节点上运行日志收集守护进程
在每个节点上运行监控守护进程
建立DaemonSet
vim daemonset-example.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-example
labels:
k8s-app: nginx
spec:
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
运行并查看
实例3:Jobs
Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。
创建job.yaml文件,运行来检查 Job
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 apply -f job.yaml
kubectl describe jobs/pi