初步认识pod可以参考:https://blog.csdn.net/qq_35887546/article/details/105579274
Pod的status信息保存在PodStatus中定义,有一个phase字段
Pod的相位(phase)是Pod在其生命周期中的简单宏观概述,该阶段并不是对容器或Pod的总和汇总,也不是为了作为综合状态机。
Pod相位的数量和含义是严格指定的。除了文档中列举的状态外,不应该再假定Pod有其他phase值。
下面是phase可能的值:
Pod 有一个 PodStatus 对象,其中包含一个 PodCondition 数组。 PodCondition 数组的每个元素都有一个 type 字段和一个 status 字段。type 字段是字符串,可能的值有 PodScheduled、Ready、Initialized 和 Unschedulable。status 字段是一个字符串,可能的值有 True、False 和 Unknown。
Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下三点:
如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。
Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
由于 Init 容器必须在应用容器启动之前运行完成,因此 Init
容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
使用k8s之前确定环境ok:
[root@server1 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7ff77c879f-8gzr5 1/1 Running 5 2d2h
coredns-7ff77c879f-dxst6 0/1 Running 4 2d2h
etcd-server1 1/1 Running 5 2d2h
kube-apiserver-server1 1/1 Running 5 2d2h
kube-controller-manager-server1 1/1 Running 29 2d2h
kube-flannel-ds-amd64-qwk6c 1/1 Running 10 2d1h
kube-flannel-ds-amd64-tkzrg 1/1 Running 7 2d1h
kube-flannel-ds-amd64-wcqrh 1/1 Running 4 2d1h
kube-proxy-dm476 1/1 Running 3 2d1h
kube-proxy-fs7rm 1/1 Running 3 2d1h
kube-proxy-lzdn8 1/1 Running 4 2d2h
kube-scheduler-server1 1/1 Running 25 2d2h
[root@server1 ~]# kubectl get pod
No resources found in default namespace.
没有问题,
[root@server1 manifest]# vim init.yaml
[root@server1 manifest]# cat init.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: myapp:v1
initContainers:
- name: init-container
image: busybox
command: ["/bin/sh", "-c", "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
其中init容器种执行的命令是用来检测default 命名空间的解析,这个解析需要一个service,即init容器在运行时会检测service,若果service没有运行的话就会一直处于初始化状态。
我们先来运行一下这个pod:
[root@server1 manifest]# kubectl create -f init.yaml
pod/myapp-pod created
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/1 0 83s
可以看出pod一直处于初始化状态。
现在进入容器内部查看解析:
[root@server1 manifest]# kubectl exec -it myapp-pod -c init-container -- sh
/ # nslookup myservice.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10:53
** server can't find myservice.default.svc.cluster.local: NXDOMAIN
^C
/ #
可以看出果然没有解析。
接下来我们创建一个service:
[root@server1 manifest]# vim service.yaml
[root@server1 manifest]# cat service.yaml
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
[root@server1 manifest]# kubectl create -f service.yaml
service/myservice created
[root@server1 manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d4h
myservice ClusterIP 10.109.148.189 <none> 80/TCP 9s
创建service成功,之后再查看pod状态:
[root@server1 manifest]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-pod 1/1 Running 0 53s 10.244.2.18 server3 <none> <none>
可以看出已经处于运行状态,同样我们可以访问它:
[root@server1 manifest]# curl 10.244.2.18
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
之后再进入容器查看解析:
[root@server1 manifest]# kubectl run test -it --image=radial/busyboxplus
If you don't see a command prompt, try pressing enter.
/ # nslookup myservice.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: myservice.default.svc.cluster.local
Address 1: 10.109.148.189 myservice.default.svc.cluster.local
/ #
果然解析成功。
因此可以验证如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。
实验完成后删除:
[root@server1 manifest]# kubectl delete pod test
[root@server1 manifest]# kubectl delete pod myapp-pod
[root@server1 manifest]# kubectl delete svc myservice
容器探针用来检测主容器的运行状态。
在pod生命周期中可以做的一些事情。主容器启动前可以完成初始化容器,初始化容器可以有多个,他们是串行执行的,执行完成后就退出了,在主程序刚刚启动的时候可以指定一个post start 主程序启动开始后执行一些操作,在主程序结束前可以指定一个 pre stop 表示主程序结束前执行的一些操作。在程序启动后可以做两类常用检测 liveness probe(存活性探测) 和 readness probe(就绪性探测)
探针是由 kubelet 对容器执⾏的定期诊断。 要执⾏诊断, kubelet 调⽤由容器实现的 Handler。 有三种类型的探测方式:
每次探测都将获得以下三种结果之一:
Kubelet 可以选择是否执行在容器上运行的两种探针执行和做出反应:
PodSpec 中有一个 restartPolicy 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always。
一般Pod 不会消失,直到人为销毁他们,这可能是一个人或控制器。
建议创建适当的控制器来创建 Pod,而不是直接自己创建 Pod。因为单独的 Pod 在机器故障的情况下没有办法自动复原,而控制器却可以。
三种可用的控制器:
使用 Job 运行预期会终止的 Pod,例如批量计算。Job 仅适用于重启策略为 OnFailure 或 Never 的 Pod。
对预期不会终止的 Pod 使用 ReplicationController、ReplicaSet 和 Deployment ,例如 Web 服务器。 ReplicationController 仅适用于具有 restartPolicy 为 Always 的 Pod。
提供特定于机器的系统服务,使用 DaemonSet 为每台机器运行一个 Pod 。
下文我们会详细介绍pod的控制器。
编辑以下yaml文件:
[root@server1 manifest]# vim liveness.yaml
[root@server1 manifest]# cat liveness.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
以上使用tcpsock检测容器8080端口,若liveness探针没有检测到8080端口则判定为不存活。由于我们运行的容器只暴露出来80端口,因此会检测失败。其中:
initialDelaySeconds: 1表示pod运行1s后检测状态。
periodSeconds: 3表示每3s检测一次。
timeoutSeconds: 1表示检测1s后即超时进行下次检测
之后运行并查看状态:
[root@server1 manifest]# kubectl create -f liveness.yaml
pod/liveness-http created
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 0 10s
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 0/1 CrashLoopBackOff 2 51s
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 3 54s
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 3 56s
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 3 61s
可以看出检测失败一直在重启。
接下来我们将检测端口改为80端口再运行:
[root@server1 manifest]# kubectl delete -f liveness.yaml
[root@server1 manifest]# vim liveness.yaml
[root@server1 manifest]# cat liveness.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
[root@server1 manifest]# kubectl create -f liveness.yaml
pod/liveness-http created
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 0 23s
可以看出启动成功,在运行状态。
实验后删除:
[root@server1 manifest]# kubectl delete -f liveness.yaml
编辑测试文件:
[root@server1 manifest]# vim reainess.yaml
[root@server1 manifest]# cat reainess.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-http
spec:
containers:
- name: readiness
image: nginx
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
以上使用httpGet的方式使用readinessProbe进行探测,表示在容器运行后检测test.html发布文件内容,若返回200到400之间的状态码则检测通过为READY状态,其他为不通过。
运行pod,并查看状态:
[root@server1 manifest]# kubectl create -f reainess.yaml
pod/readiness-http created
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
readiness-http 0/1 Running 0 51s
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
readiness-http 0/1 Running 0 60s
可以看出是运行状态但是并不是READY状态,可以看出检测没有通过。
[root@server1 manifest]# kubectl describe pod readiness-http
[root@server1 manifest]# kubectl logs readiness-http
[root@server1 manifest]# kubectl exec -it readiness-http -- sh
# echo redhat > /usr/share/nginx/html/test.html
#
查看pod状态:
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
readiness-http 1/1 Running 0 2m37s
可以看出已经是READY状态了。
可以看出就绪探针的作用了,即指示容器是否准备好服务请求。
实验后删除:
[root@server1 manifest]# kubectl delete -f reainess.yaml
接下来我们将两种探针融合使用:
[root@server1 manifest]# vim reainess+liveness.yaml
[root@server1 manifest]# cat reainess+liveness.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
由于有80端口,因此存活探针检测通过,但是没有test.html页面,因此就绪探针不会通过:
[root@server1 manifest]# kubectl create -f reainess+liveness.yaml
pod/liveness-http created
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 0/1 Running 0 17s
可以看出并不是READY状态,接下来我们将就绪检测的条件改为index.html:
[root@server1 manifest]# vim reainess+liveness.yaml
[root@server1 manifest]# cat reainess+liveness.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
由于容器内部有index.html文件和80端口,因此就绪检测和存活检测都会通过:
[root@server1 manifest]# kubectl create -f reainess+liveness.yaml
pod/liveness-http created
[root@server1 manifest]# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 0 16s
状态为Runing以及READY。