健康检查
健康检查(Health Check)是让系统知道您的应用实例是否正常工作的简单方法。 如果您的应用实例不再工作,则其他服务不应访问该应用或向其发送请求。 相反,应该将请求发送到已准备好的应用程序实例,或稍后重试。 系统还应该能够使您的应用程序恢复健康状态。
强大的自愈能力是 Kubernetes 这类容器编排引擎的一个重要特性。自愈的默认实现方式是自动重启发生故障的容器。除此之外,用户还可以利用Liveness 和 Readiness 探测机制设置更精细的健康检查,进而实现如下需求:
- 零停机部署。
- 避免部署无效的镜像。
- 更加安全的滚动升级。
探针类型
Liveness存活性探针
Liveness探针让Kubernetes知道你的应用程序是活着还是死了。 如果你的应用程序还活着,那么Kubernetes就不管它了。 如果你的应用程序已经死了,Kubernetes将删除Pod并启动一个新的替换它。
Readiness就绪性探针
Readiness探针旨在让Kubernetes知道您的应用何时准备好其流量服务。 Kubernetes确保Readiness探针检测通过,然后允许服务将流量发送到Pod。 如果Readiness探针开始失败,Kubernetes将停止向该容器发送流量,直到它通过。 判断容器是否处于可用Ready状态,达到ready状态表示pod可以接受请求, 如果不健康,从service的后端endpoint列表中把pod隔离出去
探针执行方式
HTTP
HTTP探针可能是最常见的自定义Liveness探针类型。 即使您的应用程序不是HTTP服务,您也可以在应用程序内创建轻量级HTTP服务以响应Liveness探针。 Kubernetes去ping一个路径,如果它得到的是200或300范围内的HTTP响应,它会将应用程序标记为健康。 否则它被标记为不健康。
httpget配置项
host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置"Host"而不是使用IP。
scheme:连接使用的schema,默认HTTP。
path: 访问的HTTP server的path。
httpHeaders:自定义请求的header。HTTP运行重复的header。
port:访问的容器的端口名字或者端口号。端口号必须介于1和65535之间。
Exec
对于Exec探针,Kubernetes则只是在容器内运行命令。 如果命令以退出代码0返回,则容器标记为健康。 否则,它被标记为不健康。 当您不能或不想运行HTTP服务时,此类型的探针则很有用,但是必须是运行可以检查您的应用程序是否健康的命令。
TCP
最后一种类型的探针是TCP探针,Kubernetes尝试在指定端口上建立TCP连接。 如果它可以建立连接,则容器被认为是健康的;否则被认为是不健康的。
如果您有HTTP探针或Command探针不能正常工作的情况,TCP探测器会派上用场。 例如,gRPC或FTP服务是此类探测的主要候选者。
InitContainer介绍
initContainers是一种专用的容器,在应用程序容器启动之前运行,可以包括一些应用程序镜像中不存在的实用工具和安装脚本,可以完成应用的必要数据初始化等工作。总的来说就是在正式的容器启动之前做一些准备工作的。
InitContainer用途
1、Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码;
2、Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低;
3、Init容器可以以root身份运行,执行一些高权限命令;
4、Init容器相关操作执行完成以后即退出,不会给业务容器带来安全隐患。
初始化容器和PostStart区别
PostStart:依赖主应用的环境,而且并不一定先于Command运行。
InitContainer:不依赖主应用的环境,可以有更高的权限和更多的工具,一定会在主应用启动之前完成。
初始化容器和普通容器的区别
1、它们总是运行到完成;
2、上一个运行完成才会运行下一个;
3、如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止,但是Pod 对应的 restartPolicy 值为 Never,Kubernetes 不会重新启动 Pod。
4、Init 容器不支持 lifecycle、livenessProbe、readinessProbe 和 startupProbe。
K8s资源定义haproxy
先简单的做出两个运行httpd程序的pod,其中默认的index.html文件不一样
[root@master ~]# vim Dockerfile
FROM busybox
RUN mkdir /data && echo 'hello,this is a test page 1 > /data/index.html
CMD ["/bin/httpd","-f","-h","/data"]
[root@master ~]# docker build -t bravealove1/apache:v1.0
Successfully built 8adfcb109338
Successfully tagged bravealove1/apache:v1.0
[root@master ~]# vim Dockerfile
FROM busybox
RUN mkdir /data && echo 'hello,this is a test page 2' > /data/index.html
CMD ["/bin/httpd","-f","-h","/data"]
[root@master ~]# docker build -t bravealove1/apache:v2.0 .
Successfully built 9a5188dcf431
Successfully tagged bravealove1/apache:v2.0
用这两个镜像做出两个pod并做出两个service
[root@master ~]# vim web.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rs1
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: rs1
template:
metadata:
labels:
app: rs1
spec:
containers:
- image: bravealove1/apache:v1.0
imagePullPolicy: IfNotPresent
name: rs1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rs2
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: rs2
template:
metadata:
labels:
app: rs2
spec:
containers:
- image: bravealove1/apache:v2.0
imagePullPolicy: IfNotPresent
name: rs2
---
apiVersion: v1
kind: Service
metadata:
name: rs1
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: rs1
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: rs2
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: rs2
type: NodePort
[root@master ~]# kubectl apply -f web.yaml
deployment.apps/rs1 created
deployment.apps/rs2 created
service/rs1 created
service/rs2 created
查看创建的deployment以及service
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/rs1-6f8b6577bd-f8t6g 1/1 Running 0 1m
pod/rs2-5cff4c7479-kz5wb 1/1 Running 0 1m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4m
service/rs1 NodePort 10.105.76.129 <none> 80:31396/TCP 1m
service/rs2 NodePort 10.102.247.86 <none> 80:31368/TCP 1m
编写写资源清单定义haproxy
[root@master ~]# vim haproxy.yaml
---
apiVersion: apps/v1
kind: Pod
metadata:
name: haproxy
namespace: default
labels:
app: haproxy
spec:
restartPolicy: OnFailure
initContainers:
- name: cfgfile
volumeMounts:
- name: haproxyconfigfile
mountPath: /tmp
containers:
- image: bravealove1/haproxy:latest
imagePullPolicy: IfNotPresent
name: haproxy
env:
- name: RSIP
value: "rs1 rs2 "
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: haproxy
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: haproxy
type: NodePort
[root@master ~]# kubectl apply -f haproxy.yml
deployment.apps/haproxy created
service/haproxy created
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/haproxy-56948856b7-hhcbp 1/1 Running 0 15m
pod/rs1-6f8b6577bd-f8t6g 1/1 Running 0 5m
pod/rs2-5cff4c7479-kz5wb 1/1 Running 0 5m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/haproxy NodePort 10.96.98.56 <none> 80:32623/TCP 15s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8m
service/rs1 NodePort 10.105.76.129 <none> 80:31396/TCP 5m
service/rs2 NodePort 10.102.247.86 <none> 80:31368/TCP 5m
测试
[root@master ~]# curl 10.105.76.129
hello,this is a test page 1
[root@master ~]# curl 10.102.247.86
hello,this is a test page 2
[root@master ~]# curl 10.96.98.56
hello,this is a test page 2
[root@master ~]# curl 10.96.98.56
hello,this is a test page 1
|