本文最初由Atul Jadhav在Msys Technology博客上发表
https://www.msystechnologies.com/blog/decoding-the-self-healing-kubernetes-step-by-step-2/
序言
如果业务应用程序不能全天候运行,那么在市场上就会被认为是低效的。其理念是,应用程序不受技术故障、功能更新或自然灾害的影响,不间断地运行。在当今的异构环境中,基础设施是复杂分层的,通过自修复可以实现应用程序的连续工作流。
Kubernetes是一种容器编排工具,它通过对机器进行物理抽象来促进应用程序的平稳运行。此外,Kubernetes的pod和容器可以自愈。
美国队长要求《复仇者联盟》中的Bruce Wanners愤怒地变成“绿巨人”。中的Bruce回答说:“这是我的秘密船长。我总是愤怒。”
你一定理解这里的类比。让我们简化一下——当系统受到影响时,Kubernetes将会自动地自愈。
Kubernetes的自修复特性,确保集群始终以最佳状态运行。Kubernetes可以自我检测两种类型的对象——podstatus和containerstatus。Kubernetes的编排功能,可以根据所需的配置监视和替换不健康的容器。同样,Kubernetes可以修复pod, pod是包含单个或多个容器的最小单元。
这三个容器状态包括
1. Waiting(等待)——创建但不运行。处于等待阶段的容器,仍然会运行一些操作,比如获取镜像或应用秘密等。要检查等待的pod状态,请使用下面的命令。
kubectl describe pod [POD_NAME]
与此状态一起显示的,还有关于此状态的消息和原因,以提供更多信息。
...
State: Waiting
Reason: ErrImagePull
...
2. Running(运行的)——正在运行的容器没有问题。在pod进入运行状态之前执行以下命令。
postStart
运行的pod将显示容器进入的时间。
...
State: Running
Started: Wed, 30 Jan 2019 16:46:38 +0530
...
3. Terminated(终止)——容器,失败或完成其执行,到达终止状态。在将pod移动到Terminated之前执行以下命令。
prestop
终止的pod将显示容器入口的时间。
…
State: Terminated
Reason: Completed
Exit Code: 0
Started: Wed, 30 Jan 2019 11:45:26 +0530
Finished: Wed, 30 Jan 2019 11:45:26 +0530
…
Kubernetes的自我修复概念——pod的阶段、探测和重启策略
在Kubernetes中的pod阶段提供了对pod位置的洞察。我们可以有
Kubernetes对pod执行了liveliness和readiness探测,以检查它们是否按照期望的状态工作。liveliness探测器将检查容器的运行状态。如果一个容器探测失败,Kubernetes将终止它,并根据重启策略创建一个新的容器。readiness探测器将检查容器的服务请求服务功能。如果容器探测失败,Kubernetes将删除相关pod的IP地址。
Liveliness探测例子。
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- args:
- /server
image: k8s.gcr.io/liveness
livenessProbe:
httpGet:
# when "host" is not defined, "PodIP" will be used
# host: my-host
# when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed
# scheme: HTTPS
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 15
timeoutSeconds: 1
name: liveness
探测包括
每个探测给出三个结果之一:
自我愈合的Kubernetes的演示描述-例1
我们需要设置代码复制来触发Kubernetes的自修复功能。
让我们看一个Nginx文件的例子。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-sample
spec:
selector:
matchLabels:
app: nginx
replicas:4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
在上面的代码中,我们看到集群中的pod总数必须是4。
现在部署文件。
kubectl apply nginx-deployment-sample
让我们列出pod
kubectl get pods -l app=nginx
这是输出。
正如你在上面看到的,我们已经创建了4个pod。
让我们删除一个pod。
kubectl delete nginx-deployment-test-83586599-r299i
现在删除了pod。我们得到以下输出
pod "deployment nginx-deployment-test-83586599-r299i" deleted
再一次,列出这些pod。
kubectl get pods -l app=nginx
我们得到以下输出。
我们又有4个pod,尽管删除了一个。
Kubernetes已自愈,以创建一个新节点,并将数量维持到4。
自我愈合的Kubernetes的演示描述-例2
得到pod细节
$ kubectl get pods -o wide
获得第一个nginx pod,并删除它——其中一个nginx pod应该处于“终止”状态
$ NGINX_POD=$(kubectl get pods -l app=nginx --output=jsonpath="{.items[0].metadata.name}")
$ kubectl delete pod $NGINX_POD; kubectl get pods -l app=nginx -o wide
$ sleep 10
获得pod的细节——一个nginx pod应该是刚开始的
$ kubectl get pods -l app=nginx -o wide
获取部署细节,并检查最近更改的事件
$ kubectl describe deployment nginx-deployment
停止其中一个节点(node2)
$ vagrant halt node2
$ sleep 30
获取节点详细信息——node2 Status=NotReady
$ kubectl get nodes
获得pod的细节——一切看起来很好——你需要等待5分钟
$ kubectl get pods -o wide
pod不会被驱逐,直到等了5分钟——(参阅‘describe pod’中的Tolerations)。它可以防止Kubernetes在不需要时启动新的容器
$ NGINX_POD=$(kubectl get pods -l app=nginx --output=jsonpath="{.items[0].metadata.name}")
$ kubectl describe pod $NGINX_POD | grep -A1 Tolerations
睡5分钟
$ sleep 300
获取pods详细信息——Status=Unknown/NodeLost,并且启动了新的容器
$ kubectl get pods -o wide
获得就业详情——再次看到,AVAILABLE=3/3
$ kubectl get deployments -o wide
启动node2节点
$ vagrant up node2
$ sleep 70
获取节点详细信息——node2应该再次准备好
$ kubectl get nodes
获得pod详情——“Unknown”pod被移除
$ kubectl get pods -o wide
**来源:GitHub作者:Petr Ruzicka
https://github.com/ruzickap/multinode_kubernetes_cluster/blob/master/docs/source/14-k8s-selfhealing.rst
总结
Kubernetes可以自愈应用程序和容器,但是当节点有问题时,如何自愈呢?为了让Kubernetes继续自我修复,它需要一组专用的基础设施,可以随时访问自修复节点。基础设施必须由自动化驱动,并由预测分析提供支持,以便预先抢占和修复问题。底线是,在任何给定的时间点,基础设施节点应该维护不间断服务所需的数量。