Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
inte容器-初始化容器
Init 容器与普通的容器非常像,除了如下两点:
-
它们总是运行到完成。
-
Init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行成功,下一个才能够运行。
-
如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。
Init 容器能做什么?
- Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
- Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
- 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
- Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
- 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
如下:建立init.yaml文件,注释掉下边服务,当init容器所监控的service未被配置时,主容器与init容器均无法正常启动
[root@server1 pod]# cat 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
如图所示:pod无法进入running状态,一直无法启动:
取消init.yaml中的注释,再次运行,发现init初始化成功,
探针
探针 是由 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存活探针
探针检测容器端口,设置检索的端口为8080(未开启),不符合条件时,会一直重启
[root@server1 pod]cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-example
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
由于8080端口未开放,一直重启:
端口改为80,检测到80端口开启,不会重启
- kubectl get pod
2.readinessProbe就绪探针
就绪探针是jiance能否获得发布文件,若获得内容,可正常运行,无法获得时,无法启动容器。
apiVersion: v1
kind: Pod
metadata:
name: pod-example
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
livenessProbe:
tcpSocket:
port: 80
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
没有获得/test.html文件内容
- kubectl get pod 查看
发现无法启动,因为没有文件
添加所需文件
- kubectl exec pod-example sh -i -t
[root@server1 pod]# kubectl exec pod-example sh -i -t
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo hello > /usr/share/nginx/html/test.html
/ # exit
- kubectl get pod pod-example -o wide
- curl 10.244.179.78/test.html
查看发现文件添加成功:
- kubectl get pod
成功READY状态: