根据我的经验,大多数人(使用Helm或手动yaml)将应用程序部署到Kubernetes上,然后认为他们就可以一直稳定运行。
然而并非如此,实际使用过程还是遇到了一些“陷阱”,我希望在此处列出这些“陷阱”,以帮助您了解在Kubernetes上启动应用程序之前需要注意的一些问题。
调度器通过 kubernetes 的 watch 机制来发现集群中新创建且尚未被调度到 Node 上的 Pod。调度器会将发现的每一个未调度的 Pod 调度到一个合适的 Node 上来运行。kube-scheduler作为集群的默认调度器,对每一个新创建的 Pod 或者是未被调度的 Pod,kube-scheduler会选择一个最优的 Node 去运行这个 Pod。然而,Pod 内的每一个容器对资源都有不同的需求,而且 Pod 本身也有不同的资源需求。因此,Pod 在被调度到 Node 上之前,根据这些特定的资源调度需求,需要对集群中的 Node 进行一次过滤。
在一个集群中,满足一个 Pod 调度请求的所有 Node 称之为 可调度节点。如果没有任何一个 Node 能满足 Pod 的资源请求,那么这个 Pod 将一直停留在未调度状态直到调度器能够找到合适的 Node。
在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、亲和以及反亲和要求、数据局域性、负载间的干扰等等。关于调度更多信息请官网自行查阅
Pod Requests and Limits来看个简单例子,这里只截取yaml部分信息
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx-demo image: nginx resources: limits: memory: "100Mi" cpu: 100m requests: memory: "1000Mi" cpu: 100m默认情况下,咱们创建服务部署文件,如果不写resources字段,Kubernetes集群会使用默认策略,不对Pod做任何资源限制,这就意味着Pod可以随意使用Node节点的内存和CPU资源。但是这样就会引发一个问题:资源争抢。
例如:一个Node节点有8G内存,有两个Pod在其上运行。
刚开始运行,两个Pod都只需要2G内存就足够运行,这时候都没有问题,但是如果其中一个Pod因为内存泄漏或者流程突然增加到导致内存用到了7G,这时候Node的8G内存显然就不够用了。这就会导致服务服务极慢或者不可用。
所以,一般情况下,我们再部署服务时,需要对pod的资源进行限制,以避免发生类似的问题。
如示例文件所示,需要加上resources;
requests: 表示运行服务所需要的最少资源,本例为需要内存100Mi,CPU 100m limits: 表示服务能使用的最大资源,本例最大资源限制在内存1000Mi,CPU 100m什么意思呢?一图胜千言吧。
PS:@@@画图我真滴尽力了@@@
Kubernetes社区中经常讨论的另一个热点话题。 掌握Liveness和Readiness探针非常重要,因为它们提供了一种运行容错软件并最大程度减少停机时间的机制。 但是,如果配置不正确,它们可能会对您的应用程序造成严重的性能影响。 以下是这两个探测的概要以及如何推理它们:
Liveness Probe:探测容器是否正在运行。 如果活动性探针失败,则kubelet将杀死Container,并且Container将接受其重新启动策略。 如果“容器”不提供活动性探针,则默认状态为“成功”。
因为Liveness探针运行频率比较高,设置尽可能简单,比如:将其设置为每秒运行一次,那么每秒将增加1个请求的额外流量,因此需要考虑该请求所需的额外资源。通常,我们会为Liveness提供一个健康检查接口,该接口返回响应代码200表明您的进程已启动并且可以处理请求。
Readiness Probe:探测容器是否准备好处理请求。 如果准备就绪探针失败,则Endpoint将从与Pod匹配的所有服务的端点中删除Pod的IP地址。
Readiness探针的检查要求比较高,因为它表明整个应用程序正在运行并准备好接收请求。对于某些应用程序,只有从数据库返回记录后,才会接受请求。 通过使用经过深思熟虑的准备情况探针,我们能够实现更高水平的可用性以及零停机部署。
Liveness and Readiness Probes检测方法一致,有三种
定义存活命令:
如果命令执行成功,返回值为零,Kubernetes 则认为本次探测成功;如果命令返回值非零,本次 Liveness 探测失败。
定义一个存活态 HTTP 请求接口;
发送一个HTTP请求,返回任何大于或等于 200 并且小于 400 的返回代码表示成功,其它返回代码都标示失败。
定义 TCP 的存活探测
向执行端口发送一个tcpSocket请求,如果能够连接表示成功,否则失败。